Implement deref-as-shift: ReactiveResetFrame, DerefFrame, continuation capture
frames.sx: ReactiveResetFrame + DerefFrame constructors, kont-capture-to-reactive-reset, has-reactive-reset-frame?. cek.sx: deref as CEK special form, step-sf-deref pushes DerefFrame, reactive-shift-deref captures continuation as signal subscriber, ReactiveResetFrame in step-continue calls update-fn on re-render. adapter-dom.sx: cek-reactive-text/cek-reactive-attr using cek-run with ReactiveResetFrame for implicit DOM bindings. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -166,6 +166,18 @@
|
||||
{:type "dynamic-wind" :phase phase
|
||||
:body-thunk body-thunk :after-thunk after-thunk :env env}))
|
||||
|
||||
;; ReactiveResetFrame: delimiter for reactive deref-as-shift
|
||||
;; Carries an update-fn that gets called with new values on re-render.
|
||||
(define make-reactive-reset-frame
|
||||
(fn (env update-fn first-render?)
|
||||
{:type "reactive-reset" :env env :update-fn update-fn
|
||||
:first-render first-render?}))
|
||||
|
||||
;; DerefFrame: awaiting evaluation of deref's argument
|
||||
(define make-deref-frame
|
||||
(fn (env)
|
||||
{:type "deref" :env env}))
|
||||
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; 3. Frame accessors
|
||||
@@ -202,12 +214,35 @@
|
||||
;; Returns (captured-frames remaining-kont).
|
||||
;; captured-frames: frames from top up to (not including) ResetFrame.
|
||||
;; remaining-kont: frames after ResetFrame.
|
||||
;; Stops at either "reset" or "reactive-reset" frames.
|
||||
(define scan
|
||||
(fn (k captured)
|
||||
(if (empty? k)
|
||||
(error "shift without enclosing reset")
|
||||
(let ((frame (first k)))
|
||||
(if (= (frame-type frame) "reset")
|
||||
(if (or (= (frame-type frame) "reset")
|
||||
(= (frame-type frame) "reactive-reset"))
|
||||
(list captured (rest k))
|
||||
(scan (rest k) (append captured (list frame))))))))
|
||||
(scan kont (list))))
|
||||
|
||||
;; Check if a ReactiveResetFrame exists anywhere in the continuation
|
||||
(define has-reactive-reset-frame?
|
||||
(fn (kont)
|
||||
(if (empty? kont) false
|
||||
(if (= (frame-type (first kont)) "reactive-reset") true
|
||||
(has-reactive-reset-frame? (rest kont))))))
|
||||
|
||||
;; Capture frames up to nearest ReactiveResetFrame.
|
||||
;; Returns (captured-frames, reset-frame, remaining-kont).
|
||||
(define kont-capture-to-reactive-reset
|
||||
(fn (kont)
|
||||
(define scan
|
||||
(fn (k captured)
|
||||
(if (empty? k)
|
||||
(error "reactive deref without enclosing reactive-reset")
|
||||
(let ((frame (first k)))
|
||||
(if (= (frame-type frame) "reactive-reset")
|
||||
(list captured frame (rest k))
|
||||
(scan (rest k) (append captured (list frame))))))))
|
||||
(scan kont (list))))
|
||||
|
||||
Reference in New Issue
Block a user