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)))) ((prop (nth ast 1)) (value (hs-to-sx (nth ast 2))))
(if (if
(= (len ast) 5) (= (len ast) 5)
(list (let
(quote hs-transition) ((raw-tgt (nth ast 4)))
(hs-to-sx (nth ast 4)) (list
prop (quote hs-transition)
value (if (nil? raw-tgt) (quote me) (hs-to-sx raw-tgt))
(nth ast 3)) prop
(list value
(quote hs-transition) (nth ast 3)))
(hs-to-sx (nth ast 3)) (let
prop ((raw-tgt (nth ast 3)))
value (list
nil))))) (quote hs-transition)
(if (nil? raw-tgt) (quote me) (hs-to-sx raw-tgt))
prop
value
nil))))))
(define (define
emit-make emit-make
(fn (fn
@@ -913,6 +917,19 @@
(list (quote dom-set-style) tgt "visibility" "visible")) (list (quote dom-set-style) tgt "visibility" "visible"))
(true (list (quote dom-set-style) tgt "display" ""))))) (true (list (quote dom-set-style) tgt "display" "")))))
((= head (quote transition)) (emit-transition ast)) ((= 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 repeat)) (emit-repeat ast))
((= head (quote fetch)) ((= head (quote fetch))
(list (quote hs-fetch) (hs-to-sx (nth ast 1)) (nth ast 2))) (list (quote hs-fetch) (hs-to-sx (nth ast 1)) (nth ast 2)))

View File

@@ -1011,18 +1011,21 @@
(fn (fn
() ()
(let (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")))))
(expect-kw! "to")
(let (let
((value (parse-expr))) ((from-val (if (match-kw "from") (parse-expr) nil)))
(expect-kw! "to")
(let (let
((dur (if (match-kw "over") (if (= (tp-type) "number") (parse-dur (get (adv!) "value")) 400) nil))) ((value (parse-expr)))
(let (let
((tgt (parse-tgt-kw "on" (list (quote me))))) ((dur (if (match-kw "over") (parse-expr) nil)))
(if (if
dur from-val
(list (quote transition) prop value dur tgt) (list (quote transition-from) prop from-val value dur)
(list (quote transition) prop value tgt)))))))) (if
dur
(list (quote transition) prop value dur nil)
(list (quote transition) prop value nil)))))))))
(define (define
parse-repeat-cmd parse-repeat-cmd
(fn (fn

View File

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