Compiler: dict destructuring in let, paren-aware library stripping — 31/31 sxbc

compile-let now handles dict destructuring patterns:
(let {:key1 var1 :key2 var2} source body). This unblocked core-signals.sx
(deref uses dict destructuring) which was the sole bytecode skip.

Rewrote stripLibraryWrapper from line-based to paren-aware extraction.
The old regex missed (define-library on its own line (no trailing space),
silently passing the full wrapper to the compiler.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-11 08:52:36 +00:00
parent bca0d8e4e5
commit ef8f8b7c03
17 changed files with 278 additions and 84 deletions

View File

@@ -589,24 +589,64 @@
(list (list (make-symbol loop-name) lambda-expr)))
(call-expr (cons (make-symbol loop-name) inits)))
(compile-letrec em (list letrec-bindings call-expr) scope tail?)))
(let
((bindings (first args))
(body (rest args))
(let-scope (make-scope scope)))
(dict-set! let-scope "next-slot" (get scope "next-slot"))
(for-each
(fn
(binding)
(let
((name (if (= (type-of (first binding)) "symbol") (symbol-name (first binding)) (first binding)))
(value (nth binding 1)))
(compile-expr em value let-scope false)
(if
(dict? (first args))
(let
((pattern (first args))
(source-expr (nth args 1))
(body (slice args 2))
(let-scope (make-scope scope)))
(dict-set! let-scope "next-slot" (get scope "next-slot"))
(compile-expr em source-expr let-scope false)
(let
((temp-slot (scope-define-local let-scope "__dict_src")))
(emit-op em 17)
(emit-byte em temp-slot)
(for-each
(fn
(k)
(let
((var-name (get pattern k))
(key-str
(if
(= (type-of k) "keyword")
(keyword-name k)
(str k))))
(emit-op em 16)
(emit-byte em temp-slot)
(let
((key-idx (pool-add (get em "pool") key-str)))
(emit-op em 2)
(emit-u16 em key-idx))
(let
((get-idx (pool-add (get em "pool") "get")))
(emit-op em 10)
(emit-u16 em get-idx)
(emit-byte em 2))
(let
((slot (scope-define-local let-scope (if (= (type-of var-name) "symbol") (symbol-name var-name) var-name))))
(emit-op em 17)
(emit-byte em slot))))
(keys pattern))
(compile-begin em body let-scope tail?)))
(let
((bindings (first args))
(body (rest args))
(let-scope (make-scope scope)))
(dict-set! let-scope "next-slot" (get scope "next-slot"))
(for-each
(fn
(binding)
(let
((slot (scope-define-local let-scope name)))
(emit-op em 17)
(emit-byte em slot))))
bindings)
(compile-begin em body let-scope tail?)))))
((name (if (= (type-of (first binding)) "symbol") (first binding) (make-symbol (first binding))))
(value (nth binding 1)))
(compile-expr em value let-scope false)
(let
((slot (scope-define-local let-scope (symbol-name name))))
(emit-op em 17)
(emit-byte em slot))))
bindings)
(compile-begin em body let-scope tail?))))))
(define
compile-letrec
(fn