Add provide/context/emit!/emitted — render-time dynamic scope
Four new primitives for scoped downward value passing and upward accumulation through the render tree. Specced in .sx, bootstrapped to Python and JS across all adapters (eval, html, sx, dom, async). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -56,7 +56,7 @@
|
||||
(list "if" "when" "cond" "case" "let" "let*" "begin" "do"
|
||||
"define" "defcomp" "defisland" "defmacro" "defstyle" "defhandler"
|
||||
"deftype" "defeffect"
|
||||
"map" "map-indexed" "filter" "for-each"))
|
||||
"map" "map-indexed" "filter" "for-each" "provide"))
|
||||
|
||||
(define render-html-form? :effects []
|
||||
(fn ((name :as string))
|
||||
@@ -237,6 +237,21 @@
|
||||
(render-to-html (apply f (list item)) env)))
|
||||
coll))))
|
||||
|
||||
;; provide — render-time dynamic scope
|
||||
(= name "provide")
|
||||
(let ((prov-name (trampoline (eval-expr (nth expr 1) env)))
|
||||
(prov-val (trampoline (eval-expr (nth expr 2) env)))
|
||||
(body-start 3)
|
||||
(body-count (- (len expr) 3)))
|
||||
(provide-push! prov-name prov-val)
|
||||
(let ((result (if (= body-count 1)
|
||||
(render-to-html (nth expr body-start) env)
|
||||
(join "" (filter (fn (r) (not (spread? r)))
|
||||
(map (fn (i) (render-to-html (nth expr i) env))
|
||||
(range body-start (+ body-start body-count))))))))
|
||||
(provide-pop! prov-name)
|
||||
result))
|
||||
|
||||
;; Fallback
|
||||
:else
|
||||
(render-value-to-html (trampoline (eval-expr expr env)) env))))
|
||||
|
||||
Reference in New Issue
Block a user