Root cause: sf-letrec returns a thunk (for TCO) but the CEK dispatch wrapped it as a value without evaluating. The thunk leaked as the return value of letrec expressions, breaking sx-parse and any function using letrec. Fix: step-sf-letrec unwraps the thunk into a CEK state, so the last letrec body expression is properly evaluated by the CEK machine. Also: - compile-letrec: two-phase (nil-init then assign) for mutual recursion - Skip JIT for inner functions (closure.bindings != globals) in both vm_call and JIT hook - vm-reset-fn for sx-parse removed (no longer needed) - Parser regression test: letrec with mutable pos + recursive sublists Test results: JS 943/17, OCaml 955/0, Python 747/0 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
389 KiB
389 KiB