Created Tuesday 18 November 2008
Few things aren't right with the current compiler:
What other way to we have except than Expanded inheritance to represent C unions? Plus, it's not right the BOOLEANs have the right to inherit but not the other Expanded. BOOLEAN, TRUE and FALSE shouldn't be treated any differently than other prototypes.
By that I'm talking about INTEGERs, BLOCKs and other built-in values. If those prototypes aren't present in the standard library, the compiler complain.
But, the standard library shouldn't be treated any differently from any other library. What if for some reason the main project uses a different library and includes another project that uses the standard library. The two INTEGERs would likely be different. Which one will be chosen by the compiler to represent integer values?
For types that requires a prototype in every case (numerics and blocks). That is when the compiler can't do without a prototype, a minimal prototype will be included in the builtin namespace, and a more complete implementation will be available in the standard library. If the standard library isn't available for some reason, the builtin prototype will be used.
See: Specs:Work In Progress:Builtin Prototypes
The standard library that override builtin types should auto-import builtin types. So transition could be made transparently.
The numeric constants will just be of some special type (won't have a prototype) until they could be converted to an Expanded prototype. The conversion is allowed if the prototype allows it by adding in the Section Header, a slot like:
Section Header - convert := Integer|UnsignedInteger|Real;
This slot could be used to tell the compiler that the numeric values could be converted to this type. The size of the prototype should be used to create the integer or real. Moreover, this could be used to tell the compiler that the prototype can only represent unsigned integers (so signed integers wouldn't be allowed to convert).
If ever a message ('+' operator for example) is sent to a numeric constant that hasn't yet been converted to a numeric type, the constant is converted to INTEGER or REAL, whatever these names represent to the current context.
This requires the compiler to know about arrays. See BLOCK and NATIVE ARRAY special syntax.
Internally, the string constant would be represented as a fixed array of characters. Just as numeric constants, characters won't be bound to any special type at first. Again, if a message is sent to the string constant, it will be converted to the type STRING_CONSTANT.
The string constant is created using characters that has the same length as CHARACTER, this usually would be 8 bits. However, in some cases of long strings, this could be 16 bits.
A prototype could say it accept to be created from string constants by specifying in its Section Header:
Section Header - convert := String;
Then, the following slot must be defined to convert strings:
- convert_string str:[CHARACTER, n:INTEGER] :SELF;
This slot would be called whenever a string should be converted to this prototype.
This should solved by the Expanded inheritance.
See BLOCK and NATIVE ARRAY special syntax
See Expanded Inheritance
The compiler could provide a build-in minimal standard library (using Specs:Work In Progress:Builtin Prototypes). The library would contain the basic functionality for BLOCK, INTEGER, STRING_CONSTANT and the like.
Now, we don't want this library to grow too big, do we? So we'll have to limit the features provided by the built-in prototypes. So, where do we implement the missing functionality?
The best thing would be to have a way to inject new slots. This would likely be used very rarely, only for such cases. Or having a way to change the auto-export at runtime (this would be still be statically computed), and having this auto-export apply in every case (strong auto export).
I don't have a solution yet ... :(