Post by Marco van de VoortThe change to unsigned arithmetic (and types) by default alone, and probably
the string handling too.
Modula-2 has always had both signed and unsigned types.
If you convert code from a language that has only got signed integers to a language that has got both signed and unsigned integers, you simply use only the signed integers and ignore unsigned integers.
It's the opposite direction that would cause extra work.
Besides, any type can be done in library in M2 R10. You want Pascal strings, write a library that conforms to blueprint ProtoString and it will behave as if it was built-in.
The hard work in a Delphi-to-M2R10 converter would be to convert variant records into an equivalent set of extensible records.
TYPE Variant = ( VarA, VarB, ... );
TYPE Foobar = RECORD
foo : Foo;
CASE v : Variant OF
VarA : bar : Bar
| VarB : baz : Baz
...
END
END
to
TYPE Foobar = RECORD ( NIL )
foo : Foo
END;
TYPE BarRec = RECORD ( Foobar )
bar : Bar
END;
TYPE BazRec = RECORD ( Foobar )
baz : Baz
END;
...
This may look straight forward on paper but it is quite a bit of work. Furthermore, when declaring variables of the type and using them, the Variant Record version will always use the Foobar type, whereas the Extensible Record will use a different type for each variant. This is also quite a bit of work.
At some point we will need a PIM4 to M2R10 translator and handle this. Since I already have a working front end for PIM now in the rewrite of M2C, it will make sense to use that and add an option to generate M2R10 as output.
If anyone wants to work on a Pascal/Delphi to M2R10 translator, I think it would probably be saving quite some effort if they simply wrote a front end that generates the same AST as M2C. M2C's middle and back end could then be used.
I have designed the AST so it covers both PIM and extended features, such as variant records and extensible records which have separate AST nodes. It is realised as an opaque library, with only a few functions and completely isolated from the parser.
That is to say, the parser does not have any knowledge of the AST internals, nor will any front end author writing for this AST need to know any internals. Architecturally it is front-end agnostic.
There are likely to be features in Delphi that don't map well to the existing AST nodes. However, thanks to the simplicity and modularity of the AST module, additional nodes could easily be added.
Here is the struct that implements the opaque AST node type
struct m2c_astnode_struct_t {
/* node_type */ m2c_ast_nodetype_t node_type;
/* lexeme */ m2c_string_t lexeme;
/* subnode_count */ uint_t subnode_count;
/* subnode_table */ m2c_astnode_t subnode_table[];
};
The node type is an enumeration, the subnode table is an array of pointers to the node type itself. Thanks to C's variadic argument lists and structs with flex array members, this array can be allocated exactly to the number of passed in subnodes.
Technically, there are two variants, even though I abstained from using variant structs (or unions as C calls them) one node-type for terminals (identifiers, number literals, character code literals and quoted literals) which uses the lexeme field only, and another for non-terminals (all else) which uses the subnode fields only. Avoiding the use of unions trades the space of one pointer in return for ease of coding and readability.
To add a new node type, all one has to do is add another value to the enumeration that defines node types and add parameters to an structured initialiser that says how many subnodes the new node type has and what the types of the subnodes shall be.
The new node type can then be created with the existing function
node = m2c_ast_new_node(MY_NEW_NODE_TYPE, subnode1, subnode2, ...);
Of course the tree walker needs to have a procedure that knows what to do with the new node type and the code generator will need a template to be populated from the new node type.
Yet, this is all a lot less work than writing your own AST, tree walker and code generator from scratch.
If the front end was to be written in Delphi, it should be possible to interface to the C libraries by some foreign function interfacing mechanism. If it was to be written in M2C, there will be a foreign function interface that allows M2 definition modules to be used for corresponding C implementations.
Note that the AST module is not yet in the public repo, I hope to be able to commit it within the next few days.
Anyway, this would be my recommendation if anyone wants to write a Delphi-M2R10 translator: Write a Delphi front-end (even with a subset initially) and hook into my AST library and back end for M2C to save yourself about half the work (or even more).
As for Golang, I reckon that the differences are more substantial than between Pascal and M2, and this would naturally cause more effort then. A Delphi front end would certainly be a good start and whoever does that will gain experience that would then come in handy for doing a Golang-M2R10 translator later.
Unfortunately, I cannot help on either translator (other than providing the AST library, tree walker and code generator) because I have to focus on the completion of the bootstrap and then the eventual compiler.
It would be worthwhile having though I think.