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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user