<commit_before># 16-bit Javascript VM

The project consists of:

- The definition of an [assembly language](https://en.wikipedia.org/wiki/Assembly_language) with 37 instructions
- An [assembler](https://en.wikipedia.org/wiki/Assembly_language#Assembler) to transform a `*.asm` file into a binary executable format
- A small [virtual machine](https://en.wikipedia.org/wiki/Virtual_machine) which simulates a basic computer architecture: A memory space, stack, and CPU with 4 general purpose registers and a fetch-decode-execute cycle

The virtual machine can run in two modes: run (default) and step. Run mode simply runs the entire program in sucession. Step mode runs the program in a debug environment, pausing before executing each instruction and displaying the entire state of the machine.

## Running the VM
### Running the assembler

`node src/assembler -i {infile.asm} -o {outfile.bin}`

### Running a program

`node src -p {program.bin}`

## Assembly language

The assembly language consists of 16 distinct instructions which support all the basic features you would expect: Arithmetic, Loading values to and from memory/registers, conditional/non conditional jumps, functions, system calls for reading and and writing stdio etc.

Comments start with a `;` character.
Labels can be defined by `:some_label_name` on their own line and then referenced in an instruction like so: `LDV16 A, :some_label_name`.

### Examples

A couple of examples illustrating the language can be found in the `asm/` folder.

### Instruction set

#### Real instructions

|Instruction|Arguments|16 bit representation |Description|
|-----------|---------|-------------------------|-------------|
|`MOV`| `D, S`          | `XXXXXXXXSSDD0000` | Move value at source register to destination register|
|`LDV`| `D, V`          | `VVVVVVVVVVDD0001` | Load a value into destination register. |
|`LDA`| `D, M`          | `MMMMMMMMMMDD1110` | Load a value from memory into destination register|
|`LDM`| `D, M`          | `MMMMMMMMMMDD0011` | Load the value in destination register into memory|
|`LDR`| `D, S`          | `XXXXXXXXSSDD0010` | Load the value from memory pointed at by the source register into the destination register|
|`LDP`| `D, S`          | `XXXXXXXXSSDD1111` | Load the value in source register into the memory address pointed to by destination register|
|`ATH`| `D, S, O, M, B` | `BBBMOOOOSSDD0100` | Perform an arithmetic operation on the source and destination registers. O specifies the operation (listed below) and M is the mode, where 0 = place result in destination register and 1 = place result in source register. If the instruction is right or left shift then B specifies the shifting value|
|`CAL`| `D`             | `XXXXXXXXXXDD0101` | Call a function in memory pointed at by the destination register|
|`RET`|                 | `XXXXXXXXXXXX0110` | Return from function|
|`JLT`| `D, S`          | `XXXXXXXXSSDD0111` | Jump to memory address pointed at by the source register, if value in the A register is less than value in destination register|
|`PSH`| `S`             | `XXXXXXXXSSXX1000` | Push the value in source register onto the stack|
|`POP`| `D`             | `XXXXXXXXXXDD1001` | Pop the stack into the destination register|
|`SYS`|                 | `XXXXXXXXXXXX1010` | Perform a system call. This is described below in more detail.|
|`HLT`|                 | `XXXXXXXXXXXX1011` | Program halt|
|`JMP`| `M`             | `MMMMMMMMMMXX1100` | Jump to address in memory. Can only reference memory up to 0x3FF.|
|`JMR`| `S`             | `XXXXXXXXSSXX1101` | Jump to the address pointed at by the source register|


#### Pseudo Instructions

Pseudo instructions are prepocessed by the assembler and expanded into combinations of the real instructions.

|Instruction|Arguments|Expanded length  |Description|
|-----------|---------|-----------------|-----------|
|`ADD`      | `D, S`    |1                | Add destination to source and store the result in destination|
|`ADDS`     | `D, S`    |1                | Add destination to source and store the result in source|
|`SUB`      | `D, S`    |1                | Subract destination from source and store the result in destination|
|`SUBS`     | `D, S`    |1                | Subract destination from source and store the result in source|
|`MUL`      | `D, S`    |1                | Multiply destination with source and store the result in destination|
|`MULS`     | `D, S`    |1                | Multiply destination with source and store the result in source|
|`DIV`      | `D, S`    |1                | Divide destination by source and store the result in destination|
|`DIVS`      | `D, S`    |1                | Divide destination by source and store the result in source|
|`INC`      | `D`       |1                | Add one to the destination register|
|`DEC`      | `D`       |1                | Subtract one from the destination register|
|`LSF`      | `D, A`    |1                | Binary shift left the destination register by amount A (max 7)|
|`LSR`      | `D, A`    |1                | Binary shift right the destination register by amount A (max 7)|
|`AND`      | `D, S`    |1                | Binary and the destination and source, and store the result in the destination|
|`OR`       | `D, S`    |1                | Binary or the destination and source, and store the result in the destination|
|`XOR`      | `D, S`    |1                | Binary exclusive-or the destination and source, and store the result in the destination|
|`NOT`      | `D`       |1                | Binary not (invert) the destination|
|`LDV16`    | `D, V`    |6                | Load a 16 bit value into destination|
|`SWP`      | `D, S`    |3                | Swap the values in the source and destination registers|
|`JGE`      | `D, A`    |4                | Jump to address A if value in destination regigster is greater than or equal to the A register. Can potentially mutate all registers except A and destination|
|`JEQ`      | `D, A`    |11               | Jump to address A if value in destination regigster is equal to the A register. Can potentially mutate all registers except A and destination|
|`JNE`      | `D, A`    |14               | Jump to address A if value in destination regigster is equal to the A register. Can potentially mutate all registers except A and destination|


#### Arithmetic Operation table

|Operation    |Value  |
|-------------|-------|
|`Add`        |`0000` |
|`Subtract`   |`0001` |
|`Multiply`   |`0010` |
|`Divide`     |`0011` |
|`Left shift` |`0100` |
|`Right shift`|`0101` |
|`And`        |`0111` |
|`Or`         |`1000` |
|`Xor`        |`1001` |
|`Not`        |`1010` |


#### System calls

A system call in the VM allows the program to ask resources outside of it's context, such as communication with stdin and stdout. System calls are passed off to the os module and can return their results directly into the CPUs registers.

|System call           |Call code |
|----------------------|----------|<commit_msg>Fixes a few typos and one aesthetic fix in a table (#19)<commit_after># 16-bit Javascript VM

The project consists of:

- The definition of an [assembly language](https://en.wikipedia.org/wiki/Assembly_language) with 37 instructions
- An [assembler](https://en.wikipedia.org/wiki/Assembly_language#Assembler) to transform a `*.asm` file into a binary executable format
- A small [virtual machine](https://en.wikipedia.org/wiki/Virtual_machine) which simulates a basic computer architecture: A memory space, stack, and CPU with 4 general purpose registers and a fetch-decode-execute cycle

The virtual machine can run in two modes: run (default) and step. Run mode simply runs the entire program in sucession. Step mode runs the program in a debug environment, pausing before executing each instruction and displaying the entire state of the machine.

## Running the VM
### Running the assembler

`node src/assembler -i {infile.asm} -o {outfile.bin}`

### Running a program

`node src -p {program.bin}`

## Assembly language

The assembly language consists of 16 distinct instructions which support all the basic features you would expect: Arithmetic, Loading values to and from memory/registers, conditional/non conditional jumps, functions, system calls for reading and and writing stdio etc.

Comments start with a `;` character.
Labels can be defined by `:some_label_name` on their own line and then referenced in an instruction like so: `LDV16 A, :some_label_name`.

### Examples

A couple of examples illustrating the language can be found in the `asm/` folder.

### Instruction set

#### Real instructions

|Instruction|Arguments|16 bit representation |Description|
|-----------|---------|-------------------------|-------------|
|`MOV`| `D, S`          | `XXXXXXXXSSDD0000` | Move value at source register to destination register|
|`LDV`| `D, V`          | `VVVVVVVVVVDD0001` | Load a value into destination register. |
|`LDA`| `D, M`          | `MMMMMMMMMMDD1110` | Load a value from memory into destination register|
|`LDM`| `D, M`          | `MMMMMMMMMMDD0011` | Load the value in destination register into memory|
|`LDR`| `D, S`          | `XXXXXXXXSSDD0010` | Load the value from memory pointed at by the source register into the destination register|
|`LDP`| `D, S`          | `XXXXXXXXSSDD1111` | Load the value in source register into the memory address pointed to by destination register|
|`ATH`| `D, S, O, M, B` | `BBBMOOOOSSDD0100` | Perform an arithmetic operation on the source and destination registers. O specifies the operation (listed below) and M is the mode, where 0 = place result in destination register and 1 = place result in source register. If the instruction is right or left shift then B specifies the shifting value|
|`CAL`| `D`             | `XXXXXXXXXXDD0101` | Call a function in memory pointed at by the destination register|
|`RET`|                 | `XXXXXXXXXXXX0110` | Return from function|
|`JLT`| `D, S`          | `XXXXXXXXSSDD0111` | Jump to memory address pointed at by the source register, if value in the A register is less than value in destination register|
|`PSH`| `S`             | `XXXXXXXXSSXX1000` | Push the value in source register onto the stack|
|`POP`| `D`             | `XXXXXXXXXXDD1001` | Pop the stack into the destination register|
|`SYS`|                 | `XXXXXXXXXXXX1010` | Perform a system call. This is described below in more detail.|
|`HLT`|                 | `XXXXXXXXXXXX1011` | Program halt|
|`JMP`| `M`             | `MMMMMMMMMMXX1100` | Jump to address in memory. Can only reference memory up to 0x3FF.|
|`JMR`| `S`             | `XXXXXXXXSSXX1101` | Jump to the address pointed at by the source register|


#### Pseudo Instructions

Pseudo instructions are prepocessed by the assembler and expanded into combinations of the real instructions.

|Instruction|Arguments|Expanded length  |Description|
|-----------|---------|-----------------|-----------|
|`ADD`      | `D, S`    |1                | Add destination to source and store the result in destination|
|`ADDS`     | `D, S`    |1                | Add destination to source and store the result in source|
|`SUB`      | `D, S`    |1                | Subtract destination from source and store the result in destination|
|`SUBS`     | `D, S`    |1                | Subtract destination from source and store the result in source|
|`MUL`      | `D, S`    |1                | Multiply destination with source and store the result in destination|
|`MULS`     | `D, S`    |1                | Multiply destination with source and store the result in source|
|`DIV`      | `D, S`    |1                | Divide destination by source and store the result in destination|
|`DIVS`     | `D, S`    |1                | Divide destination by source and store the result in source|
|`INC`      | `D`       |1                | Add one to the destination register|
|`DEC`      | `D`       |1                | Subtract one from the destination register|
|`LSF`      | `D, A`    |1                | Binary shift left the destination register by amount A (max 7)|
|`LSR`      | `D, A`    |1                | Binary shift right the destination register by amount A (max 7)|
|`AND`      | `D, S`    |1                | Binary and the destination and source, and store the result in the destination|
|`OR`       | `D, S`    |1                | Binary or the destination and source, and store the result in the destination|
|`XOR`      | `D, S`    |1                | Binary exclusive-or the destination and source, and store the result in the destination|
|`NOT`      | `D`       |1                | Binary not (invert) the destination|
|`LDV16`    | `D, V`    |6                | Load a 16 bit value into destination|
|`SWP`      | `D, S`    |3                | Swap the values in the source and destination registers|
|`JGE`      | `D, A`    |4                | Jump to address A if value in destination register is greater than or equal to the A register. Can potentially mutate all registers except A and destination|
|`JEQ`      | `D, A`    |11               | Jump to address A if value in destination register is equal to the A register. Can potentially mutate all registers except A and destination|
|`JNE`      | `D, A`    |14               | Jump to address A if value in destination register is not equal to the A register. Can potentially mutate all registers except A and destination|


#### Arithmetic Operation table

|Operation    |Value  |
|-------------|-------|
|`Add`        |`0000` |
|`Subtract`   |`0001` |
|`Multiply`   |`0010` |
|`Divide`     |`0011` |
|`Left shift` |`0100` |
|`Right shift`|`0101` |
|`And`        |`0111` |
|`Or`         |`1000` |
|`Xor`        |`1001` |
|`Not`        |`1010` |


#### System calls

A system call in the VM allows the program to ask resources outside of it's context, such as communication with stdin and stdout. System calls are passed off to the os module and can return their results directly into the CPUs registers.

|System call           |Call code |
|----------------------|----------|
{'fraction_non_alphanumeric': 0.11549655710939163, 'fraction_numerical': 0.021154255696741675, 'mean_word_length': 2.6141611082606464, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 30, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1904359', 'n_tokens_mistral': 4143, 'n_tokens_neox': 3822, 'n_words': 1774}