HS runtime + generator: make, Values, toggle styles, scoped storage, array ops, fetch coercion, scripts in PW bodies
Runtime (lib/hyperscript/ + shared/static/wasm/sx/hs-*.sx):
- make: parser accepts `<tag.class#id/>` selectors and `from <expr>,…`; compiler
emits via scoped-set so `called <name>` persists; `called $X` lands on
window; runtime dispatches element vs host-new constructor by type.
- Values: `x as Values` walks form inputs/selects/textareas, producing
{name: value | [value,…]}; duplicates promote to array; multi-select and
checkbox/radio handled.
- toggle *display/*visibility/*opacity: paired with sensible inline defaults
in the mock DOM so toggle flips block/visible/1 ↔ none/hidden/0.
- add/remove/put at array: emit-set paths route list mutations back through
the scoped binding; add hs-put-at! / hs-splice-at! / hs-dict-without.
- remove OBJ.KEY / KEY of OBJ: rebuild dict via hs-dict-without and reassign,
since SX dicts are copy-on-read across the bridge.
- dom-set-data: use (host-new "Object") rather than (dict) so element-local
storage actually persists between reads.
- fetch: hs-fetch normalizes JSON/Object/Text/Response format aliases;
compiler sets `the-result` when wrapping a fetch in the `let ((it …))`
chain, and __get-cmd shares one evaluation via __hs-g.
Mock DOM (tests/hs-run-filtered.js):
- parseHTMLFragments accepts void elements (<input>, <br>, …);
- setAttribute tracks name/type/checked/selected/multiple;
- select.options populated on appendChild;
- insertAdjacentHTML parses fragments and inserts real El children into the
parent so HS-activated handlers attach.
Generator (tests/playwright/generate-sx-tests.py):
- process_hs_val strips `//` / `--` line comments before newline→then
collapse, and strips spurious `then` before else/end/catch/finally.
- parse_dev_body interleaves window-setup ops and DOM resets between
actions/assertions; pre-html setups still emit up front.
- generate_test_pw compiles any `<script type=text/hyperscript>` (flattened
across JS string-concat) under guard, exposing def blocks.
- Ordered ops for `run()`-style tests check window.obj.prop via new
_js_window_expr_to_sx; add DOM-constructing evaluate + _hyperscript
pattern for `as Values` tests (result.key[i].toBe(…)).
- js_val_to_sx handles backticks and escapes embedded quotes.
Net delta across suites:
- if 16→18, make 0→8, toggle 12→21, add 9→10, remove 11→16, put 29→31,
fetch 11→15, repeat 14→26, expressions/asExpression 20→25, set 27→28,
core/scoping 12→14, when 39→39 (no regression).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -353,16 +353,41 @@
|
||||
emit-make
|
||||
(fn
|
||||
(ast)
|
||||
(if
|
||||
(= (len ast) 3)
|
||||
(list
|
||||
(quote let)
|
||||
(list
|
||||
(list
|
||||
(make-symbol (nth ast 2))
|
||||
(list (quote hs-make) (nth ast 1))))
|
||||
(make-symbol (nth ast 2)))
|
||||
(list (quote hs-make) (nth ast 1)))))
|
||||
(let
|
||||
((type-name (nth ast 1))
|
||||
(called (if (>= (len ast) 3) (nth ast 2) nil))
|
||||
(args (if (>= (len ast) 4) (nth ast 3) nil))
|
||||
(kind (if (>= (len ast) 5) (nth ast 4) (quote auto))))
|
||||
(let
|
||||
((make-call (cond ((nil? args) (list (quote hs-make) type-name)) (true (cons (quote hs-make) (cons type-name (map hs-to-sx args)))))))
|
||||
(cond
|
||||
((and called (> (len called) 1) (= (substring called 0 1) "$"))
|
||||
(list
|
||||
(quote let)
|
||||
(list (list (quote __hs-mk) make-call))
|
||||
(list
|
||||
(quote do)
|
||||
(list
|
||||
(quote host-set!)
|
||||
(list (quote host-global) "window")
|
||||
called
|
||||
(quote __hs-mk))
|
||||
(list (quote set!) (quote it) (quote __hs-mk))
|
||||
(quote __hs-mk))))
|
||||
(called
|
||||
(list
|
||||
(quote do)
|
||||
(list (quote set!) (make-symbol called) make-call)
|
||||
(list (quote set!) (quote it) (make-symbol called))
|
||||
(make-symbol called)))
|
||||
(true
|
||||
(list
|
||||
(quote let)
|
||||
(list (list (quote __hs-mk) make-call))
|
||||
(list
|
||||
(quote do)
|
||||
(list (quote set!) (quote it) (quote __hs-mk))
|
||||
(quote __hs-mk)))))))))
|
||||
(define
|
||||
emit-inc
|
||||
(fn
|
||||
@@ -1182,13 +1207,38 @@
|
||||
(if (nil? raw-tgt) (quote me) (hs-to-sx raw-tgt))
|
||||
(nth ast 1)))))
|
||||
((= head (quote remove-element))
|
||||
(list (quote dom-remove) (hs-to-sx (nth ast 1))))
|
||||
(let
|
||||
((tgt (nth ast 1)))
|
||||
(cond
|
||||
((and (list? tgt) (= (first tgt) (quote array-index)))
|
||||
(let
|
||||
((coll (nth tgt 1)) (idx (hs-to-sx (nth tgt 2))))
|
||||
(emit-set
|
||||
coll
|
||||
(list (quote hs-splice-at!) (hs-to-sx coll) idx))))
|
||||
((and (list? tgt) (= (first tgt) dot-sym))
|
||||
(let
|
||||
((obj (nth tgt 1)) (prop (nth tgt 2)))
|
||||
(emit-set
|
||||
obj
|
||||
(list (quote hs-dict-without) (hs-to-sx obj) prop))))
|
||||
((and (list? tgt) (= (first tgt) (quote of)))
|
||||
(let
|
||||
((prop-ast (nth tgt 1)) (obj-ast (nth tgt 2)))
|
||||
(let
|
||||
((prop (cond ((string? prop-ast) prop-ast) ((and (list? prop-ast) (= (first prop-ast) (quote ref))) (nth prop-ast 1)) (true (hs-to-sx prop-ast)))))
|
||||
(emit-set
|
||||
obj-ast
|
||||
(list
|
||||
(quote hs-dict-without)
|
||||
(hs-to-sx obj-ast)
|
||||
prop)))))
|
||||
(true (list (quote dom-remove) (hs-to-sx tgt))))))
|
||||
((= head (quote add-value))
|
||||
(let
|
||||
((val (hs-to-sx (nth ast 1))) (tgt (nth ast 2)))
|
||||
(list
|
||||
(quote set!)
|
||||
(hs-to-sx tgt)
|
||||
(emit-set
|
||||
tgt
|
||||
(list (quote hs-add-to!) val (hs-to-sx tgt)))))
|
||||
((= head (quote add-attr))
|
||||
(let
|
||||
@@ -1201,9 +1251,8 @@
|
||||
((= head (quote remove-value))
|
||||
(let
|
||||
((val (hs-to-sx (nth ast 1))) (tgt (nth ast 2)))
|
||||
(list
|
||||
(quote set!)
|
||||
(hs-to-sx tgt)
|
||||
(emit-set
|
||||
tgt
|
||||
(list (quote hs-remove-from!) val (hs-to-sx tgt)))))
|
||||
((= head (quote empty-target))
|
||||
(let
|
||||
@@ -1348,11 +1397,16 @@
|
||||
((= head (quote set!))
|
||||
(emit-set (nth ast 1) (hs-to-sx (nth ast 2))))
|
||||
((= head (quote put!))
|
||||
(list
|
||||
(quote hs-put!)
|
||||
(hs-to-sx (nth ast 1))
|
||||
(nth ast 2)
|
||||
(hs-to-sx (nth ast 3))))
|
||||
(let
|
||||
((val (hs-to-sx (nth ast 1)))
|
||||
(pos (nth ast 2))
|
||||
(raw-tgt (nth ast 3)))
|
||||
(cond
|
||||
((and (or (= pos "end") (= pos "start")) (list? raw-tgt) (or (= (first raw-tgt) (quote local)) (= (first raw-tgt) (quote ref))))
|
||||
(emit-set
|
||||
raw-tgt
|
||||
(list (quote hs-put-at!) val pos (hs-to-sx raw-tgt))))
|
||||
(true (list (quote hs-put!) val pos (hs-to-sx raw-tgt))))))
|
||||
((= head (quote if))
|
||||
(if
|
||||
(> (len ast) 3)
|
||||
@@ -1387,10 +1441,24 @@
|
||||
(reduce
|
||||
(fn
|
||||
(body cmd)
|
||||
(list
|
||||
(quote let)
|
||||
(list (list (quote it) cmd))
|
||||
body))
|
||||
(if
|
||||
(and
|
||||
(list? cmd)
|
||||
(= (first cmd) (quote hs-fetch)))
|
||||
(list
|
||||
(quote let)
|
||||
(list (list (quote it) cmd))
|
||||
(list
|
||||
(quote begin)
|
||||
(list
|
||||
(quote set!)
|
||||
(quote the-result)
|
||||
(quote it))
|
||||
body))
|
||||
(list
|
||||
(quote let)
|
||||
(list (list (quote it) cmd))
|
||||
body)))
|
||||
(nth compiled (- (len compiled) 1))
|
||||
(rest (reverse compiled)))
|
||||
(cons (quote do) compiled))))
|
||||
@@ -1512,10 +1580,13 @@
|
||||
(let
|
||||
((val (hs-to-sx (nth ast 1))))
|
||||
(list
|
||||
(quote begin)
|
||||
(list (quote set!) (quote the-result) val)
|
||||
(list (quote set!) (quote it) val)
|
||||
val)))
|
||||
(quote let)
|
||||
(list (list (quote __hs-g) val))
|
||||
(list
|
||||
(quote begin)
|
||||
(list (quote set!) (quote the-result) (quote __hs-g))
|
||||
(list (quote set!) (quote it) (quote __hs-g))
|
||||
(quote __hs-g)))))
|
||||
((= head (quote append!))
|
||||
(let
|
||||
((tgt (hs-to-sx (nth ast 2)))
|
||||
|
||||
Reference in New Issue
Block a user