Once a time, there was a Guy that wanted to do a Browser, he didn’t manage to do it but then he wanted to do a Javascript Compiler/VM, that guy is me btw.
Oh btw github repo where the JS Runtime is in: GitHub - BudNoise/Birdol: The Birdol Project
First i tried to make a VM using Left-Associative Tree Walk Interpreter but that crashed a little TOO MUCH so i went to Bytecode-Based Interpreter (which i already knew a bit)
So the first thing i made was the Stack and JS_Object wrapper for ints and strings
then i made a very, VERY small VM which it’s bytecode resembles a lot to CPython
i implemented these bytecodes at first
LOAD_CONST
LOAD_VAR
STORE_VAR
the stack had a List[JS_Object] as Pool and a Dict[String, JS_Object] as a Variable List
then i made a PUSH_OP opcode which usually was between the constants but it could also be after the constants due to the flexibility Bok (The VM) has
before making the compiler i implemented an IF/ELSE statement using a
RUN type min_to_max val1,operator,val2
The Compiler initially had only two classes, a Tokenizer and the Compiler itself, there was no difference between Parser, IR and Codegen because it was all in the Compiler (NOTE: yall should add these as different classes for more modularity),
It was VERY error-prone due to the null difference between the three so i rebuilt the compiler in three classes
JS_Parser.parse(tokens: List[String]) → JS_IR
JS_Codegen.generate(ir: JS_IR) → JS_VM
JS_VM.run(args: List[JS_Object] = )
for user-made functions i made that the args are put in the stack as _funcarg_i_