Skip to content
Arno van der Vegt edited this page Oct 7, 2020 · 30 revisions

Data

The Wheel virtual machine only uses a number type. All strings are numeric indices which point to an offset in a string list.

The VMData class contains register, heap and string data.

Commands

The virtual machine has 16 commands. Each command can have up to two parameters.

# Command Description
0 call Call a procedure
1 ret Return from a procedure
2 copy Copy from the source register to the destination register
3 jmpc Jump conditional, based on the given flag value
4 mod Call a module
5 set Set a value
6 add Add a value
7 sub Subtract a value
8 mul Multiply a value
9 div Divide a value
10 and Boolean and a value
11 or Boolean or a value
12 cmp Compare two values
13 setf Set a flag
14 sets Set a string
15 adds Add a string

Command parameters

There are four parameter types:

Type Value
Constant 0
Global 1
Local 2
Pointer 3

The combination of a command and two parameters can be stored in eight bits:

Bits: 8..5 4..3 2..1
Function Command First param type Second param type

call command

The call command has two parameters. The first parameter is the offset in the code, the second is the current stack usage. When a call is made then the value of the stack register and the code register values are saved on the stack. The next example calls a procedure at command 45 and adds 5 to the stack register:

call 56, 5

ret command

The ret command has a single parameter, the value of the parameter is stored in the ret register.

Some module calls, for example the round function in the math module set the return register. Modules can set a keepRet value which has the effect that the parameter of the ret command is ignored after that module call is made. This example sets the return register to 45:

ret 45

copy command

The copy command has two parameters but the first one is ignored. The second parameter is the number of values which have to be copies. The copy command copies from the address set in the src register to the address set in the dest register. The following code copies 10 values:

copy 0, 10

jmpc command

The jmpc command jumps if a given flag condition is met. It has two parameters, the first parameter is the flags which have to be set and the next parameter is the address to jump to. In the following code a jump is done if the equal flag is set:

jmpc 1, 40

mod command

The mod command calls a procedure in a module. This command has two parameters, the first parameter is the module and the second parameter is the procedure within the module. Data is passed to a module by pointing the src register to a block of data which you want to pass to the module. The current version of the compiler only accepts constant parameter values. The following example code calls the fifth procedure of the third module:

mod 3, 5

set command

The set command sets a value in a memory location. It has two parameters. The first parameter can be a global memory location, a location on the stack or a pointer location. The second parameter can be a constant, global memory location, stack or pointer location. The following example shows set commands with different parameters:

set [3],          5            ; Set a global memory location with offset 3 to 5
set [stack + 10], 7            ; Set a stack location to 7
set [ptr + 6],    2            ; Set a pointer location to 2

set [3],          [5]          ; Copy the value of global memory location 5 to global location 3
set [stack + 10], [ptr + 4]    ; Copy the pointer value to the stack location
set [ptr + 6],    [stack + 4]  ; Copy the stack location to the pointer location

add command

The add command has two parameters and adds the value of the second parameter to the value at the memory location of the first paremater. The first parameter can be a global memory location, a location on the stack or a pointer location. The second parameter can be a constant, global memory location, stack or pointer location. The following example shows add commands with different parameters:

add [3],          5            ; Adds 5 to the global memory location with offset 3
add [stack + 10], 7            ; Adds 7 to the stack location
add [ptr + 6],    2            ; Adds 2 to a pointer location

add [3],          [5]          ; Add the value of the global memory location 5 to the global location 3
add [stack + 10], [ptr + 4]    ; Add the pointer value to the stack location
add [ptr + 6],    [stack + 4]  ; Add the stack location to the pointer location

sub command

The sub command has two parameters and subtracts the value of the second parameter from the value at the memory location of the first parameter. The first parameter can be a global memory location, a location on the stack or a pointer location. The second parameter can be a constant, global memory location, stack or pointer location. The following example shows sub commands with different parameters:

sub [3],          5            ; Subtracts 5 from the global memory location with offset 3
sub [stack + 10], 7            ; Subtracts 7 from the stack location
sub [ptr + 6],    2            ; Subtracts 2 from a pointer location

sub [3],          [5]          ; Subtract the value of the global memory location 5 from the global location 3
sub [stack + 10], [ptr + 4]    ; Subtract the pointer value from the stack location
sub [ptr + 6],    [stack + 4]  ; Subtract the stack location from the pointer location

mul command

The mul command has two parameters and multiplies the value of the second parameter with the value at the memory location of the first parameter. The first parameter can be a global memory location, a location on the stack or a pointer location. The second parameter can be a constant, global memory location, stack or pointer location. The following example shows mul commands with different parameters:

mul [3],          5            ; Multiply the global memory location with offset 3 with 5
mul [stack + 10], 7            ; Multiply the stack location with 7
mul [ptr + 6],    2            ; Multiply the pointer location with 2

mul [3],          [5]          ; Multiply the global memory location 3 with the value at memory location 5
mul [stack + 10], [ptr + 4]    ; Multiply the stack location with the value at the pointer location
mul [ptr + 6],    [stack + 4]  ; Multiply the pointer location with the value at the stack location

div command

The div command has two parameters and divides the value at the memory location of the first parameter with the value of the second parameter. The first parameter can be a global memory location, a location on the stack or a pointer location. The second parameter can be a constant, global memory location, stack or pointer location. The following example shows div commands with different parameters:

div [3],          5            ; Divide the global memory location with offset 3 with 5
div [stack + 10], 7            ; Divide the stack location with 7
div [ptr + 6],    2            ; Divide the pointer location with 2

div [3],          [5]          ; Divide the global memory location 3 with the value at memory location 5
div [stack + 10], [ptr + 4]    ; Divide the stack location with the value at the pointer location
div [ptr + 6],    [stack + 4]  ; Divide the pointer location with the value at the stack location

and command

The and command has two parameters and sets the value of at the memory location of the first parameter to the boolean and value of the first and second parameter values. The following example shows the and command with two global values:

and [3], [5] ; The value at global location 3 is set to the value at location 3 and the value at location 5

or command

The or command has two parameters and sets the value of at the memory location of the first parameter to the boolean or value of the first or second parameter values. The following example shows the or command with two global values:

or [3], [5] ; The value at global location 3 is set to the value at location 3 and the value at location 5

cmp command

The cmp command has two parameters and compares the parameter values with each other and stores the results in the flags register. The resulting flags are: eq (equal), neq (not equal), l (less), le (less or equal), g (greater), ge (greater or equal). See flags. Based on the compare result a conditional jump can be executed.

The following example compares two values.

cmp [10], [stack + 34] ; Compare the value at global location 10 is with value at the stack location 34

setf command

The setf command has two parameters. The first parameter is a memory value on the stack and the second parameter is a flag value which can contain zero or more flag bits. Because the compiler only generates code to set a local (stack) value only this type of first parameter is supported. The following example sets the stack memory location to the value of the third flag bit:

setf [stack + 3], 4 ; Set the stack memory location to the less flag value

sets command

The sets command has two parameters. With this command the value of a string can be assigned to another string. The first parameter is the index of the string of which the value will be changed, the second parameter is the index of the value string. The following example assigns a string value.

; The global memory value at offset 3 contains a string index. 
; The string at this index is assigned the string value which is stored at offset 4 in the string list.
sets [3], 4 

adds command

The adds command has two parameters and adds one string value to another string variable. The following example adds a string to a string variable.

; Add the string which is stored at the memory offset 3 points to to the string 
; which is stored at offset 2.
adds 2, [3] 

Registers

Registers are memory locations with a specific purpose. Wheel uses 9 registers which are the first 9 positions in the VM memory:

Register Offset Function
stack 0 The stack pointer, used to address local variables
src 1 The source register used to pass data to modules and to copy data
dest 2 The destination register, used to copy data
ptr 3 The pointer register, used to address variables
code 4 The code offset
return 5 The return value
flags 6 The flags to store the result of a comparison
range1 7 The first range check register
range2 8 The second range check register

Flags

When two values are compared then the first six bits of the flags register will be given a value based on the following conditions:

Flag Bit # Value Description
eq 1 1 Equal
neq 2 2 Not equal
l 3 4 Less
le 4 8 Less or equal
g 5 16 Greater
ge 6 32 Greater or equal

The flags will be set when the cmp command is executed.