On this page
Architecture
Full, up-to-date architecture docs live in
docs/architecture/. This page used to describe the whole compiler pipeline in one file but only covered 9 of the 32 crates incrates/(~28%) and predated the native, LLVM and wasm-aot backends. It is now a short overview + pointer; the layered pipeline, the full crate table, the 9-surfaces checklist, and the ADRs (architecture decisions) all moved todocs/architecture/.
Overview¶
Zolo compiles the same .zolo source to four execution targets that share a
front-end (lexer → parser → single desugar pipeline → typeck):
- VM (
zolo run) — compiles to Lua 5.1 source, executed byzolo-vm, a Lua 5.1 VM implemented in Rust. This is the reference/oracle backend. - Native (
zolo build --emit native) — Cranelift, viazolo-native. - LLVM (
zolo build --emit llvm) — reuses the native backend's AST→IR lowering, emits LLVM IR, links withclang/lld. - wasm-aot (
zolo build --emit wasm) — also reuses the shared IR lowering, emits a WebAssembly module directly.
See docs/architecture/layers.md
for the full pipeline diagram and
docs/architecture/crates.md
for the table of all 32 crates (front-end, backends, shared IR/runtime,
stdlib, tooling).
Crate Structure (top-level orientation only)¶
zolo-lang/
├── crates/
│ ├── zolo-lang/ # CLI binary (facade for run/build/check/test/fmt/fix/dev)
│ ├── zolo-lexer/ # Tokenizer
│ ├── zolo-parser/ # Parser → AST
│ ├── zolo-compiler/ # Front-end desugar pipeline, typeck, VM-path lowering (AST → Lua)
│ ├── zolo-vm/ # Lua 5.1 VM (executes the Lua the VM path emits) — the oracle backend
│ ├── zolo-native/ # AST → ZoloIR lowering (shared) + Cranelift codegen
│ ├── zolo-llvm/ # Reuses zolo-native's lowering; emits LLVM IR
│ ├── zolo-wasm-aot/ # Reuses zolo-native's lowering; emits WebAssembly directly
│ ├── zolo-ir/ # Shared IR (native/LLVM/wasm-aot)
│ ├── zolo-runtime/ # Native/LLVM ABI: NaN-boxed values, GC, tables, plugin bridge
│ ├── zolo-std/ # VM-path stdlib (Lua prelude)
│ ├── zolo-lsp/ # Language Server Protocol
│ ├── zolo-dap/ # Debug Adapter Protocol
│ └── zolo-fmt/ # Code formatter
│ └── … 18 more crates — see docs/architecture/crates.md
├── editors/
│ └── vscode/ # VS Code extension
└── examples/ # Example .zolo filesFor per-crate responsibilities (all 32), dependency edges, and which of the
"9 surfaces" each one touches, see
docs/architecture/crates.md.
Data Flow¶
Running a file (VM path)¶
zolo run hello.zolo
→ lex tokens (zolo-lexer)
→ parse AST (zolo-parser)
→ front-end desugar pipeline, 7 passes (zolo-compiler::front_end)
→ macro/derive expansion + type check (zolo-compiler)
→ lower to Lua 5.1 source, with prelude prepended (zolo-compiler::lowering)
→ compile Lua to bytecode and execute (zolo-vm)Building a native/LLVM/wasm binary¶
zolo build hello.zolo --emit native|llvm|wasm
→ lex, parse, desugar, typeck (same front-end as above)
→ lower AST to ZoloIR (zolo-native::lower_to_ir — shared by all three)
→ native: Cranelift codegen → object → link against zolo-runtime
→ llvm: LLVM IR emission → clang/lld → link against zolo-runtime
→ wasm: direct wasm lowering + zolo-wasm-emit encoder → .wasm moduleThe VM is treated as the oracle: crates/zolo-lang/tests/e2e_vm_native.rs
and crates/zolo-llvm/tests/parity.rs diff stdout/exit-code of the AOT
backends against it. See
ADR 0005.
LSP request¶
VS Code → LSP Client → stdin → zolo-lsp
→ parse document (on each edit)
→ respond to request (hover/completion/etc.) — each feature builds its
own analysis AST, see docs/architecture/surfaces.md §7
→ stdout → LSP Client → VS CodeDebug session¶
VS Code → DAP Client → stdin → zolo-dap
→ compile source to Lua (with source map)
→ set breakpoints (mapped via source map)
→ step/continue (track current line)
→ respond with stack frames / variables
→ stdout → DAP Client → VS CodeArchitecture decisions (ADRs)¶
Why the architecture is shaped this way — and which alternatives were
rejected — is recorded in docs/decisions/*.md. See the index and format
guide at
docs/architecture/adr/README.md.