Generating Compilers
I have started to write the hacking docs. As usual, having to explain things made me realize how important it is to make them as simple as possible. Right now, when you add a new function to SEJ, you have to
- extend the scanner/parser,
- implement the function in the byte-code compiler (which you can do quite easily by delegating it to a support function on the runtime class),
- implement the function in the constant folder (again, you can delegate to the runtime class),
- and, later on, implement the function in the source-code compiler (which again could call the delegate).
For aggregations, this becomes much worse because you can no longer simply delegate to a function on the runtime. So I am exploring a totally different way (which has been in the back of my head for a while now): writing the implementations as small methods on a special class. Then, a compiler analyzes the class and generates all three implementations mentioned above: byte-code, source-code, and constant-folder. The benefits are:
- people can read the definitions of how spreadsheet methods are implemented,
- you can write the implementations in plain Java (not byte-code),
- generated byte and source code is checked for correctness at compile-time and can be tested by unit tests,
- no redundancy,
- automatic guarantee that the byte-code corresponds to the one the Java compiler would produce.
The drawbacks are the complexity of the pattern compiler, and the need to document the rules for the pattern methods (which define, in essence, a DSL). On the other hand, the pattern compiler can be ditched at any time because you can simply continue working with the generated sources.