Hyperscript: remove/tell/transition commands, test generator ref() fix

Parser: remove me/[@attr]/{css}, tell body scoping (skip then),
transition from/to syntax + my/style prefixes.
Compiler: remove-element, remove-attr, remove-css, transition-from.
Runtime: hs-transition-from for from/to CSS transitions.
Generator changes (already committed) fix ref() unnamed-first mapping,
assertion dedup for pre/post pairs, on-event then insertion.

Conformance: 374→395 (+21 tests, 48%)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-12 18:03:56 +00:00
parent 7ec42386fb
commit e71e74941e
3 changed files with 70 additions and 36 deletions

View File

@@ -240,18 +240,22 @@
((prop (nth ast 1)) (value (hs-to-sx (nth ast 2))))
(if
(= (len ast) 5)
(let
((raw-tgt (nth ast 4)))
(list
(quote hs-transition)
(hs-to-sx (nth ast 4))
(if (nil? raw-tgt) (quote me) (hs-to-sx raw-tgt))
prop
value
(nth ast 3))
(nth ast 3)))
(let
((raw-tgt (nth ast 3)))
(list
(quote hs-transition)
(hs-to-sx (nth ast 3))
(if (nil? raw-tgt) (quote me) (hs-to-sx raw-tgt))
prop
value
nil)))))
nil))))))
(define
emit-make
(fn
@@ -913,6 +917,19 @@
(list (quote dom-set-style) tgt "visibility" "visible"))
(true (list (quote dom-set-style) tgt "display" "")))))
((= head (quote transition)) (emit-transition ast))
((= head (quote transition-from))
(let
((prop (nth ast 1))
(from-val (hs-to-sx (nth ast 2)))
(to-val (hs-to-sx (nth ast 3)))
(dur (nth ast 4)))
(list
(quote hs-transition-from)
(quote me)
prop
from-val
to-val
dur)))
((= head (quote repeat)) (emit-repeat ast))
((= head (quote fetch))
(list (quote hs-fetch) (hs-to-sx (nth ast 1)) (nth ast 2)))

View File

@@ -1011,18 +1011,21 @@
(fn
()
(let
((prop (get (adv!) "value")))
((prop (cond ((= (tp-type) "style") (get (adv!) "value")) ((= (tp-val) "my") (do (adv!) (if (= (tp-type) "style") (get (adv!) "value") (get (adv!) "value")))) (true (get (adv!) "value")))))
(let
((from-val (if (match-kw "from") (parse-expr) nil)))
(expect-kw! "to")
(let
((value (parse-expr)))
(let
((dur (if (match-kw "over") (if (= (tp-type) "number") (parse-dur (get (adv!) "value")) 400) nil)))
(let
((tgt (parse-tgt-kw "on" (list (quote me)))))
((dur (if (match-kw "over") (parse-expr) nil)))
(if
from-val
(list (quote transition-from) prop from-val value dur)
(if
dur
(list (quote transition) prop value dur tgt)
(list (quote transition) prop value tgt))))))))
(list (quote transition) prop value dur nil)
(list (quote transition) prop value nil)))))))))
(define
parse-repeat-cmd
(fn

View File

@@ -344,6 +344,20 @@
(dom-set-style target prop value)
(when duration (hs-settle target))))
(define
hs-transition-from
(fn
(target prop from-val to-val duration)
(dom-set-style target prop (str from-val))
(when
duration
(dom-set-style
target
"transition"
(str prop " " (/ duration 1000) "s")))
(dom-set-style target prop (str to-val))
(when duration (hs-settle target))))
(define
hs-type-check
(fn
@@ -359,20 +373,21 @@
((= type-name "Object") (dict? value))
(true true)))))
(define
hs-type-check-strict
(fn
(value type-name)
(if (nil? value) false (hs-type-check value type-name))))
(define
hs-strict-eq
(fn (a b) (and (= (type-of a) (type-of b)) (= a b))))
;; ── Sandbox/test runtime additions ──────────────────────────────
;; Property access — dot notation and .length
(define
hs-falsy?
(fn
@@ -384,8 +399,7 @@
((and (list? v) (= (len v) 0)) true)
((= v 0) true)
(true false))))
;; ── Sandbox/test runtime additions ──────────────────────────────
;; Property access — dot notation and .length
;; DOM query stub — sandbox returns empty list
(define
hs-matches?
(fn
@@ -394,7 +408,7 @@
(string? target)
(if (= pattern ".*") true (string-contains? target pattern))
false)))
;; DOM query stub — sandbox returns empty list
;; Method dispatch — obj.method(args)
(define
hs-contains?
(fn
@@ -414,11 +428,11 @@
true
(hs-contains? (rest collection) item)))))
(true false))))
;; Method dispatch — obj.method(args)
(define precedes? (fn (a b) (< (str a) (str b))))
;; ── 0.9.90 features ─────────────────────────────────────────────
;; beep! — debug logging, returns value unchanged
(define precedes? (fn (a b) (< (str a) (str b))))
;; Property-based is — check obj.key truthiness
(define
hs-empty?
(fn
@@ -429,11 +443,11 @@
((list? v) (= (len v) 0))
((dict? v) (= (len (keys v)) 0))
(true false))))
;; Property-based is — check obj.key truthiness
(define hs-first (fn (lst) (first lst)))
;; Array slicing (inclusive both ends)
(define hs-last (fn (lst) (last lst)))
(define hs-first (fn (lst) (first lst)))
;; Collection: sorted by
(define hs-last (fn (lst) (last lst)))
;; Collection: sorted by descending
(define
hs-template
(fn
@@ -519,7 +533,7 @@
(set! i (+ i 1))
(tpl-loop)))))))
(do (tpl-loop) result))))
;; Collection: sorted by descending
;; Collection: split by
(define
hs-make-object
(fn
@@ -531,7 +545,7 @@
(fn (pair) (dict-set! d (first pair) (nth pair 1)))
pairs)
d))))
;; Collection: split by
;; Collection: joined by
(define
hs-method-call
(fn
@@ -554,7 +568,7 @@
(if (= (first lst) item) i (idx-loop (rest lst) (+ i 1))))))
(idx-loop obj 0)))
(true nil))))
;; Collection: joined by
(define hs-beep (fn (v) v))
(define hs-prop-is (fn (obj key) (not (hs-falsy? (host-get obj key)))))