From bf9d342c6ebd362e8fc59c6a009dfc14c8d99d81 Mon Sep 17 00:00:00 2001 From: giles Date: Tue, 5 May 2026 18:29:13 +0000 Subject: [PATCH] =?UTF-8?q?HS:=20parse-cmd=20arith=20guard=20fixes=20?= =?UTF-8?q?=E2=80=94=20math/numbers/sourceInfo/stringPostfix=20(+14=20test?= =?UTF-8?q?s)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three parse-cmd / parse-feat refinements: 1. Remove dict-branch from arith guard: span-mode=true produces dict nodes with :kind "arith", not lists. The guard only needs the list-branch (for span-mode=false). Without this, hs-src "x + y" threw a parse error. 2. parse-feat top-level expression-first fallback: when no feature keyword is found, try parse-expr first. If it fully consumes the input (at-end?), return the expression directly — bypassing parse-cmd and its arith guard. This matches upstream _hyperscript("1 + 1") which evaluates as an expression, not a pseudo-command. 3. paren-close exception in arith guard: when the token after the arithmetic expression is ")", we are inside a parenthesised context (e.g. "(0+1) em" string-postfix). Allow it through without the pseudo-command error. Co-Authored-By: Claude Sonnet 4.6 --- lib/hyperscript/parser.sx | 34 ++++++++++++++++++------------ shared/static/wasm/sx/hs-parser.sx | 34 ++++++++++++++++++------------ 2 files changed, 40 insertions(+), 28 deletions(-) diff --git a/lib/hyperscript/parser.sx b/lib/hyperscript/parser.sx index 15e05503..8a125aaa 100644 --- a/lib/hyperscript/parser.sx +++ b/lib/hyperscript/parser.sx @@ -2878,19 +2878,17 @@ (let ((expr (parse-expr))) (if - (if - (and (dict? expr) (get expr :hs-ast)) - (= (get expr :kind) "arith") - (and - (list? expr) - (let - ((h (first expr))) - (or - (= h (quote +)) - (= h (quote -)) - (= h (quote *)) - (= h (quote /)) - (= h (make-symbol "%")))))) + (and + (list? expr) + (not (= (tp-type) "paren-close")) + (let + ((h (first expr))) + (or + (= h (quote +)) + (= h (quote -)) + (= h (quote *)) + (= h (quote /)) + (= h (make-symbol "%"))))) (error "Pseudo-commands must be function calls") expr)))))))) (define @@ -3220,7 +3218,15 @@ (error "worker plugin is not installed — see https://hyperscript.org/features/worker")) ((= val "bind") (do (adv!) (parse-bind-feat))) - (true (parse-cmd-list)))))) + (true + (let + ((saved-p p)) + (let + ((expr (guard (_e (true nil)) (parse-expr)))) + (if + (and expr (at-end?)) + expr + (do (set! p saved-p) (parse-cmd-list)))))))))) (define coll-feats (fn diff --git a/shared/static/wasm/sx/hs-parser.sx b/shared/static/wasm/sx/hs-parser.sx index 15e05503..8a125aaa 100644 --- a/shared/static/wasm/sx/hs-parser.sx +++ b/shared/static/wasm/sx/hs-parser.sx @@ -2878,19 +2878,17 @@ (let ((expr (parse-expr))) (if - (if - (and (dict? expr) (get expr :hs-ast)) - (= (get expr :kind) "arith") - (and - (list? expr) - (let - ((h (first expr))) - (or - (= h (quote +)) - (= h (quote -)) - (= h (quote *)) - (= h (quote /)) - (= h (make-symbol "%")))))) + (and + (list? expr) + (not (= (tp-type) "paren-close")) + (let + ((h (first expr))) + (or + (= h (quote +)) + (= h (quote -)) + (= h (quote *)) + (= h (quote /)) + (= h (make-symbol "%"))))) (error "Pseudo-commands must be function calls") expr)))))))) (define @@ -3220,7 +3218,15 @@ (error "worker plugin is not installed — see https://hyperscript.org/features/worker")) ((= val "bind") (do (adv!) (parse-bind-feat))) - (true (parse-cmd-list)))))) + (true + (let + ((saved-p p)) + (let + ((expr (guard (_e (true nil)) (parse-expr)))) + (if + (and expr (at-end?)) + expr + (do (set! p saved-p) (parse-cmd-list)))))))))) (define coll-feats (fn