HS runtime: empty/swap/compound events, host-set! fix — 403→423 (51%)

- Fix host-set → host-set! in emit-inc/emit-dec (increment/decrement properties)
- Implement empty/clear command: parser dispatch, compiler, polymorphic runtime
- Implement swap command: parser dispatch, compiler (let+do temp swap pattern)
- Add parse-compound-event-name: joins dot/colon tokens (example.event, htmx:load)
- Add hs-compile to source parser (was only in WASM deploy copy)
- Add clear/swap to tokenizer keywords and cmd-kw? list
- Generator: fix run() with extra args, String.raw support

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-13 09:17:43 +00:00
parent e2fe070dd4
commit eaf3c88a36
9 changed files with 1159 additions and 35 deletions

View File

@@ -942,12 +942,40 @@
(if (= (tp-type) "comma") (adv!) nil)
(dd-collect (append acc (list key val))))))))
(cons (quote dict) (dd-collect (list)))))
(define
parse-compound-event-name
(fn
()
(let
((result (get (adv!) "value")))
(define
collect!
(fn
()
(when
(not (at-end?))
(cond
((= (tp-type) "class")
(let
((part (tp-val)))
(adv!)
(set! result (str result "." part))
(collect!)))
((= (tp-type) "local")
(let
((part (tp-val)))
(adv!)
(set! result (str result ":" part))
(collect!)))
(true nil)))))
(collect!)
result)))
(define
parse-send-cmd
(fn
()
(let
((name (get (adv!) "value")))
((name (parse-compound-event-name)))
(let
((dtl (if (= (tp-type) "paren-open") (parse-detail-dict) nil)))
(let
@@ -1422,6 +1450,21 @@
(let
((end-pos (skip-to-close 0)))
(substring src start-pos end-pos)))))
(define
parse-empty-cmd
(fn
()
(let
((target (cond ((at-end?) (list (quote sym) "me")) ((and (= (tp-type) "keyword") (or (= (tp-val) "then") (= (tp-val) "end"))) (list (quote sym) "me")) (true (parse-expr)))))
(list (quote empty-target) target))))
(define
parse-swap-cmd
(fn
()
(let
((lhs (parse-expr)))
(match-kw "with")
(let ((rhs (parse-expr))) (list (quote swap!) lhs rhs)))))
(define
parse-cmd
(fn
@@ -1503,6 +1546,12 @@
(do (adv!) (parse-halt-cmd)))
((and (= typ "keyword") (= val "focus"))
(do (adv!) (parse-focus-cmd)))
((and (= typ "keyword") (= val "empty"))
(do (adv!) (parse-empty-cmd)))
((and (= typ "keyword") (= val "clear"))
(do (adv!) (parse-empty-cmd)))
((and (= typ "keyword") (= val "swap"))
(do (adv!) (parse-swap-cmd)))
(true (parse-expr))))))
(define
parse-cmd-list
@@ -1548,7 +1597,10 @@
(= v "scroll")
(= v "select")
(= v "reset")
(= v "focus"))))
(= v "focus")
(= v "empty")
(= v "clear")
(= v "swap"))))
(define
cl-collect
(fn
@@ -1578,7 +1630,7 @@
(let
((every? (match-kw "every")))
(let
((event-name (let ((v (tp-val))) (adv!) v)))
((event-name (parse-compound-event-name)))
(let
((flt (if (= (tp-type) "bracket-open") (do (adv!) (let ((f (parse-expr))) (if (= (tp-type) "bracket-close") (adv!) nil) f)) nil)))
(let