Skip to content

Commit 7a4bc2b

Browse files
Session B: codegen covers locals, branches, loops, recursion
Expand omnimcode-codegen's lower_function to handle the full pure-i64 subset of OMC bytecode. After this session, any OMC fn whose body uses only i64 values, locals, conditionals, while loops, and recursive self-calls JITs to native code with byte-identical results to the tree-walk interpreter. What's new: - FunctionLowerer struct: extracts the per-fn state (block table, var slots, builder, stack) out of free functions - Two-pass lowering: first identify block leaders (jump targets, post-terminator ops), then walk ops emitting per-block IR - Locals via entry-block allocas: StoreVar / AssignVar / LoadVar use load/store on a HashMap-tracked PointerValue per name - Control flow: Jump, JumpIfFalse, JumpIfTrue lower to LLVM conditional/unconditional branches - Comparisons: Eq, Ne, Lt, Le, Gt, Ge produce i64 0/1 (z-extended from i1) so they match the bytecode VM's semantics - Arithmetic: Div, Mod (signed), Neg added to Session A's Add/Sub/Mul - Bitwise: BitAnd, BitOr, BitXor, BitNot, Shl, Shr - Logical: And, Or (non-short-circuit, matches compiler emission), Not - Recursive Call: Op::Call with name == current fn name lowers to a self-call. Cross-fn calls still rejected — that's Session D. JumpIfFalse-cleanup-Pop idiom: the OMC bytecode compiler emits JumpIfFalse (which PEEKS the condition) followed by a Pop in both the fall-through path and at the jump target. Codegen models the branch as consume-and-jump, then marks both cleanup Pops as no-ops via a per-fn HashSet so we don't double-pop or stack-underflow. Same handling for JumpIfTrue. Tests added (8 total, all passing): - jit_max_two_args: tests if/else, JumpIfFalse - jit_abs_single_arg: tests Neg + comparison - jit_sum_to_n_while_loop: tests while loop, locals (s, k via allocas), backward Jump, comparison-driven exit - jit_factorial_recursion: factorial(20) = 2,432,902,008,176,640,000 exercises recursive self-Call, conditional return base case - jit_rejects_cross_fn_call: negative case for Session D scope guard Still NOT yet covered (deferred to subsequent sessions): - Floats, strings, arrays, dicts, builtins (Session D) - Cross-fn calls (Session D) - HBit dual-band representation (Session C — packed i64x2) - AVX-512 intrinsics, harmony monitoring opcode, predictive correction - Closures, match, try/catch Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 35c80c0 commit 7a4bc2b

2 files changed

Lines changed: 766 additions & 155 deletions

File tree

0 commit comments

Comments
 (0)