HS: add CSS template interpolation fix (+1 test)

${}{"val"} pattern in add {prop: ${}{"val"}} uses two consecutive brace
groups: empty ${} followed by {"val"} for the actual expression. The prior
fix called parse-expr when already at the brace-close of the empty group,
returning nil. New fix: detect empty ${} (brace-open then brace-close),
skip the close, then read the actual value from the following {…} block.
Also handles non-empty ${expr} directly as before.
Suite hs-upstream-add: 17/19 → 18/19. Smoke 0-195: 174/195 → 175/195.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-26 14:42:36 +00:00
parent a0bbf74c01
commit 5a76a04010
2 changed files with 276 additions and 84 deletions

View File

@@ -23,13 +23,14 @@
(define at-end? (fn () (or (>= p tok-len) (= (tp-type) "eof")))) (define at-end? (fn () (or (>= p tok-len) (= (tp-type) "eof"))))
(define cur-start (fn () (if (< p tok-len) (get (tp) "pos") 0))) (define cur-start (fn () (if (< p tok-len) (get (tp) "pos") 0)))
(define cur-line (fn () (if (< p tok-len) (get (tp) "line") 1))) (define cur-line (fn () (if (< p tok-len) (get (tp) "line") 1)))
(define prev-end (fn () (if (> p 0) (get (nth tokens (- p 1)) "end") 0))) (define
(define hs-ast-wrap prev-end
(fn (raw kind start end-pos line fields) (fn () (if (> p 0) (get (nth tokens (- p 1)) "end") 0)))
(if hs-span-mode (define
{:hs-ast true :kind kind :start start :end end-pos :line line hs-ast-wrap
:src src :children raw :fields fields} (fn
raw))) (raw kind start end-pos line fields)
(if hs-span-mode {:children raw :end end-pos :kind kind :line line :src src :start start :hs-ast true :fields fields} raw)))
(define (define
match-kw match-kw
(fn (fn
@@ -80,7 +81,11 @@
(base) (base)
(let (let
((base-start (if (and (dict? base) (get base :hs-ast)) (get base :start) (cur-start))) ((base-start (if (and (dict? base) (get base :hs-ast)) (get base :start) (cur-start)))
(base-line (if (and (dict? base) (get base :hs-ast)) (get base :line) (cur-line)))) (base-line
(if
(and (dict? base) (get base :hs-ast))
(get base :line)
(cur-line))))
(if (if
(and (= (tp-type) "class") (not (at-end?))) (and (= (tp-type) "class") (not (at-end?)))
(let (let
@@ -90,7 +95,11 @@
(parse-prop-chain (parse-prop-chain
(hs-ast-wrap (hs-ast-wrap
(list (make-symbol ".") base prop) (list (make-symbol ".") base prop)
"member" base-start (prev-end) base-line {:root base})))) "member"
base-start
(prev-end)
base-line
{:root base}))))
(if (if
(= (tp-type) "paren-open") (= (tp-type) "paren-open")
(let (let
@@ -98,7 +107,11 @@
(parse-prop-chain (parse-prop-chain
(hs-ast-wrap (hs-ast-wrap
(list (quote method-call) base args) (list (quote method-call) base args)
"call" base-start (prev-end) base-line {:root base}))) "call"
base-start
(prev-end)
base-line
{:root base})))
base))))) base)))))
(define (define
parse-trav parse-trav
@@ -143,11 +156,23 @@
((typ (tp-type)) (val (tp-val))) ((typ (tp-type)) (val (tp-val)))
(cond (cond
((= typ "number") ((= typ "number")
(let ((s (cur-start)) (l (cur-line))) (let
(do (adv!) (hs-ast-wrap (parse-dur val) "number" s (prev-end) l {})))) ((s (cur-start)) (l (cur-line)))
(do
(adv!)
(hs-ast-wrap
(parse-dur val)
"number"
s
(prev-end)
l
{}))))
((= typ "string") ((= typ "string")
(let ((s (cur-start)) (l (cur-line))) (let
(do (adv!) (hs-ast-wrap val "string" s (prev-end) l {})))) ((s (cur-start)) (l (cur-line)))
(do
(adv!)
(hs-ast-wrap val "string" s (prev-end) l {}))))
((= typ "template") (do (adv!) (list (quote template) val))) ((= typ "template") (do (adv!) (list (quote template) val)))
((and (= typ "keyword") (= val "true")) (do (adv!) true)) ((and (= typ "keyword") (= val "true")) (do (adv!) true))
((and (= typ "keyword") (= val "false")) (do (adv!) false)) ((and (= typ "keyword") (= val "false")) (do (adv!) false))
@@ -212,10 +237,20 @@
((and (= typ "keyword") (= val "last")) ((and (= typ "keyword") (= val "last"))
(do (adv!) (parse-pos-kw (quote last)))) (do (adv!) (parse-pos-kw (quote last))))
((= typ "id") ((= typ "id")
(let ((s (cur-start)) (l (cur-line))) (let
(do (adv!) (hs-ast-wrap (list (quote query) (str "#" val)) "selector" s (prev-end) l {})))) ((s (cur-start)) (l (cur-line)))
(do
(adv!)
(hs-ast-wrap
(list (quote query) (str "#" val))
"selector"
s
(prev-end)
l
{}))))
((= typ "selector") ((= typ "selector")
(let ((s (cur-start)) (l (cur-line))) (let
((s (cur-start)) (l (cur-line)))
(do (do
(adv!) (adv!)
(hs-ast-wrap (hs-ast-wrap
@@ -226,9 +261,14 @@
(list (list
(quote query-scoped) (quote query-scoped)
val val
(parse-cmp (parse-arith (parse-poss (parse-atom)))))) (parse-cmp
(parse-arith (parse-poss (parse-atom))))))
(list (quote query) val)) (list (quote query) val))
"selector" s (prev-end) l {})))) "selector"
s
(prev-end)
l
{}))))
((= typ "attr") ((= typ "attr")
(do (adv!) (list (quote attr) val (list (quote me))))) (do (adv!) (list (quote attr) val (list (quote me)))))
((= typ "style") ((= typ "style")
@@ -245,11 +285,29 @@
(adv!) (adv!)
(list (quote dom-ref) name (list (quote me))))))) (list (quote dom-ref) name (list (quote me)))))))
((= typ "class") ((= typ "class")
(let ((s (cur-start)) (l (cur-line))) (let
(do (adv!) (hs-ast-wrap (list (quote query) (str "." val)) "selector" s (prev-end) l {})))) ((s (cur-start)) (l (cur-line)))
(do
(adv!)
(hs-ast-wrap
(list (quote query) (str "." val))
"selector"
s
(prev-end)
l
{}))))
((= typ "ident") ((= typ "ident")
(let ((s (cur-start)) (l (cur-line))) (let
(do (adv!) (hs-ast-wrap (list (quote ref) val) "ref" s (prev-end) l {})))) ((s (cur-start)) (l (cur-line)))
(do
(adv!)
(hs-ast-wrap
(list (quote ref) val)
"ref"
s
(prev-end)
l
{}))))
((= typ "paren-open") ((= typ "paren-open")
(do (do
(adv!) (adv!)
@@ -970,8 +1028,7 @@
((prop (get (adv!) "value"))) ((prop (get (adv!) "value")))
(when (= (tp-type) "colon") (adv!)) (when (= (tp-type) "colon") (adv!))
(let (let
((val (tp-val))) ((val (if (and (= (tp-type) "ident") (= (tp-val) "$")) (do (adv!) (when (= (tp-type) "brace-open") (adv!)) (if (= (tp-type) "brace-close") (do (adv!) (if (= (tp-type) "brace-open") (do (adv!) (let ((inner (parse-expr))) (when (= (tp-type) "brace-close") (adv!)) inner)) "")) (let ((expr (parse-expr))) (when (= (tp-type) "brace-close") (adv!)) expr))) (get (adv!) "value"))))
(adv!)
(set! pairs (cons (list prop val) pairs)) (set! pairs (cons (list prop val) pairs))
(collect-pairs!)))))) (collect-pairs!))))))
(collect-pairs!) (collect-pairs!)
@@ -2052,9 +2109,19 @@
((right (let ((a (parse-atom))) (if (nil? a) a (parse-poss a))))) ((right (let ((a (parse-atom))) (if (nil? a) a (parse-poss a)))))
(let (let
((lhs-start (if (and (dict? left) (get left :hs-ast)) (get left :start) 0)) ((lhs-start (if (and (dict? left) (get left :hs-ast)) (get left :start) 0))
(lhs-line (if (and (dict? left) (get left :hs-ast)) (get left :line) 1))) (lhs-line
(if
(and (dict? left) (get left :hs-ast))
(get left :line)
1)))
(parse-arith (parse-arith
(hs-ast-wrap (list op left right) "arith" lhs-start (prev-end) lhs-line {:lhs left :rhs right})))))) (hs-ast-wrap
(list op left right)
"arith"
lhs-start
(prev-end)
lhs-line
{:rhs right :lhs left}))))))
left)))) left))))
(define (define
parse-the-expr parse-the-expr
@@ -2454,15 +2521,21 @@
((and (= typ "keyword") (= val "put")) ((and (= typ "keyword") (= val "put"))
(do (adv!) (parse-put-cmd))) (do (adv!) (parse-put-cmd)))
((and (= typ "keyword") (= val "if")) ((and (= typ "keyword") (= val "if"))
(let ((s (cur-start)) (l (cur-line))) (let
((s (cur-start)) (l (cur-line)))
(do (do
(adv!) (adv!)
(let ((r (parse-if-cmd))) (let
(let ((tb (if (and (list? r) (> (len r) 2)) (nth r 2) nil))) ((r (parse-if-cmd)))
(hs-ast-wrap r "if" s (prev-end) l (let
(if tb ((tb (if (and (list? r) (> (len r) 2)) (nth r 2) nil)))
{:true-branch (if (and (list? tb) (= (first tb) (quote do))) (nth tb 1) tb)} (hs-ast-wrap
{}))))))) r
"if"
s
(prev-end)
l
(if tb {:true-branch (if (and (list? tb) (= (first tb) (quote do))) (nth tb 1) tb)} {})))))))
((and (= typ "keyword") (= val "wait")) ((and (= typ "keyword") (= val "wait"))
(do (adv!) (parse-wait-cmd))) (do (adv!) (parse-wait-cmd)))
((and (= typ "keyword") (= val "send")) ((and (= typ "keyword") (= val "send"))
@@ -2470,8 +2543,17 @@
((and (= typ "keyword") (= val "trigger")) ((and (= typ "keyword") (= val "trigger"))
(do (adv!) (parse-trigger-cmd))) (do (adv!) (parse-trigger-cmd)))
((and (= typ "keyword") (= val "log")) ((and (= typ "keyword") (= val "log"))
(let ((s (cur-start)) (l (cur-line))) (let
(do (adv!) (hs-ast-wrap (parse-log-cmd) "cmd" s (prev-end) l {})))) ((s (cur-start)) (l (cur-line)))
(do
(adv!)
(hs-ast-wrap
(parse-log-cmd)
"cmd"
s
(prev-end)
l
{}))))
((and (= typ "keyword") (= val "increment")) ((and (= typ "keyword") (= val "increment"))
(do (adv!) (parse-inc-cmd))) (do (adv!) (parse-inc-cmd)))
((and (= typ "keyword") (= val "decrement")) ((and (= typ "keyword") (= val "decrement"))
@@ -2511,8 +2593,17 @@
((and (= typ "keyword") (= val "tell")) ((and (= typ "keyword") (= val "tell"))
(do (adv!) (parse-tell-cmd))) (do (adv!) (parse-tell-cmd)))
((and (= typ "keyword") (= val "for")) ((and (= typ "keyword") (= val "for"))
(let ((s (cur-start)) (l (cur-line))) (let
(do (adv!) (hs-ast-wrap (parse-for-cmd) "cmd" s (prev-end) l {})))) ((s (cur-start)) (l (cur-line)))
(do
(adv!)
(hs-ast-wrap
(parse-for-cmd)
"cmd"
s
(prev-end)
l
{}))))
((and (= typ "keyword") (= val "make")) ((and (= typ "keyword") (= val "make"))
(do (adv!) (parse-make-cmd))) (do (adv!) (parse-make-cmd)))
((and (= typ "keyword") (= val "install")) ((and (= typ "keyword") (= val "install"))
@@ -2642,10 +2733,13 @@
loop loop
(fn (fn
(i) (i)
(when (< i (- (len cmds-list) 1)) (when
(< i (- (len cmds-list) 1))
(let (let
((cur-node (nth cmds-list i)) (nxt-node (nth cmds-list (+ i 1)))) ((cur-node (nth cmds-list i))
(when (and (dict? cur-node) (get cur-node :hs-ast)) (nxt-node (nth cmds-list (+ i 1))))
(when
(and (dict? cur-node) (get cur-node :hs-ast))
(dict-set! (get cur-node :fields) "next" nxt-node))) (dict-set! (get cur-node :fields) "next" nxt-node)))
(loop (+ i 1))))) (loop (+ i 1)))))
(loop 0) (loop 0)
@@ -2810,7 +2904,9 @@
((= val "behavior") (do (adv!) (parse-behavior-feat))) ((= val "behavior") (do (adv!) (parse-behavior-feat)))
((= val "live") (do (adv!) (parse-live-feat))) ((= val "live") (do (adv!) (parse-live-feat)))
((= val "when") (do (adv!) (parse-when-feat))) ((= val "when") (do (adv!) (parse-when-feat)))
((= val "worker") (error "worker plugin is not installed — see https://hyperscript.org/features/worker")) ((= val "worker")
(error
"worker plugin is not installed — see https://hyperscript.org/features/worker"))
(true (parse-cmd-list)))))) (true (parse-cmd-list))))))
(define (define
coll-feats coll-feats

View File

@@ -23,13 +23,14 @@
(define at-end? (fn () (or (>= p tok-len) (= (tp-type) "eof")))) (define at-end? (fn () (or (>= p tok-len) (= (tp-type) "eof"))))
(define cur-start (fn () (if (< p tok-len) (get (tp) "pos") 0))) (define cur-start (fn () (if (< p tok-len) (get (tp) "pos") 0)))
(define cur-line (fn () (if (< p tok-len) (get (tp) "line") 1))) (define cur-line (fn () (if (< p tok-len) (get (tp) "line") 1)))
(define prev-end (fn () (if (> p 0) (get (nth tokens (- p 1)) "end") 0))) (define
(define hs-ast-wrap prev-end
(fn (raw kind start end-pos line fields) (fn () (if (> p 0) (get (nth tokens (- p 1)) "end") 0)))
(if hs-span-mode (define
{:hs-ast true :kind kind :start start :end end-pos :line line hs-ast-wrap
:src src :children raw :fields fields} (fn
raw))) (raw kind start end-pos line fields)
(if hs-span-mode {:children raw :end end-pos :kind kind :line line :src src :start start :hs-ast true :fields fields} raw)))
(define (define
match-kw match-kw
(fn (fn
@@ -80,7 +81,11 @@
(base) (base)
(let (let
((base-start (if (and (dict? base) (get base :hs-ast)) (get base :start) (cur-start))) ((base-start (if (and (dict? base) (get base :hs-ast)) (get base :start) (cur-start)))
(base-line (if (and (dict? base) (get base :hs-ast)) (get base :line) (cur-line)))) (base-line
(if
(and (dict? base) (get base :hs-ast))
(get base :line)
(cur-line))))
(if (if
(and (= (tp-type) "class") (not (at-end?))) (and (= (tp-type) "class") (not (at-end?)))
(let (let
@@ -90,7 +95,11 @@
(parse-prop-chain (parse-prop-chain
(hs-ast-wrap (hs-ast-wrap
(list (make-symbol ".") base prop) (list (make-symbol ".") base prop)
"member" base-start (prev-end) base-line {:root base})))) "member"
base-start
(prev-end)
base-line
{:root base}))))
(if (if
(= (tp-type) "paren-open") (= (tp-type) "paren-open")
(let (let
@@ -98,7 +107,11 @@
(parse-prop-chain (parse-prop-chain
(hs-ast-wrap (hs-ast-wrap
(list (quote method-call) base args) (list (quote method-call) base args)
"call" base-start (prev-end) base-line {:root base}))) "call"
base-start
(prev-end)
base-line
{:root base})))
base))))) base)))))
(define (define
parse-trav parse-trav
@@ -143,11 +156,23 @@
((typ (tp-type)) (val (tp-val))) ((typ (tp-type)) (val (tp-val)))
(cond (cond
((= typ "number") ((= typ "number")
(let ((s (cur-start)) (l (cur-line))) (let
(do (adv!) (hs-ast-wrap (parse-dur val) "number" s (prev-end) l {})))) ((s (cur-start)) (l (cur-line)))
(do
(adv!)
(hs-ast-wrap
(parse-dur val)
"number"
s
(prev-end)
l
{}))))
((= typ "string") ((= typ "string")
(let ((s (cur-start)) (l (cur-line))) (let
(do (adv!) (hs-ast-wrap val "string" s (prev-end) l {})))) ((s (cur-start)) (l (cur-line)))
(do
(adv!)
(hs-ast-wrap val "string" s (prev-end) l {}))))
((= typ "template") (do (adv!) (list (quote template) val))) ((= typ "template") (do (adv!) (list (quote template) val)))
((and (= typ "keyword") (= val "true")) (do (adv!) true)) ((and (= typ "keyword") (= val "true")) (do (adv!) true))
((and (= typ "keyword") (= val "false")) (do (adv!) false)) ((and (= typ "keyword") (= val "false")) (do (adv!) false))
@@ -212,10 +237,20 @@
((and (= typ "keyword") (= val "last")) ((and (= typ "keyword") (= val "last"))
(do (adv!) (parse-pos-kw (quote last)))) (do (adv!) (parse-pos-kw (quote last))))
((= typ "id") ((= typ "id")
(let ((s (cur-start)) (l (cur-line))) (let
(do (adv!) (hs-ast-wrap (list (quote query) (str "#" val)) "selector" s (prev-end) l {})))) ((s (cur-start)) (l (cur-line)))
(do
(adv!)
(hs-ast-wrap
(list (quote query) (str "#" val))
"selector"
s
(prev-end)
l
{}))))
((= typ "selector") ((= typ "selector")
(let ((s (cur-start)) (l (cur-line))) (let
((s (cur-start)) (l (cur-line)))
(do (do
(adv!) (adv!)
(hs-ast-wrap (hs-ast-wrap
@@ -226,9 +261,14 @@
(list (list
(quote query-scoped) (quote query-scoped)
val val
(parse-cmp (parse-arith (parse-poss (parse-atom)))))) (parse-cmp
(parse-arith (parse-poss (parse-atom))))))
(list (quote query) val)) (list (quote query) val))
"selector" s (prev-end) l {})))) "selector"
s
(prev-end)
l
{}))))
((= typ "attr") ((= typ "attr")
(do (adv!) (list (quote attr) val (list (quote me))))) (do (adv!) (list (quote attr) val (list (quote me)))))
((= typ "style") ((= typ "style")
@@ -245,11 +285,29 @@
(adv!) (adv!)
(list (quote dom-ref) name (list (quote me))))))) (list (quote dom-ref) name (list (quote me)))))))
((= typ "class") ((= typ "class")
(let ((s (cur-start)) (l (cur-line))) (let
(do (adv!) (hs-ast-wrap (list (quote query) (str "." val)) "selector" s (prev-end) l {})))) ((s (cur-start)) (l (cur-line)))
(do
(adv!)
(hs-ast-wrap
(list (quote query) (str "." val))
"selector"
s
(prev-end)
l
{}))))
((= typ "ident") ((= typ "ident")
(let ((s (cur-start)) (l (cur-line))) (let
(do (adv!) (hs-ast-wrap (list (quote ref) val) "ref" s (prev-end) l {})))) ((s (cur-start)) (l (cur-line)))
(do
(adv!)
(hs-ast-wrap
(list (quote ref) val)
"ref"
s
(prev-end)
l
{}))))
((= typ "paren-open") ((= typ "paren-open")
(do (do
(adv!) (adv!)
@@ -970,8 +1028,7 @@
((prop (get (adv!) "value"))) ((prop (get (adv!) "value")))
(when (= (tp-type) "colon") (adv!)) (when (= (tp-type) "colon") (adv!))
(let (let
((val (tp-val))) ((val (if (and (= (tp-type) "ident") (= (tp-val) "$")) (do (adv!) (when (= (tp-type) "brace-open") (adv!)) (if (= (tp-type) "brace-close") (do (adv!) (if (= (tp-type) "brace-open") (do (adv!) (let ((inner (parse-expr))) (when (= (tp-type) "brace-close") (adv!)) inner)) "")) (let ((expr (parse-expr))) (when (= (tp-type) "brace-close") (adv!)) expr))) (get (adv!) "value"))))
(adv!)
(set! pairs (cons (list prop val) pairs)) (set! pairs (cons (list prop val) pairs))
(collect-pairs!)))))) (collect-pairs!))))))
(collect-pairs!) (collect-pairs!)
@@ -2052,9 +2109,19 @@
((right (let ((a (parse-atom))) (if (nil? a) a (parse-poss a))))) ((right (let ((a (parse-atom))) (if (nil? a) a (parse-poss a)))))
(let (let
((lhs-start (if (and (dict? left) (get left :hs-ast)) (get left :start) 0)) ((lhs-start (if (and (dict? left) (get left :hs-ast)) (get left :start) 0))
(lhs-line (if (and (dict? left) (get left :hs-ast)) (get left :line) 1))) (lhs-line
(if
(and (dict? left) (get left :hs-ast))
(get left :line)
1)))
(parse-arith (parse-arith
(hs-ast-wrap (list op left right) "arith" lhs-start (prev-end) lhs-line {:lhs left :rhs right})))))) (hs-ast-wrap
(list op left right)
"arith"
lhs-start
(prev-end)
lhs-line
{:rhs right :lhs left}))))))
left)))) left))))
(define (define
parse-the-expr parse-the-expr
@@ -2454,15 +2521,21 @@
((and (= typ "keyword") (= val "put")) ((and (= typ "keyword") (= val "put"))
(do (adv!) (parse-put-cmd))) (do (adv!) (parse-put-cmd)))
((and (= typ "keyword") (= val "if")) ((and (= typ "keyword") (= val "if"))
(let ((s (cur-start)) (l (cur-line))) (let
((s (cur-start)) (l (cur-line)))
(do (do
(adv!) (adv!)
(let ((r (parse-if-cmd))) (let
(let ((tb (if (and (list? r) (> (len r) 2)) (nth r 2) nil))) ((r (parse-if-cmd)))
(hs-ast-wrap r "if" s (prev-end) l (let
(if tb ((tb (if (and (list? r) (> (len r) 2)) (nth r 2) nil)))
{:true-branch (if (and (list? tb) (= (first tb) (quote do))) (nth tb 1) tb)} (hs-ast-wrap
{}))))))) r
"if"
s
(prev-end)
l
(if tb {:true-branch (if (and (list? tb) (= (first tb) (quote do))) (nth tb 1) tb)} {})))))))
((and (= typ "keyword") (= val "wait")) ((and (= typ "keyword") (= val "wait"))
(do (adv!) (parse-wait-cmd))) (do (adv!) (parse-wait-cmd)))
((and (= typ "keyword") (= val "send")) ((and (= typ "keyword") (= val "send"))
@@ -2470,8 +2543,17 @@
((and (= typ "keyword") (= val "trigger")) ((and (= typ "keyword") (= val "trigger"))
(do (adv!) (parse-trigger-cmd))) (do (adv!) (parse-trigger-cmd)))
((and (= typ "keyword") (= val "log")) ((and (= typ "keyword") (= val "log"))
(let ((s (cur-start)) (l (cur-line))) (let
(do (adv!) (hs-ast-wrap (parse-log-cmd) "cmd" s (prev-end) l {})))) ((s (cur-start)) (l (cur-line)))
(do
(adv!)
(hs-ast-wrap
(parse-log-cmd)
"cmd"
s
(prev-end)
l
{}))))
((and (= typ "keyword") (= val "increment")) ((and (= typ "keyword") (= val "increment"))
(do (adv!) (parse-inc-cmd))) (do (adv!) (parse-inc-cmd)))
((and (= typ "keyword") (= val "decrement")) ((and (= typ "keyword") (= val "decrement"))
@@ -2511,8 +2593,17 @@
((and (= typ "keyword") (= val "tell")) ((and (= typ "keyword") (= val "tell"))
(do (adv!) (parse-tell-cmd))) (do (adv!) (parse-tell-cmd)))
((and (= typ "keyword") (= val "for")) ((and (= typ "keyword") (= val "for"))
(let ((s (cur-start)) (l (cur-line))) (let
(do (adv!) (hs-ast-wrap (parse-for-cmd) "cmd" s (prev-end) l {})))) ((s (cur-start)) (l (cur-line)))
(do
(adv!)
(hs-ast-wrap
(parse-for-cmd)
"cmd"
s
(prev-end)
l
{}))))
((and (= typ "keyword") (= val "make")) ((and (= typ "keyword") (= val "make"))
(do (adv!) (parse-make-cmd))) (do (adv!) (parse-make-cmd)))
((and (= typ "keyword") (= val "install")) ((and (= typ "keyword") (= val "install"))
@@ -2642,10 +2733,13 @@
loop loop
(fn (fn
(i) (i)
(when (< i (- (len cmds-list) 1)) (when
(< i (- (len cmds-list) 1))
(let (let
((cur-node (nth cmds-list i)) (nxt-node (nth cmds-list (+ i 1)))) ((cur-node (nth cmds-list i))
(when (and (dict? cur-node) (get cur-node :hs-ast)) (nxt-node (nth cmds-list (+ i 1))))
(when
(and (dict? cur-node) (get cur-node :hs-ast))
(dict-set! (get cur-node :fields) "next" nxt-node))) (dict-set! (get cur-node :fields) "next" nxt-node)))
(loop (+ i 1))))) (loop (+ i 1)))))
(loop 0) (loop 0)
@@ -2810,7 +2904,9 @@
((= val "behavior") (do (adv!) (parse-behavior-feat))) ((= val "behavior") (do (adv!) (parse-behavior-feat)))
((= val "live") (do (adv!) (parse-live-feat))) ((= val "live") (do (adv!) (parse-live-feat)))
((= val "when") (do (adv!) (parse-when-feat))) ((= val "when") (do (adv!) (parse-when-feat)))
((= val "worker") (error "worker plugin is not installed — see https://hyperscript.org/features/worker")) ((= val "worker")
(error
"worker plugin is not installed — see https://hyperscript.org/features/worker"))
(true (parse-cmd-list)))))) (true (parse-cmd-list))))))
(define (define
coll-feats coll-feats