Parser: catch/finally in on handlers, cmd terminators — 279/831 (34%)

- parse-cmd: catch/finally/end/else/otherwise are now terminators that
  stop parse-cmd-list (return nil from parse-cmd)
- parse-on-feat: optional catch var handler / finally handler clauses
  after the command body, before 'end'
- emit-on: scan-on passes catch-info/finally-info through recursion,
  wraps compiled body in (guard (var (true catch-body)) body) when
  catch clause is present
- Runtime: hs-put! handles "start" (afterbegin) and "end" (beforeend)
- Removed duplicate conformance-dev.sx (all 110 tests already in behavioral)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-10 21:51:43 +00:00
parent f97a1711c6
commit 08cd82ed65
5 changed files with 99 additions and 20 deletions

View File

@@ -1201,6 +1201,9 @@
(let
((typ (tp-type)) (val (tp-val)))
(cond
;; Terminators — these end a command list, not start a command
((and (= typ "keyword") (or (= val "catch") (= val "finally") (= val "end") (= val "else") (= val "otherwise")))
nil)
((and (= typ "keyword") (= val "add"))
(do (adv!) (parse-add-cmd)))
((and (= typ "keyword") (= val "remove"))
@@ -1298,6 +1301,18 @@
((source (if (match-kw "from") (parse-expr) nil)))
(let
((body (parse-cmd-list)))
;; Parse optional catch/finally
(let
((catch-clause
(if (match-kw "catch")
(let ((var (let ((v (tp-val))) (adv!) v))
(handler (parse-cmd-list)))
(list var handler))
nil))
(finally-clause
(if (match-kw "finally")
(parse-cmd-list)
nil)))
(match-kw "end")
(let
((parts (list (quote on) event-name)))
@@ -1307,7 +1322,10 @@
((parts (if flt (append parts (list :filter flt)) parts)))
(let
((parts (if source (append parts (list :from source)) parts)))
(append parts (list body)))))))))))))
(let ((parts (if catch-clause (append parts (list :catch catch-clause)) parts)))
(let ((parts (if finally-clause (append parts (list :finally finally-clause)) parts)))
(let ((parts (append parts (list body))))
parts)))))))))))))))
(define
parse-init-feat
(fn