Architecture

Overview #

Zolo is a compiled language that transpiles to Lua 5.1 and runs on a custom Lua VM implemented in Rust. The pipeline is:

Zolo Source (.zolo)
    ↓
  Lexer (zolo-lexer)     → Token stream
    ↓
  Parser (zolo-parser)   → AST
    ↓
  Type Checker (zolo-compiler/typeck)  → Type-checked AST
    ↓
  Lowering (zolo-compiler/lowering)    → Lua 5.1 source code
    ↓
  Lua Compiler (zolo-vm)               → Lua bytecode
    ↓
  Lua VM (zolo-vm)                     → Execution

Crate Structure #

zolo-lang/
├── crates/
│   ├── zolo-lang/        # CLI binary (facade)
│   ├── zolo-lexer/       # Tokenizer
│   ├── zolo-parser/      # Parser → AST
│   ├── zolo-compiler/    # AST → Lua transpiler + type checker
│   ├── zolo-vm/          # Lua 5.1 VM (ported from luaoxide)
│   ├── zolo-std/         # Standard library (Lua runtime)
│   ├── zolo-lsp/         # Language Server Protocol
│   ├── zolo-dap/         # Debug Adapter Protocol
│   └── zolo-fmt/         # Code formatter
├── editors/
│   └── vscode/           # VS Code extension
└── examples/             # Example .zolo files

Crate Details #

zolo-lexer #

Tokenizes Zolo source code into a stream of tokens with spans.

Key files:

  • token.rsTokenKind enum with all token types
  • lexer.rsLexer struct, iterator over tokens
  • keywords.rs — Keyword lookup table

Handles: String interpolation ("text {expr} more"), tagged templates (tag"..."), all operators, comments (// and /* */).

zolo-parser #

Recursive descent parser that produces an AST.

Key files:

  • ast.rs — Complete AST type definitions (Program, Item, Expr, Stmt, Pattern, TypeExpr)
  • parser.rsParser struct with Pratt-style expression parsing
  • error.rs — Parse errors with source spans

Handles: Operator precedence, all expression types, pattern matching, decorators, generics.

zolo-compiler #

Transpiles the Zolo AST to Lua 5.1 source code.

Key files:

  • lowering.rsLuaEmitter that walks the AST and emits Lua code
  • compiler.rs — High-level compile_to_lua() and compile_to_lua_with_source_map()
  • typeck.rs — Basic type inference and checking

Key translations:

Zolo Lua
let x = 10 local x = 10
fn f(a, b) { a + b } local function f(a, b) return a + b end
|x| x * 2 function(x) return x * 2 end
a |> f(b) f(a, b)
a &. f() (function(x) f(x); return x end)(a)
a?.b (a ~= nil and a.b or nil)
a ?? b (function() local __t = a; if __t ~= nil then return __t else return b end end)()
arr[i] arr[i + 1] (0-indexed → 1-indexed)
struct S { x } Constructor function + metatable
enum E { A(x) } {__tag="A", x}
match Chain of if/elseif with destructuring
@memoize fn f() Cache wrapper around function
@deprecated fn f() Warn-once wrapper
@builder struct S Builder methods generated after struct

Compilation modes:

  • Run — skip @test functions
  • Test — include @test functions and emit test runner

Source maps: The emitter tracks (lua_line, zolo_line) pairs for debugging.

zolo-vm #

A Lua 5.1 VM ported from luaoxide, implemented entirely in Rust.

Key components:

  • Bytecode execution (38 Lua 5.1 opcodes)
  • Stack-based VM with frame management
  • Tri-color mark-sweep garbage collector
  • Hybrid array+hash tables
  • String interning
  • Standard library (base, string, table, math, io, os, debug, coroutine)

zolo-std #

Runtime standard library written in Lua, injected as a prelude before user code.

Provides: string.*, Array.*, Map.*, Set.*, Option.*, Result.*, Iter.*, BigInt.*, assert_eq, assert_ne.

zolo-lsp #

Language Server Protocol implementation using tower-lsp.

Modules:

  • server.rs — Main LSP server, registers capabilities, dispatches requests
  • hover.rs — Hover information for symbols
  • completion.rs — Autocomplete suggestions
  • definition.rs — Go to definition
  • symbols.rs — Document symbol outline
  • semantic_tokens.rs — Semantic highlighting tokens
  • signature_help.rs — Function signature parameter info
  • inlay_hints.rs — Type and parameter name hints
  • document.rs — Document state management with DashMap

zolo-dap #

Debug Adapter Protocol implementation over stdin/stdout.

Modules:

  • protocol.rs — DAP message types (Request, Response, Event)
  • transport.rs — Content-Length framed JSON I/O
  • session.rs — Debug session handling (launch, breakpoints, stepping)

zolo-fmt #

AST-based code formatter.

Key file:

  • printer.rs — Walks the AST and prints formatted Zolo code

VS Code Extension #

TypeScript extension for VS Code.

Key files:

  • extension.ts — Extension entry point, LSP client, command registration
  • explorer.ts — Zolo Explorer sidebar (TreeDataProvider)
  • astViewer.ts — AST Viewer webview panel
  • debugProvider.ts — Debug adapter factory
  • package.json — Extension manifest (contributions, activation, commands)

Data Flow #

Running a File #

zolo run hello.zolo
    → read file
    → lex tokens
    → parse AST
    → type check
    → lower to Lua (with prelude prepended)
    → compile Lua to bytecode (via VM)
    → execute bytecode

LSP Request #

VS Code → LSP Client → stdin → zolo-lsp
    → parse document (on each edit)
    → respond to request (hover/completion/etc.)
    → stdout → LSP Client → VS Code

Debug 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 Code
enespt-br