HS: parser fixes — parenthesized commands + add error + class-name depth (+3 tests)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 40s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 40s
- parse-on-feat: event-vars paren check now restores position and returns empty
list when the first token after '(' is a keyword (command starter). Previously
'(log me)' was consumed as event variable names instead of a parenthesized
command, silently dropping the command body and returning empty innerHTML.
Fixes 'can support parenthesized commands and features'.
- parse-add-cmd: true-fallback now throws instead of returning nil when no 'to'
keyword follows the expression. Makes 'add - to' and similar invalid add forms
throw a parse error, satisfying assert-throws in 'basic parse error messages
work' and '_hyperscript() evaluate API still throws on first error'.
- read-class-name: '(' and ')' now only allowed inside '[...]' bracket groups
(depth > 0). Previously allowing them at top level caused '.innerHTML)' at the
end of a possessive expression to be consumed into the class token, producing
'innerHTML))' as a bogus property name. Tailwind classes like
'group-[:nth-of-type(3)_&]:block' still tokenize correctly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1164,7 +1164,9 @@
|
||||
(let
|
||||
((tgt (parse-expr)))
|
||||
(list (quote add-value) value tgt))
|
||||
nil))))))
|
||||
(error
|
||||
(str
|
||||
"Invalid 'add' syntax: expected a class (.foo), attribute, or expression with 'to'"))))))))
|
||||
(define
|
||||
parse-remove-cmd
|
||||
(fn
|
||||
@@ -2973,7 +2975,7 @@
|
||||
(let
|
||||
((of-filter (when (and (= event-name "mutation") (match-kw "of")) (cond ((and (= (tp-type) "ident") (or (= (tp-val) "attributes") (= (tp-val) "childList") (= (tp-val) "characterData"))) (let ((nm (tp-val))) (do (adv!) (dict "type" nm)))) ((= (tp-type) "attr") (let ((attrs (list (tp-val)))) (do (adv!) (define collect-or! (fn () (when (match-kw "or") (cond ((= (tp-type) "attr") (do (set! attrs (append attrs (list (tp-val)))) (adv!) (collect-or!))) (true (set! p (- p 1))))))) (collect-or!) (dict "type" "attrs" "attrs" attrs)))) (true nil)))))
|
||||
(let
|
||||
((event-vars (if (= (tp-type) "paren-open") (do (adv!) (define ev-coll (fn () (cond ((or (= (tp-type) "paren-close") (= (tp-type) "eof")) (do (when (= (tp-type) "paren-close") (adv!)) (list))) ((or (= (tp-type) "ident") (= (tp-type) "keyword")) (let ((nm (tp-val))) (adv!) (cons nm (ev-coll)))) (true (do (adv!) (ev-coll)))))) (ev-coll)) (list))))
|
||||
((event-vars (if (= (tp-type) "paren-open") (let ((saved-p p)) (do (adv!) (if (= (tp-type) "keyword") (do (set! p saved-p) (list)) (do (define ev-coll (fn () (cond ((or (= (tp-type) "paren-close") (= (tp-type) "eof")) (do (when (= (tp-type) "paren-close") (adv!)) (list))) ((or (= (tp-type) "ident") (= (tp-type) "keyword")) (let ((nm (tp-val))) (adv!) (cons nm (ev-coll)))) (true (do (adv!) (ev-coll)))))) (ev-coll))))) (list))))
|
||||
(let
|
||||
((flt (if (= (tp-type) "bracket-open") (do (adv!) (let ((f (parse-expr))) (if (= (tp-type) "bracket-close") (adv!) nil) f)) nil)))
|
||||
(let
|
||||
|
||||
@@ -459,7 +459,7 @@
|
||||
(define
|
||||
build-name
|
||||
(fn
|
||||
(acc)
|
||||
(acc depth)
|
||||
(cond
|
||||
((and (< pos src-len) (= (hs-cur) "\\") (< (+ pos 1) src-len))
|
||||
(do
|
||||
@@ -467,15 +467,35 @@
|
||||
(let
|
||||
((c (hs-cur)))
|
||||
(hs-advance! 1)
|
||||
(build-name (str acc c)))))
|
||||
((and (< pos src-len) (or (hs-ident-char? (hs-cur)) (= (hs-cur) ":") (= (hs-cur) "[") (= (hs-cur) "]") (= (hs-cur) "(") (= (hs-cur) ")") (= (hs-cur) "&")))
|
||||
(build-name (str acc c) depth))))
|
||||
((and (< pos src-len) (= (hs-cur) "["))
|
||||
(do
|
||||
(let
|
||||
((c (hs-cur)))
|
||||
(hs-advance! 1)
|
||||
(build-name (str acc c)))))
|
||||
(build-name (str acc c) (+ depth 1)))))
|
||||
((and (< pos src-len) (= (hs-cur) "]"))
|
||||
(do
|
||||
(let
|
||||
((c (hs-cur)))
|
||||
(hs-advance! 1)
|
||||
(build-name
|
||||
(str acc c)
|
||||
(if (> depth 0) (- depth 1) 0)))))
|
||||
((and (< pos src-len) (> depth 0) (or (= (hs-cur) "(") (= (hs-cur) ")")))
|
||||
(do
|
||||
(let
|
||||
((c (hs-cur)))
|
||||
(hs-advance! 1)
|
||||
(build-name (str acc c) depth))))
|
||||
((and (< pos src-len) (or (hs-ident-char? (hs-cur)) (= (hs-cur) ":") (= (hs-cur) "&")))
|
||||
(do
|
||||
(let
|
||||
((c (hs-cur)))
|
||||
(hs-advance! 1)
|
||||
(build-name (str acc c) depth))))
|
||||
(true acc))))
|
||||
(build-name "")))
|
||||
(build-name "" 0)))
|
||||
(define
|
||||
hs-emit!
|
||||
(fn
|
||||
|
||||
@@ -1164,7 +1164,9 @@
|
||||
(let
|
||||
((tgt (parse-expr)))
|
||||
(list (quote add-value) value tgt))
|
||||
nil))))))
|
||||
(error
|
||||
(str
|
||||
"Invalid 'add' syntax: expected a class (.foo), attribute, or expression with 'to'"))))))))
|
||||
(define
|
||||
parse-remove-cmd
|
||||
(fn
|
||||
@@ -2973,7 +2975,7 @@
|
||||
(let
|
||||
((of-filter (when (and (= event-name "mutation") (match-kw "of")) (cond ((and (= (tp-type) "ident") (or (= (tp-val) "attributes") (= (tp-val) "childList") (= (tp-val) "characterData"))) (let ((nm (tp-val))) (do (adv!) (dict "type" nm)))) ((= (tp-type) "attr") (let ((attrs (list (tp-val)))) (do (adv!) (define collect-or! (fn () (when (match-kw "or") (cond ((= (tp-type) "attr") (do (set! attrs (append attrs (list (tp-val)))) (adv!) (collect-or!))) (true (set! p (- p 1))))))) (collect-or!) (dict "type" "attrs" "attrs" attrs)))) (true nil)))))
|
||||
(let
|
||||
((event-vars (if (= (tp-type) "paren-open") (do (adv!) (define ev-coll (fn () (cond ((or (= (tp-type) "paren-close") (= (tp-type) "eof")) (do (when (= (tp-type) "paren-close") (adv!)) (list))) ((or (= (tp-type) "ident") (= (tp-type) "keyword")) (let ((nm (tp-val))) (adv!) (cons nm (ev-coll)))) (true (do (adv!) (ev-coll)))))) (ev-coll)) (list))))
|
||||
((event-vars (if (= (tp-type) "paren-open") (let ((saved-p p)) (do (adv!) (if (= (tp-type) "keyword") (do (set! p saved-p) (list)) (do (define ev-coll (fn () (cond ((or (= (tp-type) "paren-close") (= (tp-type) "eof")) (do (when (= (tp-type) "paren-close") (adv!)) (list))) ((or (= (tp-type) "ident") (= (tp-type) "keyword")) (let ((nm (tp-val))) (adv!) (cons nm (ev-coll)))) (true (do (adv!) (ev-coll)))))) (ev-coll))))) (list))))
|
||||
(let
|
||||
((flt (if (= (tp-type) "bracket-open") (do (adv!) (let ((f (parse-expr))) (if (= (tp-type) "bracket-close") (adv!) nil) f)) nil)))
|
||||
(let
|
||||
|
||||
@@ -459,7 +459,7 @@
|
||||
(define
|
||||
build-name
|
||||
(fn
|
||||
(acc)
|
||||
(acc depth)
|
||||
(cond
|
||||
((and (< pos src-len) (= (hs-cur) "\\") (< (+ pos 1) src-len))
|
||||
(do
|
||||
@@ -467,15 +467,35 @@
|
||||
(let
|
||||
((c (hs-cur)))
|
||||
(hs-advance! 1)
|
||||
(build-name (str acc c)))))
|
||||
((and (< pos src-len) (or (hs-ident-char? (hs-cur)) (= (hs-cur) ":") (= (hs-cur) "[") (= (hs-cur) "]") (= (hs-cur) "(") (= (hs-cur) ")") (= (hs-cur) "&")))
|
||||
(build-name (str acc c) depth))))
|
||||
((and (< pos src-len) (= (hs-cur) "["))
|
||||
(do
|
||||
(let
|
||||
((c (hs-cur)))
|
||||
(hs-advance! 1)
|
||||
(build-name (str acc c)))))
|
||||
(build-name (str acc c) (+ depth 1)))))
|
||||
((and (< pos src-len) (= (hs-cur) "]"))
|
||||
(do
|
||||
(let
|
||||
((c (hs-cur)))
|
||||
(hs-advance! 1)
|
||||
(build-name
|
||||
(str acc c)
|
||||
(if (> depth 0) (- depth 1) 0)))))
|
||||
((and (< pos src-len) (> depth 0) (or (= (hs-cur) "(") (= (hs-cur) ")")))
|
||||
(do
|
||||
(let
|
||||
((c (hs-cur)))
|
||||
(hs-advance! 1)
|
||||
(build-name (str acc c) depth))))
|
||||
((and (< pos src-len) (or (hs-ident-char? (hs-cur)) (= (hs-cur) ":") (= (hs-cur) "&")))
|
||||
(do
|
||||
(let
|
||||
((c (hs-cur)))
|
||||
(hs-advance! 1)
|
||||
(build-name (str acc c) depth))))
|
||||
(true acc))))
|
||||
(build-name "")))
|
||||
(build-name "" 0)))
|
||||
(define
|
||||
hs-emit!
|
||||
(fn
|
||||
|
||||
Reference in New Issue
Block a user