Minimal programming language parser and execution experiment
bun run test
bun run exec examples/assignment
bun run exec -- --trace examples/loop
bun run exec -- --step examples/if-elsePrograms live in examples/. Use Enter or n for next, p for previous, and q to quit in step mode.
- numbers:
1,42 - strings:
"hello",'path/to/file' - variables:
a,count_1 - assignment:
a = 1 + 2 - arithmetic:
+,-,*,/(numeric only) - comparison:
<(returns1or0) - parentheses:
(1 + 2) * 3 - blocks:
{ ... } if (expr) { ... } else { ... }while (expr) { ... }fn name(a, b) { ... }return expr;- function calls:
add(1, 2) - statements end with
; - last expression value is the program result
Not supported yet: string +, ==, arrays, comments, forward references.
| Call | Args | Result |
|---|---|---|
print(...) |
zero or more expressions | prints to stdout, leaves last arg in ax |
assert(expr) |
one expression | throws if falsy |
clock() |
none | Date.now() |
Functions must be declared before use. Calls check arity (add(1) is an error).
Assignment and arithmetic
a = 1;
b = 2 + a;
b;→ 3
Loop
i = 0;
sum = 0;
while (i < 2) {
sum = sum + i;
i = i + 1;
}
sum;→ 1
If / else and multi-arg print
value = 0;
if (value) {
result = 1;
} else {
result = 2;
}
print('result =', result);
result;→ prints: result = 2
→ returns: 2
Functions
fn add(a, b) {
return a + b;
}
add(1, 2);→ 3
Failed assertion
assert(1);
assert(1 + 2 < 4);
assert(2 + 2 < 4);→ RUNTIME ERR: assert failed
at line 3
import { execute } from './src/index.ts'
execute('a = 1; b = a + 2; b;') // 3execute(code) compiles and runs source, then returns the final value in ax.
For directive-level debugging:
import { inspect } from './src/index.ts'
const { directives, trace, result } = inspect('a = 1; a;')The four phase entry points are src/tokenize.ts, src/parse.ts, src/run.ts, and src/trace.ts. Each call owns its state. Tests are in test/.
See docs/design.md for the current gaps between this project and the c4-inspired language target.