Saturday, 25. October 2008, 19:07:08
I've updated my
TODO list for those curious as to the status of Project V. I can now edit values for types from within the IDE. Take a look at this partial screenshot.

Just a little recap as to how types are defined in Project V. There are three kinds of entities.
1. Types
2. Modifiers
3. Instances
A type is the most powerful and flexible entity. It contains sets. In the above screenshot, you can see a type by the name of Integer. It has one set called Properties. The Properties set is special in that it defines the meaning of the type itself. You can see three of those properties: Size, Signed and Endian. As you can see, we have defined a 4 byte signed integer that is stored in little endian order. Simply use or create a type with different properties to get a different kind of integer.
The last line is MyInteger. This is a derived entity from the Integer type. Since it has a value (22), we can infer that it is an instance. So by creating an instance entity and deriving it from a specific type, we create an instance of that type. From the properties, the IDE knows that 22 takes up 4 bytes, is signed and is stored in little endian order.
To really screw with your head, consider that each of the properties are also instances and are defined exactly like MyInteger is defined. Note that the size property has a base type of Integer of which it is helping to define. In Project V, circular type definitions like this are no problem.
Here is C++ style pseudo code to explain the Size property.
class Integer
{
Properties: // Imagine this defines a set
Integer Size=4;
Bool Signed=TRUE;
Endian Endian=little;
} MyInteger = 22;
(Heck, I may allow users to create type definitions in this manner. Look at the Size property again. If Size is itself an instance, what is the size of it and what property defines it? Answer: itself!)
So far I've explained types and instances. But what about modifiers? Modifiers and instances are almost identical. While types can have many other base types, modifiers and instances can only have one direct base type. And the only difference between modifiers and instances is that a modifier will not create an instance. So you can use a modifier to override properties in base types. In fact, MyInteger is derived from the Int32 modifier which contains the properties you see in the screenshot above. And the typename of MyInteger would be Int32, NOT Integer as that is further up the hierarchy.
Here is really what's going on.
type Integer
{
Properties: // Imagine this defines a set
Integer Size;
Bool Signed;
Endian Endian;
}
modifier Int32 : Integer
{
// Override the Properties set in the Integer type
Properties(Integer):
Size = 4;
Signed = TRUE;
Endian = little;
}
type Enum
{
// The Options set will contain the items of the enumeration.
Options:
}
type Bool : Int32, Enum
{
// Override the Options set in Enum.
Options(Enum):
Bool FALSE = 0;
Bool TRUE = 1;
}
type Endian : Int32, Enum
{
// Override the Options set in Enum.
Options(Enum):
Endian little = 0;
Endian big = 1;
}
Int32 MyInteger = 22;
So how should I show the typename of all the properties? Most property editors don't show it at all. I don't really want to widen the treeview to display this information. A rollover popup might be good. However, I'm not sure what's the best way to go. Any suggestions? Maybe I could toggle it on or off and display instances as "Int32:MyInteger". I'm still not sure.
I'll be working on connecting components together next. I'll have to display instances and its type hierarchy as well. Moreso than what's in the screenshot above. That's mostly for updating existing data structures and values.
So what should be the very first component to show itself in Project V? Addition? Or maybe a more esoteric component? And if there are suggestions for built-in components, let me know. Right now, I have this potential list (which will only work on integers to start off until I can make generic versions).
Multiplexor
Demultiplexor
Compare !=
Compare ==
Compare <=
Compare <
Compare >=
Compare >
And
Or
Xor
Not
Div (two outputs. Quotient and Remainder)
Mul
Subtraction
Addition
The multiplexor and demultiplexor are required as this is how you select where data goes. But if I didn't care about speed, I could build them out of the other components.
The Demultiplexor takes two inputs (and has two outputs although only one output is activated at a time). The first input is a boolean selector that selects what output to send the input. So there are two outputs named TRUE and FALSE which are activated depending on the state of the selector.
The Multiplexor has three inputs and one output. It again has a boolean selector and chooses either the input with the label of TRUE or FALSE depending on its state. The selected input is sent out on the output and the other value is discarded.
I'm thinking of building a swap component based on a selector instead of the multiplexor. Three inputs and two outputs. Basically two inputs are sent directly to two corresponding outputs if the selector is FALSE. If the selector is TRUE, then the inputs are swapped. That may be more useful than a multiplexor. If you don't use the second output, you can simply leave it unconnected and you have exactly the same functionality as a multiplexor.
And believe it or not, you can build anything and everything possible with that setup though I wouldn't recommend using such low level components for actual software development.
That would make a total of 16 components, many of which can be built from a subset of that same list. Actually, you only need two components to build anything you want. A NOT component and your choice of AND or OR component. You decide which one you want. In fact, you could combine them and only have ONE component (NAND or NOR). So it's not the computations that are critical. It's the ability to link those computations together. That's where the power comes from.