3 ms·
Surprisingly, there is not that much distance between tree-walking evaluator and (stack-oriented-)bytecode emitter: you just have slightly different accumulator
by Joker_vD 4y ago
Surprisingly, there is not that much distance between tree-walking evaluator and (stack-oriented-)bytecode emitter: you just have slightly different accumulator (integer vs. list of bytecodes) with slightly different operations on it (arithmetics vs. appending line "add/sub/etc." to the end of list).
Throw in some more of context tracking (e.g. "did the left-hand side turn out to be a constant" or "are we in the (X+Y)+Z situation?" etc.) and you can start doing optimization such as constant folding and expression-tree rebalancing.
Then you can start emitting chunks of assembly instead of bytecode ("iconst X" turns into "push X", "add" turns into "pop eax; pop ecx; add eax, ecx; push eax" etc). Again, with enough context tracking (for example, what's in what registers), you can emit much less stupid assembly.