Placing constants on stack
It is the reference of the instructions supported by the brainterpreter VM.A full list of supported instructions is available in src/vm/opcodes.rs .Supported operations can be split into a few groups based on their functions. The groups are:Placing constant values on stack; Arithmetic and logical operations; Jump to different instructions; Loading and storing global variables; Loading and storing local variables; Accessing and storing array elements; Calling functions; Those operations place either immediate values or elements of constants array on the stack. Mnemonics Parameters Effect [{code=CONST_NIL, type=InlinedCode}] [{text=None, type=SimpleText}] [{text=Pushes , type=SimpleText}, {code=nil, type=InlinedCode}, {text= on stack, type=SimpleText}] [{code=CONST_B <b>, type=InlinedCode}] [{code=b, type=InlinedCode}, {text= immediate bolean value, type=SimpleText}] [{text=Places boolean constant on stack, type=SimpleText}] [{code=CONST_F <f>, type=InlinedCode}] [{code=f, type=InlinedCode}, {text= immediate numeric value, type=SimpleText}] [{text=Places a numeric constant on stack, type=SimpleText}] [{code=CONST <n>, type=InlinedCode}] [{code=n, type=InlinedCode}, {text= index of constant in the chunk constants, type=SimpleText}] [{text=Copies chunk constant to the stack, type=SimpleText}] Placing values on stack makes them available for other manipulations like arithmetic or logical operations.
Arithmetic and logic operations manipulates topmost values of the stack. The result of the operation is pushed back on the stack.Operations aren't applicable to all data types. E.g., division of strings does not make sense. The virtual machine will stop with the error when the operation is not applicable to operands on the stack. Unary operations Unary operations picks the last value from the stack, performs the operation and places the result on stack. It may seem as just replacing the value on the top of the stack. Mnemonics Type Effect [{code=NEG, type=InlinedCode}] [{text=Boolean, type=SimpleText}] [{text=Logical , type=SimpleText}, {code=not, type=InlinedCode}, {text= operation, type=SimpleText}] [{code=NEG, type=InlinedCode}] [{text=Number, type=SimpleText}] [{text=Negates the value on top of the stack, type=SimpleText}] Binary operations Binary operations takes two operans from the stack, performs the operation and places the result back on stack.The first operand of the binary operation should be placed on top of the stack. The second operand is on the top - 1 position.E.g., for the operation x - y the stack layout should be like that. Mnemonics Type Effect [{code=ADD, type=InlinedCode}] [{text=Number, Number, type=SimpleText}] [{text=Adds two numbers, type=SimpleText}] [{code=ADD, type=InlinedCode}] [{text=String, String, type=SimpleText}] [{text=Concatenates strings, type=SimpleText}] [{code=SUB, type=InlinedCode}] [{text=Number, Number, type=SimpleText}] [{text=Subtract second number from the first, type=SimpleText}] [{code=MUL, type=InlinedCode}] [{text=Number, Number, type=SimpleText}] [{text=Multiplies two numbers, type=SimpleText}] [{code=DIV, type=InlinedCode}] [{text=Number, Number, type=SimpleText}] [{text=Divides first number with second, type=SimpleText}] [{code=CMP, type=InlinedCode}] [{text=Number, Number, type=SimpleText}] [{text=Compares two numbers. Places , type=SimpleText}, {code=true, type=InlinedCode}, {text= or , type=SimpleText}, {code=false, type=InlinedCode}, {text= on stack, type=SimpleText}] [{code=CMP, type=InlinedCode}] [{text=Boolean, Boolean, type=SimpleText}] [{text=Compares two booleans, type=SimpleText}] [{code=CMP, type=InlinedCode}] [{text=String, String, type=SimpleText}] [{text=Compares two strings, type=SimpleText}] [{code=LE, type=InlinedCode}] [{text=Number, Number, type=SimpleText}] [{text=Pushes , type=SimpleText}, {code=true, type=InlinedCode}, {text= if the first number is less or equal comparing to the second, type=SimpleText}] [{code=GE, type=InlinedCode}] [{text=Number, Number, type=SimpleText}] [{text=Pushes , type=SimpleText}, {code=true, type=InlinedCode}, {text= if the first number is greater or equal comparing to the second, type=SimpleText}]
There are currently two jump calls allowing VM to change the execution flow. Each jump operation accepts the offset value. When applied, jump changes the instruction pointer by adding the offset to the current value. Note that the offset can be negative. Mnemonics Effect [{code=JMP <offset>, type=InlinedCode}] [{text=Unconditionally changes the instruction pointer by adding the offset, type=SimpleText}] [{code=JZ <offset>, type=InlinedCode}] [{text=Changes the instruction pointer only if the value on the top of the stack is , type=SimpleText}, {code=falze, type=InlinedCode}, {text=. If not, the execution proceeds to next operation, type=SimpleText}]
Global variable instructions access global variables by the name. Compiler places the variable name into constants pool of bytecode chunk.Loading the variable places the value on stack. Storing the variable replaces the value in globals map via the topmost value on the stack. Mnemonics Parameters Effect [{code=LD_G <idx>, type=InlinedCode}] [{text=idx - constant index containing variable name, type=SimpleText}] [{text=Copies the value of the global variable onto the stack, type=SimpleText}] [{code=ST_G <idx>, type=InlinedCode}] [{text=idx - constant index containing variable name, type=SimpleText}] [{text=Copies the value from the top of the stack to the globals map, type=SimpleText}]
Local variables are not resolved by the name. Instead of that the compiler places values on the fixed positions of the stack. Thus instructions operating on local variables takes the offset from the base of the stack to address the variable. Mnemonics Parameters Effect [{code=LD_L <idx>, type=InlinedCode}] [{text=idx - offset of the variable from the stack base, type=SimpleText}] [{text=Copies stack value representing the local variable onto the stack top, type=SimpleText}] [{code=ST_L <idx>, type=InlinedCode}] [{text=idx - offset of the variable from the stack base, type=SimpleText}] [{text=Copies the value from the top of the stack to a stack position representing the local variable, type=SimpleText}]
Array operations access elements of arrays and strings by index.Array operations does not have parameters. Instead they need all parameters to be correctly placed on the stack. Mnemonics Stack Top Top - 1 Top - 2 Effect [{code=ARR, type=InlinedCode}] [{text=initial value, type=SimpleText}] [{text=size, type=SimpleText}] [{text=None, type=SimpleText}] [{text=Allocates an array of specified size filled with initial value. Places the reference on the stack, type=SimpleText}] [{code=LD_IDX, type=InlinedCode}] [{text=array reference, type=SimpleText}] [{text=index, type=SimpleText}] [{text=none, type=SimpleText}] [{text=Copies the value with specified index from array to the stack, type=SimpleText}] [{code=ST_IDX, type=InlinedCode}] [{text=value, type=SimpleText}] [{text=array reference, type=SimpleText}] [{text=index, type=SimpleText}] [{text=Replaces value in array with the value from the top of the stack, type=SimpleText}] Array access operation will fail on attempt to access values by index outside of the array.
Mnemonics Parameters Effect [{code=CALL <arity>, type=InlinedCode}] [{code=arity, type=InlinedCode}, {text= - number of function parameters, type=SimpleText}] [{text=Calls the function. The function reference must be present at the , type=SimpleText}, {code=stack top - arity - 1, type=InlinedCode}, {text= stack element. Call operation creates a call frame for the function and starts processing the function chunk., type=SimpleText}] [{code=RET, type=InlinedCode}] [{text=None, type=SimpleText}] [{text=Finishes the function. Removes all arguments from the stack. Places the return value (or , type=SimpleText}, {code=nil, type=InlinedCode}, {text=) on the stack, type=SimpleText}]
Mnemonics Parameters Effect [{code=POP, type=InlinedCode}] [{text=None, type=SimpleText}] [{text=Pop the value off the stack. Useful for cleaning up after finishing block statements or expression statements, type=SimpleText}] [{code=PRN, type=InlinedCode}] [{text=None, type=SimpleText}] [{text=Prints the value from the top of the stack to the linked output. Removes top value from the stack, type=SimpleText}]