{"id":20808482,"url":"https://github.com/benediktwerner/intcode","last_synced_at":"2025-05-07T06:28:08.642Z","repository":{"id":36531913,"uuid":"226846376","full_name":"benediktwerner/intcode","owner":"benediktwerner","description":"Compiler, assembler, and VM for intcode from Advent of Code 2019","archived":false,"fork":false,"pushed_at":"2022-10-16T19:32:29.000Z","size":112,"stargazers_count":44,"open_issues_count":2,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-06T07:19:43.173Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"cc0-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/benediktwerner.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-CC0","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-12-09T10:36:15.000Z","updated_at":"2024-12-27T16:53:32.000Z","dependencies_parsed_at":"2023-01-17T02:22:05.644Z","dependency_job_id":null,"html_url":"https://github.com/benediktwerner/intcode","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benediktwerner%2Fintcode","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benediktwerner%2Fintcode/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benediktwerner%2Fintcode/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benediktwerner%2Fintcode/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/benediktwerner","download_url":"https://codeload.github.com/benediktwerner/intcode/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252826272,"owners_count":21810086,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-17T19:52:17.123Z","updated_at":"2025-05-07T06:28:08.626Z","avatar_url":"https://github.com/benediktwerner.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Intcode compiler, assembler and VM\n\nCompiler, assembler and VM for the [intcode computer](https://adventofcode.com/2019/day/9)\nfrom Advent of Code 2019. This is mainly for fun and to try out some different Rust parsing\nlibraries.\n\nThere are four crates in this project:\n\n- `intcode`: Wrapper binary for executing the compiler, assembler or VM\n- `vm`: An intcode VM that can run intcode files: `intcode run input.int`\n- `asm`: An intcode assembler that can assemble intcode programs from intcode assembly: `intcode asm input.asm`\n- `compiler`: An intcode compiler that can compile intcode programs from a higher-level language: `intcode compile input.ic`\n\n## Building and Installing\n\nBuilding or installing requires a working [Rust Installation](https://www.rust-lang.org/).\n\nBuild from source and install:\n```\n$ git clone https://github.com/benediktwerner/intcode\n$ cd intcode\n$ cargo install --path intcode\n$ intcode\n```\n\nTo just build from source:\n\n```\n$ git clone https://github.com/benediktwerner/intcode\n$ cd intcode\n$ cargo build\n$ ./target/debug/intcode\n```\n\n## Compiler\n\nThe compiler can compile code written in a simple high-level language to intcode:\n\n```\n// Comment\n\nvar x;              // Variables must be declared before their first use. Globals are initialized to zero.\nvar y = 13;         // but they can also be declared on the first assignment\n\nvar z = input();    // Get input\nprint(y);           // Produce output\n\nfunc fib(x) {       // Arguments and variables declared in functions are seperate for each call\n    y = 42;         // Modify a global variabl\n    if x \u003c 2 {\n        return 1;\n    }\n    return fib(x - 1) * x;  // Recursion is possible\n}\n\nprint(fib(z));\nprint(x);           // Still zero because the function has its own scope\nprint(y);           // Changed to 42\n\nconst LENGTH = 6 * 7;   // Constants are computed at compile time\n\narray a[LENGTH];        // Declare a new array with the given length. Only constant expressions can be used to specify the length\n\nvar index = 0;\nwhile index \u003c LENGTH {\n    a[index] = fib(index);\n}\n\nprint(a[LENGTH - 1]);\n```\n\nAn extension for syntax highlighting in Visual Studio Code can be found in [`vscode-syntax-highlighting`](vscode-syntax-highlighting).\nIt works if the file has the `.ic` extension.\n\n## Assembler\n\n### Example\n\nThis program computes Day 1 Part 1 in intcode:\n\n```\n# Comments start with '#'\nstart:                  # Label for jump\n    in x                # Read to memory location x. The assembler automatically 'allocates' this memory after the program.\n    eq x 0 tmp          # Check if input == 0. If yes, stop and print the result.\n    jmp_true tmp :end   # Label targets must be prefixed with a ':' (to get the address instead of the value)\n    div x 3 x\n    sub x 2 x\n    add total x total\n    jmp :start\n\nend:\n    out total\n    hlt\n\n# Initialize 'total' to 0. The assembler does this automatically so\n# this isn't really neccessary, but it shows the concept.\ntotal: data 0\n```\n\nMore examples can be found in the `examples` directory.\n\n### Instructions\n\n|        Operation         |                   Effect                   |                          Note                           |\n| :----------------------: | :----------------------------------------: | :-----------------------------------------------------: |\n|      `mov a target`      |                `target = a`                |                                                         |\n|     `add a b target`     |              `target = a + b`              |                                                         |\n|     `sub a b target`     |              `target = a - b`              |                                                         |\n|     `mul a b target`     |              `target = a * b`              |                                                         |\n|     `div a b target`     |             `target = a // b`              | Can be quite slow, only works for positive numbers atm. |\n|     `mod a b target`     |              `target = a % b`              | Can be quite slow, only works for positive numbers atm  |\n| `divmod a b target rest` |       `target, rest = divmod(a, b)`        | Can be quite slow, only works for positive numbers atm  |\n|       `in target`        |             `target = input()`             |                                                         |\n|         `out a`          |                 `print(a)`                 |                                                         |\n|       `jmp target`       |               `goto target`                |                                                         |\n|      `jnz a target`      |          `if a != 0: goto target`          |                     Alias: `jtrue`                      |\n|      `jz a target`       |          `if a == 0: goto target`          |                     Alias: `jfalse`                     |\n|     `eq a b target`      |             `target = a == b`              |                                                         |\n|     `neq a b target`     |             `target = a != b`              |                                                         |\n|     `lt a b target`      |              `target = a \u003c b`              |                                                         |\n|     `leq a b target`     |             `target = a \u003c= b`              |                                                         |\n|     `gt a b target`      |              `target = a \u003e b`              |                                                         |\n|     `geq a b target`     |             `target = a \u003e= b`              |                                                         |\n|     `and a b target`     |             `target = a and b`             |                                                         |\n|     `or a b target`      |             `target = a and b`             |                                                         |\n|      `not a target`      |              `target = not a`              |                                                         |\n|     `add_rel_base a`     |              `rel_base += a`               |                                                         |\n|     `load a target`      |            `target = memory[a]`            |                                                         |\n|     `store a target`     |            `memory[target] = a`            |                                                         |\n|          `hlt`           |                  `exit()`                  |                      Alias: `halt`                      |\n|         `data x`         |           stores `x` as raw data           |    Accepts multiple arguments, e.g. `data 1 5 13 42`    |\n|     `array val len`      |    stores `val` `len` times as raw data    |                                                         |\n|        `push val`        |  `memory[rel_base] = val; rel_base += 1`   |                                                         |\n|       `pop target`       | `rel_base -= 1; target = memory[rel_base]` |                                                         |\n|      `call target`       |                 `push(ip)`                 |                                                         |\n|          `ret`           |               `goto pop(ip)`               |                                                         |\n\nThe predifined label `__end` can be used to get the address after all the generated code.\nThis is useful for putting a stack after the program: `add_rel_base :__end`. Simply putting\na label at the end of the program will not work if the program contains\nundeclared labels/variables because they will be put after the program.\n\n### Parameter types\n\n- Identifier positional: `some_name`\n- Identifier immediate: `:some_name`\n- Identifier relative: `%some_name`\n- Value positional: `[42]`\n- Value immediate: `42`\n- Value relative: `%42`\n\n## License\n\nAll 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).\n\nNote though that some parts of this code use external libraries which have their own licenses.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenediktwerner%2Fintcode","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbenediktwerner%2Fintcode","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenediktwerner%2Fintcode/lists"}