The full eval-kl chain is working: (+ 1 2) marshalled to tagged form, compiled through the metacircular pipeline, executed by the metacircular interpreter, demarshalled back to native — it returns 3. Pure self-hosting, no C bypass.
The meta-circular evaluator is the core — the ZINC abstract machine implemented in ~100 lines of Shen pattern-matching rules, serialized to ~0.33 MB of bytecode, and loaded by a ~2600-line C VM with a custom moving generational garbage collector. The VM is self-contained: a working Shen runtime that depends only on a C compiler and its own GC — no Boehm, no host runtime.
shen->kl compiler, no Shen OS code.Shen source → shen->kl (own compiler) → KLambda → kmacros → normalize → debruijn
→ zinc-c → csexp → C VM
↑
interp.shen (meta-circular ZINC VM on Shen/Chez)
↓
serialize-reduced → globals.csexp → C VM (self-hosting)Every stage — the Shen→KLambda front-end, the normalizer, the ZINC compiler, the metacircular interpreter, the serializer — is part of this repo. The full architecture walk-through →
| Layer | What it does |
|---|---|
| shen->kl | Own full-arity Shen→KLambda compiler (safe subset, no partial application). |
| normalize | KLambda expansion, A-normal form, debruijn indices. |
| zinc-c | KLambda → ZINC bytecode, incl. %% primitive dispatch. |
| interp | The ZINC interpreter in Shen — loads, compiles, and runs. |
| zincvm.c | The native C parser + VM — all primitives, closures, tail calls, custom GC. |
| zincdec | Standalone bytecode decompiler — 4 output formats + --curried scan. |
Native values are marshalled to tagged Shen forms through the marshal_to_tagged layer.
The tagged form goes extract-kl → kl→zinc → toplevel-interp — compiled entirely by our own compiler.
The metacircular interp (97 pattern-match rules in shen/interp.shen) runs the bytecode on the C VM.
The result demarshals back to a native value. (+ 1 2) → 3. Shen compiles Shen, which runs on Shen, on the C VM.