From e71e74941e38d6668da37c080e19b16791bcd1c6 Mon Sep 17 00:00:00 2001 From: giles Date: Sun, 12 Apr 2026 18:03:56 +0000 Subject: [PATCH] Hyperscript: remove/tell/transition commands, test generator ref() fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- lib/hyperscript/compiler.sx | 41 +++++++++++++++++++++++---------- lib/hyperscript/parser.sx | 19 ++++++++------- lib/hyperscript/runtime.sx | 46 ++++++++++++++++++++++++------------- 3 files changed, 70 insertions(+), 36 deletions(-) diff --git a/lib/hyperscript/compiler.sx b/lib/hyperscript/compiler.sx index eecdd799..2bf3c984 100644 --- a/lib/hyperscript/compiler.sx +++ b/lib/hyperscript/compiler.sx @@ -240,18 +240,22 @@ ((prop (nth ast 1)) (value (hs-to-sx (nth ast 2)))) (if (= (len ast) 5) - (list - (quote hs-transition) - (hs-to-sx (nth ast 4)) - prop - value - (nth ast 3)) - (list - (quote hs-transition) - (hs-to-sx (nth ast 3)) - prop - value - nil))))) + (let + ((raw-tgt (nth ast 4))) + (list + (quote hs-transition) + (if (nil? raw-tgt) (quote me) (hs-to-sx raw-tgt)) + prop + value + (nth ast 3))) + (let + ((raw-tgt (nth ast 3))) + (list + (quote hs-transition) + (if (nil? raw-tgt) (quote me) (hs-to-sx raw-tgt)) + prop + value + 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))) diff --git a/lib/hyperscript/parser.sx b/lib/hyperscript/parser.sx index e332579e..b61639d5 100644 --- a/lib/hyperscript/parser.sx +++ b/lib/hyperscript/parser.sx @@ -1011,18 +1011,21 @@ (fn () (let - ((prop (get (adv!) "value"))) - (expect-kw! "to") + ((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 - ((value (parse-expr))) + ((from-val (if (match-kw "from") (parse-expr) nil))) + (expect-kw! "to") (let - ((dur (if (match-kw "over") (if (= (tp-type) "number") (parse-dur (get (adv!) "value")) 400) nil))) + ((value (parse-expr))) (let - ((tgt (parse-tgt-kw "on" (list (quote me))))) + ((dur (if (match-kw "over") (parse-expr) nil))) (if - dur - (list (quote transition) prop value dur tgt) - (list (quote transition) prop value tgt)))))))) + from-val + (list (quote transition-from) prop from-val value dur) + (if + dur + (list (quote transition) prop value dur nil) + (list (quote transition) prop value nil))))))))) (define parse-repeat-cmd (fn diff --git a/lib/hyperscript/runtime.sx b/lib/hyperscript/runtime.sx index 66ef9b5d..aa892e48 100644 --- a/lib/hyperscript/runtime.sx +++ b/lib/hyperscript/runtime.sx @@ -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)))))