S01E04 β 03-04-2026.
zo 0.2.0 β Petit Gadget Deviendra Grand.
0.1.1 grew the language. 0.2.0 turns to the compiler underneath it. The type checker, constant folder, and dead-code pass get sharper, the unary and parenthesis bugs are gone, and arrays nest.
N-dimensional arrays
Array types nest now, to any depth. [2][3]int is a grid, [2][2][2]int a cube, with the shape carried in the type. Indexing chains to match, and the compiler infers the element type, so str, bool, and float arrays work, not only int. Under the hood, one resolve_array_type parses every depth, replacing four near-identical sites.
imu grid: [2][3]int = [[1, 2, 3], [4, 5, 6]];
showln(grid[1][2]); -- 6
type checking
A dynamic array now fits a fixed one: []T unifies with [N]T. The checker rejects a length mismatch only when both sides fix a size and the sizes differ.
fun total(xs: []int) -> int { xs.sum() }
imu fixed: [3]int = [10, 20, 30];
total(fixed); -- a [3]int passes where []int is asked
constant folding
The folder cleans up after itself. When an expression collapses, the folder replaces the operand instructions that fed it with a Nop, so 1 + 2 leaves one live instruction, not three. What reaches codegen is what runs.
imu area := 1920 * 1080; -- folded to 2073600 at compile time
dead code elimination
Dead-code elimination drops code a program cannot reach before codegen, so it costs nothing in the binary.
if false {
showln("never runs"); -- removed; never emitted
}
unary operators
Unary ! and - apply to whole results. !f(x) negates the callβs return instead of splitting the call apart, and the tokenizer tells unary - apart from binary subtraction at the token level.
fun is_even(n: int) -> bool { n % 2 == 0 }
imu odd := !is_even(7); -- true: ! applies to the call's result
imu delta := -42; -- unary minus, not subtraction
parenthesized expressions
A * or & just after a ) reads as multiplication or bitwise-and, not a stray dereference, so the parentheses group what they should.
imu scaled := (2 + 3) * 4; -- 20