# Design ## Parsing - First we tokenize the input (syntax check) - Then we interpret the input (semantics check) - Then we execute the input ## Notation - `[operation][number type]`, e.g. `divi` for divide (div) integer - `%[register]` for addressing registers - `$[value]` for using literals/immediate values - `;` for end of statement (mandatory) - `[label]:` for labels - `#[text]` for comments: any text is ignored till a newline (`\n`) is found - `[[%register|$value]]` for accessing memory - Elements must be separated by whitespace character - Good: `add $2 $5 %A;` - Bad: `add $2$5%A;` ## Examples Divide register A by 5 and store the result in register A: `divi %A $5 %A;` Increment B until it is 10: ``` # Set B to zero addi $0 $0 %B; loop: addi $1 %B %B; lti %B $10; jmp loop; ``` Read the integer at memory location `1024` into register A: ``` seti %A [$1024]; ``` Remember not to use spaces inside the `[` brackets. ## Reserved symbols The following whitespace characters are used to separate symbols: - space (` `) - tab (`\t`) - return carriage (`\r`) - newline (`\n`) The following characters are used as identifiers: - dollar (`$`) for immediate (literal) values - percentage (`%`) for register identifiers - colon (`:`) for jump labels - semicolon (`;`) for statement termination - hash (`#`) for comments All symbols are reserved keywords and can therefore NOT be used as labels. ## Symbols ## Directives - `DECLARE` declares the first label argument to equal the second, immediate value, argument and is used to declare a constant for the virtual machine. ### Operands - `addi` add the first to the second argument and store the result in the third argument - `subi` subtract the first from the second argument and store the result in the third argument - `divi` divide the first by the second argument and store the result in the third argument - `muli` multiply the first by the second argument and store the result in the third argument - `shli` shift left the first argument by the number of positions given by the second argument and store the result in the third argument - `shri` shift right the first argument by the number of positions given by the second argument and store the result in the third argument - `seti` set the first register argument to the second argument - `int` calls the interrupt specified by the first (integer) argument ### Control Flow - `jmp` jump to the label given by the first argument - `lti` execute next statement if argument 1 is less than argument 2 else skip the next statement - `gti` execute next statement if argument 1 is greater than argument 2 else skip the next statement - `eqi` execute the next statement if argument 1 is equal to argument 2 else skip the next statement ## Memory - `popi` pops the first value on the stack into the register specified as the first argument - `pushi` pushes the value on the stack from the register or immediate value as the first argument ## Interupts - [0..9] Output to STDOUT - `0` put value of register A as ASCII character on stdout - `1` put value of register A as decimal integer on stdout - `2` put value of register A as hexadecimal integer on stdout - `3` put the string pointed at by register A for the amount of characters defined by register B on stdout