{"id":13813101,"url":"https://github.com/tekknolagi/carp","last_synced_at":"2025-05-14T22:31:48.208Z","repository":{"id":14036350,"uuid":"16738734","full_name":"tekknolagi/carp","owner":"tekknolagi","description":"\"interesting\" VM in C. Let's see how this goes.","archived":true,"fork":false,"pushed_at":"2021-01-18T23:05:49.000Z","size":425,"stargazers_count":980,"open_issues_count":6,"forks_count":84,"subscribers_count":60,"default_branch":"master","last_synced_at":"2024-11-19T07:40:43.165Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tekknolagi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-02-11T17:22:50.000Z","updated_at":"2024-10-25T16:27:12.000Z","dependencies_parsed_at":"2022-07-19T05:32:08.487Z","dependency_job_id":null,"html_url":"https://github.com/tekknolagi/carp","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tekknolagi%2Fcarp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tekknolagi%2Fcarp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tekknolagi%2Fcarp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tekknolagi%2Fcarp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tekknolagi","download_url":"https://codeload.github.com/tekknolagi/carp/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254239704,"owners_count":22037754,"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-08-04T04:01:03.222Z","updated_at":"2025-05-14T22:31:42.772Z","avatar_url":"https://github.com/tekknolagi.png","language":"C","readme":"# THIS PROJECT IS UNSTABLE AND DEPRECATED\n\nI have since started slow work on a more stable, better thought-out project\ncalled [RabbitVM](https://github.com/rabbitvm/rabbit). It doesn't quite have the\nsame level of documentation but it should work much better.\n\n# CarpVM\nThis is a project I've been slowly working on for about half a year now. The goal is to try and build a small (and decently reliable) VM from the ground up, learning more and more C as I go.\n\nRight now there are instructions, registers, a stack, data memory, and calls. Not sure if recursion works... it should in theory. Haven't tested.\n\nCONSIDER THIS PRE-ALPHA SOFTWARE. Things change more than they do in Rust!\n\n[![Build Status](https://travis-ci.org/tekknolagi/carp.svg?branch=master)](https://travis-ci.org/tekknolagi/carp) \u0026nbsp;\n![](https://ga-beacon.appspot.com/UA-47678422-4/tekknolagi/carp) \u0026nbsp;\n[![Flattr this](http://api.flattr.com/button/flattr-badge-large.png)](http://flattr.com/thing/3268893/tekknolagicarp-on-GitHub)\n\n## Installation\n\n### Getting Carp\n\n**If you already have a local copy (cloned before submodule was added)**\n\n* `git fetch`\n* `git rebase`\n* `git submodule init`\n* `git submodule update`\n\n**If you don't already have a local copy**\n\n* `git clone --recursive`\n\nNOTE: If `git submodule status` doesn't return a SHA1 hash and repository name, you have a problem.\nNOTE: Recursive clone is for testing library. If not included, tests will not build.\n\n### Building Carp\n\n1. `make`\n2. `make test` (optional)\n3. `make install`\n4. `make clean` (optional)\n\n#### Tested Machines\n\nArch (bit) | OS (with version, name) | Compiler (with version)\n---------- | ----------------------- | -----------------------\n64-bit     | Ubuntu 12.04 (precise)  | gcc 4.6.3\n64-bit     | Ubuntu 14.04 (trusty)   | gcc 4.8.2\n32-bit     | Ubuntu 14.04 (trusty)   | gcc 4.8.2\n64-bit     | OS X 10.9.4 (Mavericks) | clang 3.2\n32-bit     | OS X 10.9.4 (Mavericks) | gcc 4.2.1\n64-bit     | Arch Linux 3.13.6-1     | clang 3.4.2\n64-bit?    | Arch Linux 3.13.6-1     | gcc 4.9.0 20140604\n\n## Use\n\nNOTE: See `carp -h` for help with command-line options.\n\n### Interpreter\n\n1. Write a Carp file - see [SYNTAX.md](http://github.com/tekknolagi/carp/tree/master/SYNTAX.md). More formal spec coming.\n2. Run `./carp.out -f your_file.carp`.\n\n### API\n\n1. Include `carp/carp_machine.h` in your program.\n2. Run `gcc program.c /usr/local/lib/libcarp.a -o program.out`.\n\n## Instruction set\n\nOpcode | Arguments | Description\n------ | --------- | -----------\nHALT   | exit code | Sets `ext` to given code, halts, and attempts to clean up stack, data memory, and label memory.\nNOP    |           | Does nothing. Seriously.\nLOADR  | reg, val  | Loads given integer value into given register.\nLOAD   | diff      | Loads value at location `fp` + diff in the stack.\nSTORE  | diff, val | Stores value at location `fp` + diff.\nMOV    | dst, src  | Copies contents of src register into dst register.\nADD    |           | Pops the top two integers from the stack and pushes their sum.\nSUB    |           | Pops the top two integers from the stack and pushes the difference (lower minus upper).\nMUL    |           | Pops the top two integers from the stack and pushes their product.\nMOD    |           | Pops the top two integers from the stack and pushes lower % upper.\nSHR    |           | Pops the top two integers from the stack and pushes lower \u003e\u003e upper.\nSHL    |           | Pops the top two integers from the stack and pushes lower \u003c\u003c upper.\nNOT    |           | Pops top integer from stack and pushes bitwise NOT of that integer.\nXOR    |           | Pops the top two integers from the stack and pushes bitwise XOR..\nOR     |           | Pops the top two integers from the stack and pushes bitwise OR.\nAND    |           | Pops the top two integers from the stack and pushes bitwise AND.\nINCR   | reg       | Increments value in given register.\nDECR   | reg       | Decrements value in given register.\nINC    |           | Increments the value at the top of the stack.\nDEC    |           | Decrements the value at the top of the stack.\nPUSHR  | reg       | Pushes value in given register.\nPUSH   | val       | Pushes given value.\nPOP    | reg       | Pops an integer from the stack and dumps it into given register.\nCMP    |           | Pops the top two integers from the stack and checks if equal. 0 means equal. Pushes result.\nLT     |           | Pops the top two integers from the stack and checks if lower \u003c upper. Pushes result.\nGT     |           | Pops the top two integers from the stack and checks if lower \u003e upper. Pushes result.\nJZ     | addr      | Jumps to given absolute address if top of the stack is 0.\nRJZ    | diff      | Adds differential to `ip` (relative jump) if top of the stack is 0.\nJNZ    | addr      | Jumps to given absolute address if top of the stack is not 0.\nRJNZ   | diff      | Adds differential to `ip` (relative jump) if top of the stack is not 0.\nJMP    | addr      | Jumps to given absolute address unconditionally.\nRJMP   | diff      | Adds differential to `ip` (relative jump) unconditionally.\nCALL   | key/addr  | Save state and set IP to value in data memory at key. Function may return value in `ax`.\nRET    |           | Put top of the stack into `ax` and load previous state.\nPREG   | reg       | Prints contents of given register.\nPTOP   |           | Peeks top of stack and prints top value.\n\n## Registers\n\nName | Purpose\n---- | -------\n`r0` ... `r9` | General purpose.\n`ax` | Return value for user-defined function.\n`bx`, `cx`, `dx`, `rx` | ... something in the future. Just taking up space for now.\n`ip` | Instruction pointer. Used for keeping place in code, gotos, calling, etc.\n`sp` | Stack pointer.\n`fp` | Frame pointer. Used to keep state for function calls.\n`gbg` | Garbage register mainly used for popping.\n`run` | Boolean - is machine running?\n`ext` | Exit code.\n\n## How to contribute\n\nOne way:\n\n1. Check out the TODO.md file to see if anything needs doing.\n2. Write some code (following existing implicit style) and submit a pull request.\n\nAnother way:\n\n1. Write some code for a feature you want to exist and submit a pull request.\n\n## License\n\nGPLv3. See [LICENSE.txt](http://github.com/tekknolagi/carp/tree/master/LICENSE.txt).\n","funding_links":[],"categories":["Virtual Machines","排序","C","虚拟机","Compilers and Interpreters"],"sub_categories":["虚拟机","Educational and Toy Projects"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftekknolagi%2Fcarp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftekknolagi%2Fcarp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftekknolagi%2Fcarp/lists"}