{"id":50639962,"url":"https://github.com/openpeeps/vancode","last_synced_at":"2026-06-07T07:04:54.415Z","repository":{"id":352711336,"uuid":"1214684719","full_name":"openpeeps/vancode","owner":"openpeeps","description":"A flexible, macro-based AST, Codegen \u0026 Virtual Machine for building scripting languages and DSLs","archived":false,"fork":false,"pushed_at":"2026-05-29T22:37:45.000Z","size":1079,"stargazers_count":2,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-05-30T00:14:38.861Z","etag":null,"topics":["abstract-syntax-tree","ast","bytecode","bytecode-interpreter","codegen","interpreter","interpreters","nim","openpeeps","programming-language","stack","stackvm","virtual-machine","vm"],"latest_commit_sha":null,"homepage":"https://openpeeps.github.io/vancode/","language":"Nim","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/openpeeps.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-18T22:54:35.000Z","updated_at":"2026-05-29T22:36:50.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/openpeeps/vancode","commit_stats":null,"previous_names":["openpeeps/vancode"],"tags_count":1,"template":false,"template_full_name":"openpeeps/pistachio","purl":"pkg:github/openpeeps/vancode","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openpeeps%2Fvancode","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openpeeps%2Fvancode/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openpeeps%2Fvancode/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openpeeps%2Fvancode/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/openpeeps","download_url":"https://codeload.github.com/openpeeps/vancode/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openpeeps%2Fvancode/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34011828,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-07T02:00:07.652Z","response_time":124,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["abstract-syntax-tree","ast","bytecode","bytecode-interpreter","codegen","interpreter","interpreters","nim","openpeeps","programming-language","stack","stackvm","virtual-machine","vm"],"created_at":"2026-06-07T07:04:34.106Z","updated_at":"2026-06-07T07:04:54.406Z","avatar_url":"https://github.com/openpeeps.png","language":"Nim","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/openpeeps/vancode/blob/main/.github/vancode.png\" width=\"200px\"\u003e\u003cbr\u003e\n  A flexible AST, Codegen and Virtual Machine library\u003cbr\u003e\n  for building your own toy language, scripting engines and DSLs.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ccode\u003enimble install vancode\u003c/code\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://openpeeps.github.io/vancode\"\u003eAPI reference\u003c/a\u003e\u003cbr\u003e\n  \u003cimg src=\"https://github.com/openpeeps/vancode/workflows/test/badge.svg\" alt=\"Github Actions\"\u003e  \u003cimg src=\"https://github.com/openpeeps/vancode/workflows/docs/badge.svg\" alt=\"Github Actions\"\u003e\n\u003c/p\u003e\n\n## About\nVanCode is a tiny library for building bytecode interpreters and virtual machines in Nim. It provides a simple and efficient way to define and execute bytecode instructions, making it easier to create custom programming languages, scripting engines and DSLs (domain-specific languages).\n\nThis is a _bring-your-own-parsing_ library, so it doesn't come with a built-in Parser or Lexer. When implementing your own Parser you must use the [VanCode AST](https://openpeeps.github.io/vancode/vancode/interpreter/ast.html) provided by the library. No worries, most of the AST is pretty self-explanatory and easy to use.\n\nIt's also pretty flexible so you can easily extend it with your own custom nodes via Nim's macro system at compile-time without having to modify the library's source code.\n\n## 😍 Key Features\n- [x] Bring-your-own Lexer and Parser for maximum flexibility\n- [x] Built-in AST (Abstract Syntax Tree) representation\n- [x] Simple and efficient bytecode instruction definition and execution\n- [x] Support for multiple data types and operations\n- [ ] FFI for calling Nim code or external libraries\n- [ ] Generate self-contained executables\n- [ ] JIT (Just-In-Time) compilation for improved performance\n- [ ]  (Ahead-Of-Time) compilation for static binaries\n- [ ] Built-in package manager for easy distribution and installation\n- [x] Written in Nim language\n\n\u003e [!NOTE]\n\u003e VanCode is far from being a complete solution, I'm planning to add more features and improvements as I go, while still learning about how to design a good flexible interpreter and VM.\n\n## Examples\nLet's showcase some cool examples!\n\n### Calculator example\n\nHere is a simple calculator example that demonstrates how to use VanCode to construct the AST for a simple expression, pass it trough the code generator to produce bytecode, and then execute it in the VM.\n\n```nim\nimport std/options\nimport vancode/interpreter/[ast, codegen, chunk, value, vm, sym]\nimport vancode/interpreter/stdlib/syslib\n\n# 1. Build the AST for: 1 + 2 * 3\nlet astExpr =\n  ast.newCall(\n    ast.newIdent(\"echo\"),\n    ast.newTree(nkInfix,\n      ast.newIdent(\"+\"),\n      ast.newIntLit(1),\n      ast.newTree(nkInfix,\n        ast.newIdent(\"*\"),\n        ast.newIntLit(2),\n        ast.newIntLit(3)\n      )\n    )\n  )\n\n# 2. Wrap in a script AST node\nlet astScript = Ast(\n  sourcePath: \"calculator\",\n  nodes: @[astExpr]\n)\n\n# 3. Prepare codegen context\nlet mainChunk = newChunk(\"calculator\")\nlet script = newScript(mainChunk)\n\nlet module = newModule(\"calculator\", some(\"calculator\"))\nblock init_system_module:\n  module.initSystemTypes()\n  script.initSystemOps(module)\n\n  # Adding a FFI proc for `echo` so we can see the output of the calculation\n  script.addProc(module, \"echo\", @[paramDef(\"x\", ttyInt)], ttyVoid,\n    proc (args: StackView, argc: int): Value =\n      echo args[0].intVal)\n\n  script.addProc(module, \"echo\", @[paramDef(\"x\", ttyFloat)], ttyVoid,\n    proc (args: StackView, argc: int): Value =\n      echo args[0].floatVal)\n\n# 4. Generate bytecode from AST\nlet gen = initCompiler(script, module, mainChunk, nil, nil)\ngen.genScript(astScript, none(string))\n\n# 5. Run in the VM\nlet vmInstance = newVm()\ndiscard vmInstance.interpret(script, mainChunk)\n```\n\n👉 Check the [examples/calculator.nim](https://github.com/openpeeps/vancode/blob/main/examples/calculator.nim) for a more complete REPL implementation of the calculator example.\n\n## What's included\n\n### Codegen prebuilt operations\nVanCode comes with a set of prebuilt operations for common tasks like arithmetic, logic, control flow, function calls and more. [Check Codegen API reference](https://openpeeps.github.io/vancode/vancode/interpreter/codegen.html) for the full list of prebuilt operations and how to use them.\n\nFind the system operation functions in the [`vancode/interpreter/stdlib/syslib.nim`](https://github.com/openpeeps/vancode/blob/main/src/vancode/interpreter/stdlib/syslib.nim) module. You can use these prebuilt functions to quickly add common\nfunctionality to your language without having to implement them from scratch.\n\n#### FFI support\nVanCode provides a simple FFI (Foreign Function Interface) mechanism that allows you to call Nim code or C libraries directly from your Script modules. From there you can easily expose any functionality you want to your scripts.\n\n### AST prebuilt nodes\nVanCode also comes with a set of prebuilt AST nodes for common constructs like literals, variables, function calls, control flow and more. [Check AST API reference](https://openpeeps.github.io/vancode/vancode/interpreter/ast.html) for the full list.\n\n### Operation Codes\nVanCode's VM comes with a set of prebuilt instructions for executing the bytecode generated by the Codegen. These instructions cover a wide range of operations, from basic arithmetic and logic to control flow and function calls. [Check Chunk API reference](https://openpeeps.github.io/vancode/vancode/interpreter/chunk.html#Opcode) for more details.\n\n## Extend AST, Codegen and VM with Voodoo\nVanCode provides a powerful and flexible way to extend the AST, Codegen and VM with your own custom nodes, instructions and operations using Nim's macro system.\n\n_todo example here_\n\n\n\u003e [!NOTE]\n\u003e For a full example of how to use Voodoo to extend the AST, Codegen and VM, check the [Tim Engine](https://github.com/openpeeps/tim/blob/main/src/tim/engine/transformers.nim) transformers module.\n\n## Projects using VanCode\n- [Tim Engine](https://github.com/openpeeps/tim) - A beautiful template engine and DSL for generating HTML templates\n\n## Roadmap\n- [ ] AOT/JIT compilation using [gccjit](https://github.com/openpeeps/gccjit.nim) bindings\n- [ ] Self-contained executable generation (Similar to how Node/Bun generate self-contained executables)\n- [ ] VM Hot code optimization\n- [ ] Add more Voodoo flexibility and extensibility features to the AST, Codegen and VM\n\nNotes:\n- https://vivekn.dev/blog/bytecode-vm-scratch/\n- https://github.com/liquidev/hayago - VanCode contains work from hayago, a very interesting project that is no longer maintained but provides a good reference for Nim-based bytecode VMs. Cheers to the author! 😻\n\n### ❤ Contributions \u0026 Support\n- 🐛 Found a bug? [Create a new Issue](https://github.com/openpeeps/vancode/issues)\n- 👋 Wanna help? [Fork it!](https://github.com/openpeeps/vancode/fork)\n\n### 🎩 License\nLGPLv3 license. [Made by Humans from OpenPeeps](https://github.com/openpeeps).\u003cbr\u003e\nCopyright OpenPeeps \u0026 Contributors \u0026mdash; All rights reserved.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenpeeps%2Fvancode","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenpeeps%2Fvancode","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenpeeps%2Fvancode/lists"}