{"id":47002093,"url":"https://github.com/gold-silver-copper/grift","last_synced_at":"2026-03-11T19:20:11.026Z","repository":{"id":334724452,"uuid":"1142233985","full_name":"gold-silver-copper/grift","owner":"gold-silver-copper","description":"grift is a no_std no_alloc no_unsafe lisp for bare-metal devices","archived":false,"fork":false,"pushed_at":"2026-03-09T10:43:18.000Z","size":7833,"stargazers_count":6,"open_issues_count":0,"forks_count":3,"subscribers_count":0,"default_branch":"pure","last_synced_at":"2026-03-09T11:52:50.604Z","etag":null,"topics":["arduino","embedded","esp32","lisp","no-alloc","no-std","rust","scheme"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gold-silver-copper.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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-01-26T06:07:33.000Z","updated_at":"2026-03-09T10:43:22.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/gold-silver-copper/grift","commit_stats":null,"previous_names":["gold-silver-copper/pwn_arena","gold-silver-copper/grift"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/gold-silver-copper/grift","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gold-silver-copper%2Fgrift","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gold-silver-copper%2Fgrift/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gold-silver-copper%2Fgrift/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gold-silver-copper%2Fgrift/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gold-silver-copper","download_url":"https://codeload.github.com/gold-silver-copper/grift/tar.gz/refs/heads/pure","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gold-silver-copper%2Fgrift/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30395235,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-11T18:46:22.935Z","status":"ssl_error","status_checked_at":"2026-03-11T18:46:17.045Z","response_time":84,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["arduino","embedded","esp32","lisp","no-alloc","no-std","rust","scheme"],"created_at":"2026-03-11T19:20:08.893Z","updated_at":"2026-03-11T19:20:11.000Z","avatar_url":"https://github.com/gold-silver-copper.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# grift\n\nGrift is a small Kernel-inspired Lisp interpreter for constrained Rust\nenvironments. It implements first-class operatives (`vau`), applicatives,\nfirst-class environments, and tail-call optimization on top of a fixed-size\narena with no heap allocation and no `unsafe` code.\n\nThe project is aimed at embedded or resource-bounded settings where a normal\nallocator-backed Lisp runtime would be a poor fit, while still preserving a\nsubstantial part of the vau-calculus execution model.\n\n## Highlights\n\n- `#![no_std]`, `no_alloc`, `#![forbid(unsafe_code)]`\n- Fixed-capacity arena with free-list allocation\n- Mark-and-sweep garbage collection, triggered on OOM and available explicitly\n  via `(gc-collect)`\n- Kernel-style operative/applicative model\n- First-class mutable environments with lexical parent lists\n- Tail-call optimization via a trampoline evaluator\n- Immutable pairs and `CharPair`-based string storage\n- Symbol interning\n- Checked integer arithmetic\n- Rust native-function registration through `Lisp::register_native`\n- Lazy prelude loading from `prelude.grift`\n\n## What It Implements\n\nGrift is not a Scheme clone. The language model is centered on `vau`, where an\noperative receives its operands unevaluated together with the caller's\nenvironment.\n\nThat gives the runtime three important properties:\n\n- user-defined control forms are first-class values rather than a separate macro\n  system\n- `lambda` is derived from the operative model rather than being primitive\n- environments are explicit runtime values that can be captured, passed around,\n  and selectively exposed\n\nThe current builtin surface includes:\n\n- operatives such as `quote`, `if`, `define!`, `fn!`, `set!`, `begin`, `cond`,\n  `and`, `or`, `let`, `vau`, and `current-environment`\n- applicatives such as arithmetic, list primitives, equality, `eval`, `wrap`,\n  `unwrap`, environment constructors, GC control, and raw read/write helpers\n\n`apply` and `wrap` operate uniformly over first-class callables, including\nbuiltin operatives such as `if`.\n\n## Rust API\n\n```rust\nuse grift::{Lisp, Value};\n\nlet lisp: Lisp\u003c20_000\u003e = Lisp::new();\n\nassert_eq!(lisp.eval(\"(+ 1 2)\"), Ok(Value::Number(3)));\nassert_eq!(lisp.eval(\"(car (cons 1 2))\"), Ok(Value::Number(1)));\n```\n\nThe const generic parameter sets the arena capacity in slots. A larger value\ngives the interpreter more space for code, data, environments, temporary\nevaluation state, and garbage-collector working room.\n\nNative Rust functions can be exposed as Lisp applicatives:\n\n```rust\nuse grift::{ArenaIndex, ArenaResult, Lisp, LispOps, extract_arg};\n\nfn double(lisp: \u0026dyn LispOps, args: ArenaIndex) -\u003e ArenaResult\u003cArenaIndex\u003e {\n    let (n, _rest): (isize, ArenaIndex) = extract_arg(lisp, args)?;\n    lisp.number(n * 2)\n}\n\nlet lisp: Lisp\u003c20_000\u003e = Lisp::new();\nlisp.register_native(\"double\", double).unwrap();\n\nassert_eq!(lisp.eval(\"(double 21)\"), Ok(grift::Value::Number(42)));\n```\n\n## Lisp Example\n\n```lisp\n;; Operatives receive operands unevaluated.\n(define! my-quote\n  (vau (x) #ignore x))\n\n(my-quote (+ 1 2))   ; =\u003e (+ 1 2)\n\n;; lambda can be defined in terms of vau.\n(define! lambda\n  (vau (formals . body) e\n    (wrap\n      (eval (cons 'vau\n                  (cons formals\n                        (cons #ignore body)))\n            e))))\n\n(define! double\n  (lambda (x)\n    (* x 2)))\n\n(double 5)           ; =\u003e 10\n\n;; The caller environment can be captured explicitly.\n(define! my-if\n  (vau (test then else) e\n    (if (eval test e)\n        (eval then e)\n        (eval else e))))\n\n(apply if (list #t 1 2)) ; =\u003e 1\n((wrap if) #t 1 2)       ; =\u003e 1\n\n;; Tail recursion runs through the trampoline evaluator.\n(fn! fib (n a b)\n  (if (= n 0)\n      a\n      (fib (- n 1) b (+ a b))))\n\n(fib 50 0 1)         ; =\u003e 12586269025\n```\n\n## Runtime Model\n\nEvery runtime value lives inside `Arena\u003cValue, N\u003e`. The evaluator does not rely\non heap allocation, and the runtime keeps a small set of reserved singleton\nslots for values such as `NIL`, booleans, `#inert`, `#ignore`, the ground\nenvironment, the global environment, GC roots, and the symbol intern list.\n\nCurrent implementation details that matter:\n\n- strings are stored as linked `CharPair` chains rather than contiguous buffers\n- empty string is represented internally as `NIL`\n- user code runs in the global environment, which is a child of the builtin\n  ground environment\n- GC is currently demand-driven: the evaluator collects when allocation hits\n  `OutOfMemory`\n\nMore detail is in [docs/architecture/ARCHITECTURE.md](docs/architecture/ARCHITECTURE.md).\n\n## Build And Test\n\n```bash\ncargo build --workspace\ncargo test --workspace\n```\n\nRun the benchmark example:\n\n```bash\ncargo run -p grift --example fib_bench --release\n```\n\nRun the REPL:\n\n```bash\ncargo run -p grift --features repl\n```\n\n## Toolchain\n\nThe workspace MSRV is **Rust 1.85** (edition 2024), as declared in\n`Cargo.toml`.\n\n## Further Reading\n\n- [docs/architecture/ARCHITECTURE.md](docs/architecture/ARCHITECTURE.md): current architecture and language notes\n- [docs/grift/index.md](docs/grift/index.md): generated API-oriented documentation\n- [05-07.pdf](05-07.pdf): Revised-1 Report on the Kernel Programming Language\n- [jshutt.pdf](jshutt.pdf): \"vau: the ultimate abstraction\"\n\n## License\n\nMIT OR Apache-2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgold-silver-copper%2Fgrift","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgold-silver-copper%2Fgrift","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgold-silver-copper%2Fgrift/lists"}