Expand description
the bytecode codegen: lower a TypedAst to a Program of bytecode
chunks, ready for the Phase 5 stack VM to execute.
one recursive walk over the typed AST; each typed expression and
statement compiles to a sequence of opcodes via the write helpers on
crate::chunk::Chunk. inline constant folding runs as bytecode is
emitted – a literal arithmetic / comparison / logic expression collapses
to a single CONST before reaching the optimizer; an i64 fold that would
overflow errors with crate::errors::QalaError::IntegerOverflow rather
than silently wrapping. dead code after return / break / continue
is not emitted; a constant-condition if emits only the taken branch.
defer compilation: each [LocalsScope] carries a deferred-expression
list. defer statements append, never emit; every scope exit (fall-through,
return, break, continue, ?-propagation) walks the deferred list in
reverse and emits each expression’s bytecode. defers inside a loop body
live in the loop-body scope, which is pushed fresh per iteration; LIFO
per-iteration semantics fall out of this.
comptime evaluation: a [ComptimeInterpreter] (file-private) walks the
same opcode set as the runtime VM but enforces a 100K-instruction budget
and refuses to dispatch a CALL whose callee is not pure – defense in
depth against a typechecker miss. results that cannot be represented in
the constant pool (arrays, structs, enum variants) error at the comptime
block.
errors accumulate rather than fail-fast: a fold overflow in one function
does not stop the others from compiling. on any errors, the public entry
returns Err(Vec
file order (per compiler/CLAUDE.md): value -> opcode -> chunk -> codegen.
every byte this module writes goes through Chunk::write_op /
Chunk::write_u16 / Chunk::write_i16 so the lockstep invariant
chunk.code.len() == chunk.source_lines.len() survives codegen.
Functions§
- compile_
program - the codegen module’s public entry: lower a typed program to bytecode.