Bytecode compiler: desugar let-match, fix SPA navigation
The bytecode compiler now handles let-match (both variants):
- Variant 1: (let-match name expr {:k v} body...) — named binding + destructure
- Variant 2: (let-match {:k v} expr body...) — pattern-only destructure
Desugars to sequential let + get calls — no new opcodes needed.
This was the last blocker for SPA navigation. The bytecoded orchestration
and router modules used let-match which compiled to CALL_PRIM "let-match"
(undefined at runtime). Now desugared at compile time.
Also synced dist/sx/ sources with web/ and recompiled all 26 .sxbc modules.
2650/2650 tests pass.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -41,6 +41,7 @@
|
||||
compile-or
|
||||
compile-begin
|
||||
compile-let
|
||||
desugar-let-match
|
||||
compile-letrec
|
||||
compile-lambda
|
||||
compile-define
|
||||
@@ -250,6 +251,8 @@
|
||||
(compile-let em args scope tail?)
|
||||
(= name "let*")
|
||||
(compile-let em args scope tail?)
|
||||
(= name "let-match")
|
||||
(compile-let em (desugar-let-match args) scope tail?)
|
||||
(= name "begin")
|
||||
(compile-begin em args scope tail?)
|
||||
(= name "do")
|
||||
@@ -446,6 +449,47 @@
|
||||
(compile-expr em (first exprs) scope false)
|
||||
(emit-op em 5)
|
||||
(compile-begin em (rest exprs) scope tail?))))))
|
||||
(define
|
||||
desugar-let-match
|
||||
(fn
|
||||
(args)
|
||||
(let
|
||||
((first-arg (first args)))
|
||||
(if (dict? first-arg)
|
||||
;; Variant 2: (let-match {:k v} expr body...)
|
||||
(let
|
||||
((pattern first-arg)
|
||||
(expr (nth args 1))
|
||||
(body (slice args 2))
|
||||
(src-sym (make-symbol "__lm_tmp"))
|
||||
(bindings (list)))
|
||||
(append! bindings (list src-sym expr))
|
||||
(for-each
|
||||
(fn (k)
|
||||
(append! bindings
|
||||
(list (get pattern k)
|
||||
(list (make-symbol "get") src-sym (str k)))))
|
||||
(keys pattern))
|
||||
(cons bindings body))
|
||||
;; Variant 1: (let-match name expr {:k v} body...)
|
||||
(let
|
||||
((name-sym first-arg)
|
||||
(expr (nth args 1))
|
||||
(pattern (nth args 2))
|
||||
(body (slice args 3))
|
||||
(src-sym (if (= (str name-sym) "_")
|
||||
(make-symbol "__lm_tmp")
|
||||
name-sym))
|
||||
(bindings (list)))
|
||||
(append! bindings (list src-sym expr))
|
||||
(when (dict? pattern)
|
||||
(for-each
|
||||
(fn (k)
|
||||
(append! bindings
|
||||
(list (get pattern k)
|
||||
(list (make-symbol "get") src-sym (str k)))))
|
||||
(keys pattern)))
|
||||
(cons bindings body))))))
|
||||
(define
|
||||
compile-let
|
||||
(fn
|
||||
|
||||
Reference in New Issue
Block a user