{"id":18550882,"url":"https://github.com/mrjameshamilton/cpplox","last_synced_at":"2025-04-09T22:31:23.540Z","repository":{"id":206723221,"uuid":"708426655","full_name":"mrjameshamilton/cpplox","owner":"mrjameshamilton","description":"cpplox is a Lox interpreter \u0026 LLVM compiler written in C++","archived":false,"fork":false,"pushed_at":"2024-06-28T06:14:50.000Z","size":438,"stargazers_count":12,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-24T12:47:32.963Z","etag":null,"topics":["crafting-interpreters","interpreter","llvm","llvm-compiler","llvm-ir-code-generation","lox","lox-interpreter","lox-language"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mrjameshamilton.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}},"created_at":"2023-10-22T14:32:50.000Z","updated_at":"2025-03-14T07:47:11.000Z","dependencies_parsed_at":"2023-11-18T11:23:12.680Z","dependency_job_id":"6e66c47e-aeac-488b-baef-bb87546e25fd","html_url":"https://github.com/mrjameshamilton/cpplox","commit_stats":null,"previous_names":["mrjameshamilton/cpplox"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrjameshamilton%2Fcpplox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrjameshamilton%2Fcpplox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrjameshamilton%2Fcpplox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrjameshamilton%2Fcpplox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mrjameshamilton","download_url":"https://codeload.github.com/mrjameshamilton/cpplox/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248123525,"owners_count":21051488,"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":["crafting-interpreters","interpreter","llvm","llvm-compiler","llvm-ir-code-generation","lox","lox-interpreter","lox-language"],"created_at":"2024-11-06T21:05:59.345Z","updated_at":"2025-04-09T22:31:23.093Z","avatar_url":"https://github.com/mrjameshamilton.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# cpplox\n\n`cpplox` is a Lox interpreter and LLVM compiler written in C++. By default, the `cpplox`\nwill execute the provide script with the interpreter and if provided an output file, LLVM IR or\nan object file will be generated.\n\n## LLVM Compiler\n\nThe [compiler](https://github.com/mrjameshamilton/cpplox/tree/master/src/compiler) uses LLVM to compile Lox scripts to LLVM IR, \nwhich can generate textual LLVM IR or object files.\n\nTo compile a Lox script, provide a filename with the `-o` command line option.\n\nLLVM IR files can then be executed with the `lli` interpreter:\n\n```shell\n$ bin/cpplox examples/helloworld.lox -o helloworld.ll\n$ lli helloworld.ll\n```\n\nThe compiler can also produce an object file which can be linked\ninto an executable:\n\n```shell\n$ bin/cpplox examples/helloworld.lox -o helloworld.o\n$ clang helloworld.o -o helloworld\n$ ./helloworld\n```\n\n### Implementation details\n\n* NaN boxing with values (numbers, boolean, nil and object pointers) stored as `i64`\n* interned strings using a hash table\n* [upvalues](https://craftinginterpreters.com/closures.html#upvalues) for capturing closed over variables\n    - upvalues are closed when the local goes out of scope\n* all functions and methods are wrapped in closures for consistency\n    - functions have a runtime representation with their implementations as LLVM IR functions\n    - all closures have a receiver parameter and upvalue parameter\n* mark \u0026 sweep garbage collector\n    - a shadow stack is used to track locals as GC roots\n    - temporary locals are inserted when necessary to ensure they are reachable before assignment\n\n## Interpreter\n\nThe interpreter implementation is similar to the `jlox` Java implementation from the [Crafting Interpreters](https://craftinginterpreters.com/) book\nwith the main implementation difference being the language and the use of `std::variant` instead of the visitor pattern.\n\n```shell\n$ bin/cpplox examples/helloworld.lox\n```\n\nThe following additional native functions are implemented in the interpreter to allow running [Lox.lox](https://github.com/mrjameshamilton/loxlox), an Lox interpreter written in Lox:\n\n- `read()` reads a byte from `stdin` or `nil` if end of stream\n- `utf(byte, byte, byte, byte)` converts 1, 2, 3, or 4 bytes into a UTF string\n- `printerr(string)` prints a string to `stderr`\n- `exit(number)` exits with the specific exit code\n\n# Build\n\nThe build uses cmake and ninja and produces a binary `cpplox` in the `bin` folder:\n\n```shell\n$ mkdir build\n$ cmake -S . -G Ninja -B build\n$ ninja -C build\n$ bin/cpplox ../examples/helloworld.lox\n```\n\n# Performance\n\nAs a quick performance test, running the below fibonacci example,\ngives the following run times (on my laptop, approximate average over several runs):\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eLLVM compiler\u003c/td\u003e\n    \u003ctd\u003eclox\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e0.15 seconds\u003c/td\u003e\n    \u003ctd\u003e0.55 seconds\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n```javascript\nfun fib(n) {\n  if (n \u003c 2) return n;\n  return fib(n - 2) + fib(n - 1);\n}\n\nvar start = clock();\nprint fib(40);\nvar end = clock();\nprint end - start;\n```\n\n# Lox.lox\n\nBoth the interpreter and compiler can execute [Lox.lox](https://github.com/mrjameshamilton/loxlox), a working-but-slow\nLox interpreter written in Lox itself:\n\n```shell\n$ bin/cpplox Lox.lox -o loxlox.ll\n$ cat examples/fib.lox | lli loxlox.ll\n832040\n27.0111\n```\n\n# Running tests\n\nThe interpreter passes the [jlox test suite](https://github.com/munificent/craftinginterpreters/tree/master/test) which\ncan be checked out and executed via `ninja test`:\n\n```shell\n$ mkdir build\n$ CRAFTING_INTERPRETERS_PATH=/path/to/craftinginterpreters cmake -S . -B build -G Ninja\n$ ninja -C build\n$ ninja -C build test\n```\n\n# Docker\n\nA Dockerfile is provided that contains the required dependencies and can be\nused to build `cpplox` and clone \u0026 run the Crafting Interpreters test suite:\n\n```shell\n$ docker build -t cpploxbuilder .\n$ docker run --mount type=bind,source=\"$(pwd)\",target=/app --rm cpploxbuilder\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrjameshamilton%2Fcpplox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmrjameshamilton%2Fcpplox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrjameshamilton%2Fcpplox/lists"}