A small dynamically typed language with its own bytecode VM. C++20, no runtime deps.
WIP. Build window: Jul–Aug 2026. See docs/build-plan.md.
lexer → pratt parser → bytecode compiler → stack VM → mark-sweep GC
fn fib(n) {
if n < 2 { return n }
return fib(n - 1) + fib(n - 2)
}
fn make_counter() {
let count = 0
return fn() {
count = count + 1
return count
}
}
let c = make_counter()
print(c()) // 1
print(c()) // 2
print(fib(30)) // 832040
- Types: Number (f64), Bool, String, Nil, Function, Closure
- First-class functions, closures with upvalue capture
- if/else, while, return
- Arithmetic, comparison, logical ops
- String interning
- Built-ins: print, clock, type, len
- Tri-color mark-sweep GC with write barriers
| what | target |
|---|---|
| fib(30) | < 50 ms |
| vs tree-walker | ≥ 3× |
| GC p99 pause (1M objects) | < 2 ms |
| diff-fuzz cases | 100K+ passing |
| CI | clean under ASan + UBSan |
cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
cmake --build build
./build/ember run examples/fib.em
./build/ember dis examples/fib.em
./build/ember repl
./build/ember_bench
docs/language.mddocs/isa.mddocs/gc.mddocs/build-plan.md
- Nystrom, Crafting Interpreters (clox, ch. 14–30)
- Pratt, "Top Down Operator Precedence" (1973)
- Wilson, "Uniprocessor Garbage Collection Techniques" (1992)
MIT