From 6a4b2d9a33da4ed4ce440d49e6fd74d1bd4f741f Mon Sep 17 00:00:00 2001 From: giles Date: Sun, 29 Mar 2026 19:25:39 +0000 Subject: [PATCH] Fix compile-match: inline clauses via letrec for JIT visibility compile-match-clauses was a separate define that the JIT VM couldn't find at runtime ("VM undefined: compile-match-clauses"). Inline it as a letrec-bound local function inside compile-match so it's captured in the closure and visible to JIT-compiled code. 1166 passed, 0 failed. Co-Authored-By: Claude Opus 4.6 (1M context) --- lib/compiler.sx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/compiler.sx b/lib/compiler.sx index 85f36e43..bfab1905 100644 --- a/lib/compiler.sx +++ b/lib/compiler.sx @@ -561,7 +561,9 @@ (fn (em args scope tail?) (compile-expr em (first args) scope false) - (compile-match-clauses em (rest args) scope tail?))) + (letrec + ((do-clauses (fn (clauses) (if (empty? clauses) (do (emit-op em 5) (let ((idx (pool-add (get em "pool") "match: no clause matched"))) (emit-op em 1) (emit-u16 em idx) (emit-op em 52) (emit-u16 em (pool-add (get em "pool") "error")) (emit-byte em 1))) (let ((clause (first clauses)) (pattern (first clause)) (body (nth clause 1)) (rest-clauses (rest clauses))) (cond (and (= (type-of pattern) "symbol") (= (symbol-name pattern) "_")) (do (emit-op em 5) (compile-expr em body scope tail?)) (and (= (type-of pattern) "symbol") (not (= (symbol-name pattern) "true")) (not (= (symbol-name pattern) "false")) (not (= (symbol-name pattern) "nil"))) (let ((var-name (symbol-name pattern)) (inner-scope (scope-add scope var-name))) (emit-op em 13) (emit-byte em (scope-index inner-scope var-name)) (compile-expr em body inner-scope tail?)) (and (list? pattern) (= (len pattern) 2) (= (type-of (first pattern)) "symbol") (= (symbol-name (first pattern)) "quote") (= (type-of (nth pattern 1)) "symbol")) (do (emit-op em 6) (let ((idx (pool-add (get em "pool") (make-symbol (symbol-name (nth pattern 1)))))) (emit-op em 1) (emit-u16 em idx)) (let ((eq-idx (pool-add (get em "pool") "="))) (emit-op em 52) (emit-u16 em eq-idx) (emit-byte em 2)) (emit-op em 33) (let ((skip (current-offset em))) (emit-i16 em 0) (emit-op em 5) (compile-expr em body scope tail?) (emit-op em 32) (let ((end-jump (current-offset em))) (emit-i16 em 0) (patch-i16 em skip (- (current-offset em) (+ skip 2))) (do-clauses rest-clauses) (patch-i16 em end-jump (- (current-offset em) (+ end-jump 2)))))) :else (do (emit-op em 6) (compile-expr em pattern scope false) (let ((eq-idx (pool-add (get em "pool") "="))) (emit-op em 52) (emit-u16 em eq-idx) (emit-byte em 2)) (emit-op em 33) (let ((skip (current-offset em))) (emit-i16 em 0) (emit-op em 5) (compile-expr em body scope tail?) (emit-op em 32) (let ((end-jump (current-offset em))) (emit-i16 em 0) (patch-i16 em skip (- (current-offset em) (+ skip 2))) (do-clauses rest-clauses) (patch-i16 em end-jump (- (current-offset em) (+ end-jump 2)))))))))))) + (do-clauses (rest args))))) (define compile-case-clauses