Add :effects annotations to all spec files and update bootstrappers

Bootstrappers (bootstrap_py.py, js.sx) now skip :effects keyword in
define forms, enabling effect annotations throughout the spec without
changing generated output.

Annotated 180+ functions across 14 spec files:
- signals.sx: signal/deref [] pure, reset!/swap!/effect/batch [mutation]
- engine.sx: parse-* [] pure, morph-*/swap-* [mutation io]
- orchestration.sx: all [mutation io] (browser event binding)
- adapter-html.sx: render-* [render]
- adapter-dom.sx: render-* [render], reactive-* [render mutation]
- adapter-sx.sx: aser-* [render]
- adapter-async.sx: async-render-*/async-aser-* [render io]
- parser.sx: all [] pure
- render.sx: predicates [] pure, process-bindings [mutation]
- boot.sx: all [mutation io] (browser init)
- deps.sx: scan-*/transitive-* [] pure, compute-all-* [mutation]
- router.sx: all [] pure (URL matching)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-11 23:22:34 +00:00
parent 0f9b449315
commit 2f42e8826c
16 changed files with 274 additions and 259 deletions

View File

@@ -49,20 +49,20 @@
;; --------------------------------------------------------------------------
;; Returns a list of top-level AST expressions.
(define sx-parse
(define sx-parse :effects []
(fn ((source :as string))
(let ((pos 0)
(len-src (len source)))
;; -- Cursor helpers (closure over pos, source, len-src) --
(define skip-comment
(define skip-comment :effects []
(fn ()
(when (and (< pos len-src) (not (= (nth source pos) "\n")))
(set! pos (inc pos))
(skip-comment))))
(define skip-ws
(define skip-ws :effects []
(fn ()
(when (< pos len-src)
(let ((ch (nth source pos)))
@@ -80,11 +80,11 @@
;; -- Atom readers --
(define read-string
(define read-string :effects []
(fn ()
(set! pos (inc pos)) ;; skip opening "
(let ((buf ""))
(define read-str-loop
(define read-str-loop :effects []
(fn ()
(if (>= pos len-src)
(error "Unterminated string")
@@ -110,10 +110,10 @@
(read-str-loop)
buf)))
(define read-ident
(define read-ident :effects []
(fn ()
(let ((start pos))
(define read-ident-loop
(define read-ident-loop :effects []
(fn ()
(when (and (< pos len-src)
(ident-char? (nth source pos)))
@@ -122,19 +122,19 @@
(read-ident-loop)
(slice source start pos))))
(define read-keyword
(define read-keyword :effects []
(fn ()
(set! pos (inc pos)) ;; skip :
(make-keyword (read-ident))))
(define read-number
(define read-number :effects []
(fn ()
(let ((start pos))
;; Optional leading minus
(when (and (< pos len-src) (= (nth source pos) "-"))
(set! pos (inc pos)))
;; Integer digits
(define read-digits
(define read-digits :effects []
(fn ()
(when (and (< pos len-src)
(let ((c (nth source pos)))
@@ -158,7 +158,7 @@
(read-digits))
(parse-number (slice source start pos)))))
(define read-symbol
(define read-symbol :effects []
(fn ()
(let ((name (read-ident)))
(cond
@@ -169,10 +169,10 @@
;; -- Composite readers --
(define read-list
(define read-list :effects []
(fn ((close-ch :as string))
(let ((items (list)))
(define read-list-loop
(define read-list-loop :effects []
(fn ()
(skip-ws)
(if (>= pos len-src)
@@ -184,10 +184,10 @@
(read-list-loop)
items)))
(define read-map
(define read-map :effects []
(fn ()
(let ((result (dict)))
(define read-map-loop
(define read-map-loop :effects []
(fn ()
(skip-ws)
(if (>= pos len-src)
@@ -206,10 +206,10 @@
;; -- Raw string reader (for #|...|) --
(define read-raw-string
(define read-raw-string :effects []
(fn ()
(let ((buf ""))
(define raw-loop
(define raw-loop :effects []
(fn ()
(if (>= pos len-src)
(error "Unterminated raw string")
@@ -224,7 +224,7 @@
;; -- Main expression reader --
(define read-expr
(define read-expr :effects []
(fn ()
(skip-ws)
(if (>= pos len-src)
@@ -322,7 +322,7 @@
;; -- Entry point: parse all top-level expressions --
(let ((exprs (list)))
(define parse-loop
(define parse-loop :effects []
(fn ()
(skip-ws)
(when (< pos len-src)
@@ -336,7 +336,7 @@
;; Serializer — AST → SX source text
;; --------------------------------------------------------------------------
(define sx-serialize
(define sx-serialize :effects []
(fn (val)
(case (type-of val)
"nil" "nil"
@@ -351,7 +351,7 @@
:else (str val))))
(define sx-serialize-dict
(define sx-serialize-dict :effects []
(fn ((d :as dict))
(str "{"
(join " "