Fix stepper: mutable-list for append! in split-tag and steps-to-preview

The stepper's split-tag and steps-to-preview used (list) with append!,
but in the WASM kernel (list) creates immutable List values — append!
returns a new list without mutating, so children accumulate nowhere.

Changed all accumulator initializations to (mutable-list):
- split-tag: cch, cat, spreads
- steps-to-preview: bc-loop inner children, initial call
- result and tokens lists in the parsing setup

Also includes WASM rebuild with append! primitive and &rest fixes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-02 13:33:15 +00:00
parent 14388913c9
commit 58a122a73a
39 changed files with 482 additions and 767 deletions

View File

@@ -1,23 +1,17 @@
;; Create raw signal dict with value, subs, deps fields
(define
make-signal
(fn
(value)
(dict "__signal" true "value" value "subscribers" (list) "deps" (list))))
;; Type predicate for signals
(define signal? (fn (x) (and (dict? x) (has-key? x "__signal"))))
;; Read current value from signal
(define signal-value (fn (s) (get s "value")))
;; Write value to signal (no notification)
(define signal-set-value! (fn (s v) (dict-set! s "value" v)))
;; List of subscriber functions
(define signal-subscribers (fn (s) (get s "subscribers")))
;; Add a subscriber function
(define
signal-add-sub!
(fn
@@ -26,7 +20,6 @@
(not (contains? (get s "subscribers") f))
(dict-set! s "subscribers" (append (get s "subscribers") (list f))))))
;; Remove a subscriber function
(define
signal-remove-sub!
(fn
@@ -36,19 +29,15 @@
"subscribers"
(filter (fn (sub) (not (identical? sub f))) (get s "subscribers")))))
;; List of upstream signal dependencies
(define signal-deps (fn (s) (get s "deps")))
;; Set upstream dependencies
(define signal-set-deps! (fn (s deps) (dict-set! s "deps" deps)))
;; Create a reactive signal (user-facing constructor)
(define
signal
:effects ()
(fn ((initial-value :as any)) (make-signal initial-value)))
;; Dereference a signal, returning its current value
(define
deref
:effects ()
@@ -69,7 +58,6 @@
(signal-add-sub! s notify-fn))))
(signal-value s)))))
;; Set signal to new value and notify subscribers
(define
reset!
:effects (mutation)
@@ -84,12 +72,11 @@
(signal-set-value! s value)
(notify-subscribers s))))))
;; Apply function to current value and reset
(define
swap!
:effects (mutation)
(fn
((s :as signal) (f :as lambda) &rest args)
((s :as signal) (f :as callable) &rest args)
(when
(signal? s)
(let
@@ -100,7 +87,6 @@
(signal-set-value! s new-val)
(notify-subscribers s))))))
;; Create a derived signal that auto-updates from dependencies
(define
computed
:effects (mutation)
@@ -114,7 +100,6 @@
(register-in-scope (fn () (dispose-computed s)))
s))))
;; Create a side-effect that runs when dependencies change
(define
effect
:effects (mutation)
@@ -130,13 +115,10 @@
(register-in-scope dispose-fn)
dispose-fn)))))
;; Nesting counter for batched updates
(define *batch-depth* 0)
;; Queued notifications during batch
(define *batch-queue* (list))
;; Batch multiple signal updates, notify once at end
(define
batch
:effects (mutation)
@@ -166,7 +148,6 @@
queue)
(for-each (fn ((sub :as lambda)) (sub)) pending))))))
;; Notify all subscribers of a signal change
(define
notify-subscribers
:effects (mutation)
@@ -177,7 +158,6 @@
(when (not (contains? *batch-queue* s)) (append! *batch-queue* s))
(flush-subscribers s))))
;; Process queued subscriber notifications
(define
flush-subscribers
:effects (mutation)
@@ -185,7 +165,6 @@
((s :as dict))
(for-each (fn (sub) (cek-call sub nil)) (signal-subscribers s))))
;; Tear down a computed signal, remove from deps
(define
dispose-computed
:effects (mutation)
@@ -198,7 +177,6 @@
(signal-deps s))
(signal-set-deps! s (list)))))
;; Evaluate body in an island disposal scope
(define
with-island-scope
:effects (mutation)
@@ -207,7 +185,6 @@
(scope-push! "sx-island-scope" scope-fn)
(let ((result (body-fn))) (scope-pop! "sx-island-scope") result)))
;; Register a disposable in the current island scope
(define
register-in-scope
:effects (mutation)