Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/benediktwerner/intcode
Compiler, assembler, and VM for intcode from Advent of Code 2019
https://github.com/benediktwerner/intcode
Last synced: about 7 hours ago
JSON representation
Compiler, assembler, and VM for intcode from Advent of Code 2019
- Host: GitHub
- URL: https://github.com/benediktwerner/intcode
- Owner: benediktwerner
- License: cc0-1.0
- Created: 2019-12-09T10:36:15.000Z (almost 5 years ago)
- Default Branch: master
- Last Pushed: 2022-10-16T19:32:29.000Z (about 2 years ago)
- Last Synced: 2024-04-17T16:25:31.320Z (7 months ago)
- Language: Rust
- Homepage:
- Size: 109 KB
- Stars: 42
- Watchers: 2
- Forks: 1
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE-CC0
Awesome Lists containing this project
README
# Intcode compiler, assembler and VM
Compiler, assembler and VM for the [intcode computer](https://adventofcode.com/2019/day/9)
from Advent of Code 2019. This is mainly for fun and to try out some different Rust parsing
libraries.There are four crates in this project:
- `intcode`: Wrapper binary for executing the compiler, assembler or VM
- `vm`: An intcode VM that can run intcode files: `intcode run input.int`
- `asm`: An intcode assembler that can assemble intcode programs from intcode assembly: `intcode asm input.asm`
- `compiler`: An intcode compiler that can compile intcode programs from a higher-level language: `intcode compile input.ic`## Building and Installing
Building or installing requires a working [Rust Installation](https://www.rust-lang.org/).
Build from source and install:
```
$ git clone https://github.com/benediktwerner/intcode
$ cd intcode
$ cargo install --path intcode
$ intcode
```To just build from source:
```
$ git clone https://github.com/benediktwerner/intcode
$ cd intcode
$ cargo build
$ ./target/debug/intcode
```## Compiler
The compiler can compile code written in a simple high-level language to intcode:
```
// Commentvar x; // Variables must be declared before their first use. Globals are initialized to zero.
var y = 13; // but they can also be declared on the first assignmentvar z = input(); // Get input
print(y); // Produce outputfunc fib(x) { // Arguments and variables declared in functions are seperate for each call
y = 42; // Modify a global variabl
if x < 2 {
return 1;
}
return fib(x - 1) * x; // Recursion is possible
}print(fib(z));
print(x); // Still zero because the function has its own scope
print(y); // Changed to 42const LENGTH = 6 * 7; // Constants are computed at compile time
array a[LENGTH]; // Declare a new array with the given length. Only constant expressions can be used to specify the length
var index = 0;
while index < LENGTH {
a[index] = fib(index);
}print(a[LENGTH - 1]);
```An extension for syntax highlighting in Visual Studio Code can be found in [`vscode-syntax-highlighting`](vscode-syntax-highlighting).
It works if the file has the `.ic` extension.## Assembler
### Example
This program computes Day 1 Part 1 in intcode:
```
# Comments start with '#'
start: # Label for jump
in x # Read to memory location x. The assembler automatically 'allocates' this memory after the program.
eq x 0 tmp # Check if input == 0. If yes, stop and print the result.
jmp_true tmp :end # Label targets must be prefixed with a ':' (to get the address instead of the value)
div x 3 x
sub x 2 x
add total x total
jmp :startend:
out total
hlt# Initialize 'total' to 0. The assembler does this automatically so
# this isn't really neccessary, but it shows the concept.
total: data 0
```More examples can be found in the `examples` directory.
### Instructions
| Operation | Effect | Note |
| :----------------------: | :----------------------------------------: | :-----------------------------------------------------: |
| `mov a target` | `target = a` | |
| `add a b target` | `target = a + b` | |
| `sub a b target` | `target = a - b` | |
| `mul a b target` | `target = a * b` | |
| `div a b target` | `target = a // b` | Can be quite slow, only works for positive numbers atm. |
| `mod a b target` | `target = a % b` | Can be quite slow, only works for positive numbers atm |
| `divmod a b target rest` | `target, rest = divmod(a, b)` | Can be quite slow, only works for positive numbers atm |
| `in target` | `target = input()` | |
| `out a` | `print(a)` | |
| `jmp target` | `goto target` | |
| `jnz a target` | `if a != 0: goto target` | Alias: `jtrue` |
| `jz a target` | `if a == 0: goto target` | Alias: `jfalse` |
| `eq a b target` | `target = a == b` | |
| `neq a b target` | `target = a != b` | |
| `lt a b target` | `target = a < b` | |
| `leq a b target` | `target = a <= b` | |
| `gt a b target` | `target = a > b` | |
| `geq a b target` | `target = a >= b` | |
| `and a b target` | `target = a and b` | |
| `or a b target` | `target = a and b` | |
| `not a target` | `target = not a` | |
| `add_rel_base a` | `rel_base += a` | |
| `load a target` | `target = memory[a]` | |
| `store a target` | `memory[target] = a` | |
| `hlt` | `exit()` | Alias: `halt` |
| `data x` | stores `x` as raw data | Accepts multiple arguments, e.g. `data 1 5 13 42` |
| `array val len` | stores `val` `len` times as raw data | |
| `push val` | `memory[rel_base] = val; rel_base += 1` | |
| `pop target` | `rel_base -= 1; target = memory[rel_base]` | |
| `call target` | `push(ip)` | |
| `ret` | `goto pop(ip)` | |The predifined label `__end` can be used to get the address after all the generated code.
This is useful for putting a stack after the program: `add_rel_base :__end`. Simply putting
a label at the end of the program will not work if the program contains
undeclared labels/variables because they will be put after the program.### Parameter types
- Identifier positional: `some_name`
- Identifier immediate: `:some_name`
- Identifier relative: `%some_name`
- Value positional: `[42]`
- Value immediate: `42`
- Value relative: `%42`## License
All the code in this repository is in the public domain. Or if you prefer, you may also use it under the [MIT license](LICENSE-MIT) or [CC0 license](LICENSE-CC0).
Note though that some parts of this code use external libraries which have their own licenses.