Charles,
Can you please move both Aurel's question and my answer to the Bytecode Interpreter Concept thread, please?
Hi Aurel,
No, the bytecode commands (op_halt, op_push_int, etc) are actually stored in the
code_arr[] array together with the variables' values according to the keywords and operators (sym_print, sym_while, sym_or, sym_and, etc) and literal numeric and string values as they are seen immediately by the parser. The notion of a particular "variable" and its "type" (only integer for now) exists only as long as its declaration is being evaluated by the
parser() function, and its storage space is reserved as a location (a "cell") in the same
code_arr[] array (or out of it, if you like). They are referred to by the
interpreter() function later on by their "index" number in such bytecode commands as
push_int_var X and
store X where X is the "index" of the location (n=1, lim=2, k=3, p=4).
See
Code listing... in your console also for such bytecode command as
push_int X which means "push literal value X" against
push_int_var X which means "push value stored at location that has index number X".
store X always means "store result of current operation at location that has index number X".
The
interpreter() function doesn't know anything about either "variables" or their "types". It deals only with the bytecoded commands and the nearby literal numeric and string pointer values stored in the same
code_arr[] array. It also uses numeric literal values stored at the locations indexed 1 to 4 or saves literal results of numeric operations in them.
It "pushes" the literals into the auxiliary "stack" array
stack[] and applies arithmetic operations to its elements that have just been "pushed". Each bytecode corresponds to a certain arithmetic or print operation that is applied by the interpreter to the
stack[] array elements "pushed" into it. It also retrieves and stores values from/to the locations (former "variables") indexed 1 to 4. In other words, the
interpreter() function is the code executor function.
Your own interpreter uses 3 arrays. The toy interpreter uses only one "interleaved" bytecode/literal array
code_arr[] and a small auxiliary "stack" array
stack[] to "de-interleave" (separate) the literals from the bytecode/literal
code_arr[] array.
The toy interpreter uses a lot fewer resources so far than your own implementation.