Add reactive islands spec: signals.sx + defisland across all adapters
New spec file signals.sx defines the signal runtime: signal, computed, effect, deref, reset!, swap!, batch, dispose, and island scope tracking. eval.sx: defisland special form + island? type predicate in eval-call. boundary.sx: signal primitive declarations (Tier 3). render.sx: defisland in definition-form?. adapter-dom.sx: render-dom-island with reactive context, reactive-text, reactive-attr, reactive-fragment, reactive-list helpers. adapter-html.sx: render-html-island for SSR with data-sx-island/state. adapter-sx.sx: island? handling in wire format serialization. special-forms.sx: defisland declaration with docs and example. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -35,12 +35,14 @@
|
||||
;; lambda — closure: {params, body, closure-env, name?}
|
||||
;; macro — AST transformer: {params, rest-param, body, closure-env}
|
||||
;; component — UI component: {name, params, has-children, body, closure-env}
|
||||
;; island — reactive component: like component but with island flag
|
||||
;; thunk — deferred eval for TCO: {expr, env}
|
||||
;;
|
||||
;; Each target must provide:
|
||||
;; (type-of x) → one of the strings above
|
||||
;; (make-lambda ...) → platform Lambda value
|
||||
;; (make-component ..) → platform Component value
|
||||
;; (make-island ...) → platform Island value (component + island flag)
|
||||
;; (make-macro ...) → platform Macro value
|
||||
;; (make-thunk ...) → platform Thunk value
|
||||
;;
|
||||
@@ -141,6 +143,7 @@
|
||||
(= name "fn") (sf-lambda args env)
|
||||
(= name "define") (sf-define args env)
|
||||
(= name "defcomp") (sf-defcomp args env)
|
||||
(= name "defisland") (sf-defisland args env)
|
||||
(= name "defmacro") (sf-defmacro args env)
|
||||
(= name "defstyle") (sf-defstyle args env)
|
||||
(= name "defhandler") (sf-defhandler args env)
|
||||
@@ -192,7 +195,7 @@
|
||||
(evaluated-args (map (fn (a) (trampoline (eval-expr a env))) args)))
|
||||
(cond
|
||||
;; Native callable (primitive function)
|
||||
(and (callable? f) (not (lambda? f)) (not (component? f)))
|
||||
(and (callable? f) (not (lambda? f)) (not (component? f)) (not (island? f)))
|
||||
(apply f evaluated-args)
|
||||
|
||||
;; Lambda
|
||||
@@ -203,6 +206,10 @@
|
||||
(component? f)
|
||||
(call-component f args env)
|
||||
|
||||
;; Island (reactive component) — same calling convention
|
||||
(island? f)
|
||||
(call-component f args env)
|
||||
|
||||
:else (error (str "Not callable: " (inspect f)))))))
|
||||
|
||||
|
||||
@@ -543,6 +550,24 @@
|
||||
(list params has-children))))
|
||||
|
||||
|
||||
(define sf-defisland
|
||||
(fn (args env)
|
||||
;; (defisland ~name (params) body)
|
||||
;; Like defcomp but creates an island (reactive component).
|
||||
;; Islands have the same calling convention as components but
|
||||
;; render with a reactive context on the client.
|
||||
(let ((name-sym (first args))
|
||||
(params-raw (nth args 1))
|
||||
(body (last args))
|
||||
(comp-name (strip-prefix (symbol-name name-sym) "~"))
|
||||
(parsed (parse-comp-params params-raw))
|
||||
(params (first parsed))
|
||||
(has-children (nth parsed 1)))
|
||||
(let ((island (make-island comp-name params has-children body env)))
|
||||
(env-set! env (symbol-name name-sym) island)
|
||||
island))))
|
||||
|
||||
|
||||
(define sf-defmacro
|
||||
(fn (args env)
|
||||
(let ((name-sym (first args))
|
||||
@@ -903,6 +928,11 @@
|
||||
;; (component-closure c) → env
|
||||
;; (component-has-children? c) → boolean
|
||||
;; (component-affinity c) → "auto" | "client" | "server"
|
||||
;;
|
||||
;; (make-island name params has-children body env) → Island
|
||||
;; (island? x) → boolean
|
||||
;; ;; Islands reuse component accessors: component-params, component-body, etc.
|
||||
;;
|
||||
;; (macro-params m) → list of strings
|
||||
;; (macro-rest-param m) → string or nil
|
||||
;; (macro-body m) → expr
|
||||
@@ -915,6 +945,7 @@
|
||||
;; (callable? x) → boolean (native function or lambda)
|
||||
;; (lambda? x) → boolean
|
||||
;; (component? x) → boolean
|
||||
;; (island? x) → boolean
|
||||
;; (macro? x) → boolean
|
||||
;; (primitive? name) → boolean (is name a registered primitive?)
|
||||
;; (get-primitive name) → function
|
||||
|
||||
Reference in New Issue
Block a user