3 ms·
Note that you can avoid a second pass by doing 'backpatching' - essentially assuming whatever code you encountered was correct, emitting the relevant bytecode/m
by badsectoracula 7y ago
Note that you can avoid a second pass by doing 'backpatching' - essentially assuming whatever code you encountered was correct, emitting the relevant bytecode/machinecode with enough reserved space for an address (e.g. for a 'jump to address' instruction, emit zeroes for the address), keep a list of 'unknown stuff' and then resolve them once compilation is finished.
Many years ago i wrote a Java-like scripting language (classes, GC, etc) with that approach. Funny enough, at the time it didn't occur me that i could have separate bytecode streams for methods, etc, so the VM was almost like a custom CPU (the only non-CPU-like feature was an instruction to allocate memory) and since it generated bytecode while it was parsing the source code itself (even skipped any separate tokenization, i parsed the character streams directly) while it also allowed code to be placed outside of functions or classes (it was a scripting language after all), every time a class or function was encountered in source code, it'd emit code to jump over it - so the final bytecode would start by a series of jumps over the functions and classes before arriving to the first actual instruction :-P.