English | 简体中文
Haifa Python is a teaching-oriented compiler, interpreter, and virtual machine playground written in Python. It is designed for people who want to inspect the full path from source code to runtime state: lexer, parser, AST, semantic analysis, bytecode generation, VM execution, debugging, visualization, and lowering to a lower-level VM target.
The project currently contains four connected learning tracks:
pyjq: a jq-style JSON query/runtime toolpylua: a Lua subset with bytecode compilation, tables, closures, coroutines, tracing, and standard library supportpyscheme: a small Scheme runtime and bytecode compiler with lexical scope, pairs, lists, vectors, control forms, closures, and REPL supportHaifaArmV9VM: an ARMv9-style teaching VM target with fixed registers, explicit stack/heap/global memory, lowering from Haifa bytecode, debug snapshots, and a register-allocation teaching report
Haifa Python tries to make language implementation visible instead of mystical. The code favors readability, small modules, runnable examples, and direct tests. It is useful for:
- compiler and interpreter courses
- programming language self-study
- experiments with bytecode design and runtime behavior
- demonstrations of closures, cells/upvalues, tables, coroutines, varargs, and multi-return semantics
- comparing a high-level virtual-register VM with a lower-level ARMv9-style load/store VM
- jq-style JSON data transformation on top of the same VM infrastructure
- Register-style bytecode VM with named virtual registers
- Function calls, call frames, parameters, returns, tail calls, varargs, and multi-return values
- Closures, mutable cells, captured upvalues, and closure calls
- Lua table operations, array helpers, bitwise operations, and runtime objects
- Source/debug metadata, traceback support, coroutine events, VM snapshots, and visualizer support
HaifaArmV9VM keeps the current high-level BytecodeVM intact and adds a
separate ARMv9-style target for teaching lower-level execution:
- Fixed registers:
X0-X15,SP,FP,LR,PC, andNZCV - Explicit memory sections: constant pool, stack, heap, and globals
- Load/store execution model with
LDR/STR BL/RETcall frames and recursive function support- Heap tables, cells, closures, and multi-return objects
- Lowering from Haifa bytecode via
compiler.armv9_lowering - Optional register-cache optimization and liveness/report output via
compiler.armv9_register_alloc - Unified debug snapshots through
compiler.vm_debug_adapter
The ARMv9 target is intentionally not a full ARM CPU emulator. It is a readable VM target inspired by AArch64/ARMv9 concepts.
- jq-style parser, compiler, VM, runtime, and CLI
- Filters such as field/index access, pipes,
map,select,flatten,reduce,foreach,paths,setpath,del,walk,input, andinputs - Object and array literals
- Runtime fallback error wrapping when system
jqis unavailable
- Lua lexer/parser/compiler pipeline
- Locals, globals, functions, closures, upvalues, varargs, and multi-return
- Tables, field/index access, method calls, numeric/generic loops,
break,repeat,do,goto, and labels - Coroutine runtime with lifecycle events and trace output
- Core standard libraries, module loading, and Lua-style errors/tracebacks
- Reader/parser, tree-walking runtime, and bytecode compiler path
- Lexical scope, lambdas, closures, recursion,
let/let*/letrec, namedlet,begin,set!,cond,case,and,or, anddo - Scheme values such as symbols, pairs, lists, vectors, strings, characters, booleans, and numbers
- REPL and CLI support
- GUI visualizer through
pygame - Terminal/curses visualizer where available
- Windows-safe import fallback for headless visualizer tests when
_cursesis unavailable - Unified VM debug adapter snapshots for
BytecodeVMandHaifaArmV9VM - Static browser demo in
docs/lua-vm-demoshowing the same Lua examples in both BytecodeVM and ARMv9 modes
compiler/: core bytecode VM, ARMv9 VM, lowering, debug adapters, visualizers, instruction definitions, and compatibility wrappershaifa_jq/: jq AST, parser, compiler, VM, runtime, and CLIhaifa_lua/: Lua lexer, parser, compiler, runtime, stdlib, coroutines, modules, and CLIhaifa_scheme/: Scheme reader, runtime, compiler, values, stdlib, and CLIdocs/: user guides, VM references, sprint notes, and browser demosknowledge/: deeper design notes and architecture plansexamples/: runnable Lua and Scheme examplesbenchmark/: benchmark scripts, runner, and stored resultsvm/: earlier VM experiments and reference material
- Python 3.11+
- Optional:
pygamefor the GUI visualizer - Optional: Node.js if you want to run
node --checkon the browser demo JS
Unix/macOS:
python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install --upgrade pip setuptools wheel
python3 -m pip install .Windows PowerShell:
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip setuptools wheel
python -m pip install .To enable the GUI visualizer:
python3 -m pip install ".[gui]"pytestOn Windows during development, prefer avoiding bytecode writes:
$env:PYTHONDONTWRITEBYTECODE='1'
python -m pytest compiler\tests haifa_lua\tests haifa_scheme\tests -qCurrent full suite status after the latest iteration:
541 passed
Run a script:
python3 -m haifa_lua.cli examples/hello.lua --print-outputEvaluate inline code:
python3 -m haifa_lua.cli -e 'x = 1; y = 2; return x + y' --print-outputStart the REPL:
python3 -m haifa_lua.cli --replTrace or visualize execution:
python3 -m haifa_lua.cli examples/coroutines.lua --trace coroutine
python3 -m haifa_lua.cli examples/coroutines.lua --visualize cursesRun a script:
python3 -m haifa_scheme.cli examples/factorial.scm --print-outputRun through the VM backend with tracing:
python3 -m haifa_scheme.cli examples/factorial.scm --backend vm --trace --print-outputEvaluate inline code:
python3 -m haifa_scheme.cli -e '(letrec ((fact (lambda (n) (if (= n 0) 1 (* n (fact (- n 1))))))) (fact 5))' --print-outputStart the REPL:
python3 -m haifa_scheme.cli --replQuery a JSON file:
python3 -m haifa_jq.jq_cli '.items[] | .name' --input compiler/sample.jsonPipe JSON from stdin:
cat compiler/sample.json | python3 -m haifa_jq.jq_cli '.items[] | .price'Use the terminal visualizer:
python3 -m haifa_jq.jq_cli '.items[] | .name' --input compiler/sample.json --visualize cursesAfter installation, the same tools are available as:
pylua --help
pyjq --help
pyscheme --helpThe ARMv9 path is currently a Python API rather than a standalone CLI:
from compiler.armv9_lowering import lower_to_armv9
from compiler.armv9_vm import HaifaArmV9VM
from haifa_lua.runtime import compile_source
bytecode = list(compile_source("local t = {a = 42}; return t.a"))
lowered = lower_to_armv9(bytecode)
vm = HaifaArmV9VM(lowered.instructions, const_pool=lowered.const_pool)
vm.run()
print(vm.snapshot()["registers"])
print(lowered.allocation_report.readable_text())Use lower_to_armv9(bytecode, optimize_registers=True) to enable the teaching
register-cache optimization and report.
Open:
docs/lua-vm-demo/index.html
The demo can be opened directly in a browser. It shows the same Lua examples in two modes:
- high-level Haifa BytecodeVM instructions and named virtual registers
- ARMv9 lowering with fixed registers, stack slots, heap objects, globals,
constant pool, and
NZCV
Regenerate demo data:
$env:PYTHONDONTWRITEBYTECODE='1'
python docs\lua-vm-demo\export_demo.pyFor a guided tour:
- Run a Lua example from
examples/. - Read
haifa_lua/lexer.py,haifa_lua/parser.py, andhaifa_lua/compiler.py. - Follow execution into
compiler/bytecode.pyandcompiler/bytecode_vm.py. - Compare the jq flow in
haifa_jq/jq_parser.py,haifa_jq/jq_compiler.py, andhaifa_jq/jq_vm.py. - Compare the Scheme interpreter and compiler paths in
haifa_scheme/. - Study
compiler/armv9_lowering.pyandcompiler/armv9_vm.pyto see how the high-level VM is lowered to ARMv9-style execution. - Open the browser demo or visualizer to inspect runtime state changes.
docs/lua_guide.md: practical guide to the Lua runtimedocs/scheme_guide.md: practical guide to the Scheme runtimedocs/guide.md: jq CLI guide and examplesdocs/reference.md: command referencedocs/vm_instruction_set.md: VM instruction set referencedocs/haifa_armv9_vm_plan.md: ARMv9 VM plan and phasesdocs/lua-vm-demo/README.md: browser demo notesdocs/lua_sprint.md: Lua implementation milestonesdocs/haifa_scheme_sprit.md: Scheme implementation milestonesknowledge/03-bytecode-and-vm.md: bytecode/VM backgroundknowledge/06-lua-execution-pipeline.md: Lua execution pipeline
- The GUI visualizer depends on
pygame; use--visualize curseswhere a terminal curses backend is available. - The Lua implementation is intentionally a subset/runtime experiment, not a full Lua compatibility target.
- The Scheme implementation is intentionally a teaching subset, not a full R5RS/R7RS compatibility target.
HaifaArmV9VMis an ARMv9-style educational target, not a complete hardware emulator.- The repository favors readability, inspectability, and testable iteration over aggressive optimization.