I’ve spent the past 4 months rewriting Leema’s parser and semantic analysis, most of the compiler. It’s largely done and my next step is to reconnect the parser to the code generator.
The Bytecode Interpreter
Leema currently has a bytecode interpreter. It worked before the rewrite and is easy to handle the switches between tasks when waiting for IO, On the downside, it was pretty slow and assigning registers during compilation was the most common source of bugs in the interpreter. Unfortunately, assigning registers is the last big part of connecting the bytecode interpreter to the new compiler.
Because LLVM handles register assignment, switching to it and replacing the bytecode would solve the biggest problem right now, plus hopefully speed things up. However, it would be an unknown, probably huge amount of effort.
Which Way to Go?
Since there’s a lot work to do for the bytecode interpreter anyway, maybe it’s a good time to switch to LLVM?
Right now I’m leaning towards sticking with the bytecode interpreter for the following reasons.
- My understanding of the interpreter and my ability to debug it is much better than with LLVM. My ideas about how to block a task for IO in LLVM are only half-formed.
- The newly rewritten compiler should help with reducing bugs when assigning registers for the interpreter.
- While bytecode interpreters are slower than native code, they’re not unusably slow. Plenty of people still use Ruby, Python and PHP and although the Leema interpreter is slower than those, has plenty of low hanging fruit for optimization.
Writing this was my attempt to think through the problem and arrive at a decision and I think I’ve done that now. Thanks for reading along and rubber ducking.