ocaml: phase 3 'as' alias + 'when' guard in match (+6 tests, 295 total)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 50s

Pattern parser top wraps cons-pat with 'as ident' -> (:pas PAT NAME).
Match clause parser consumes optional 'when GUARD-EXPR' before -> and
emits (:case-when PAT GUARD BODY) instead of :case.

Eval: :pas matches inner pattern then binds the alias name; case-when
checks the guard after a successful match and falls through to the next
clause if the guard is false.

Or-patterns deferred — ambiguous with clause separator without
parens-only support.
This commit is contained in:
2026-05-08 12:28:07 +00:00
parent 7fb65cd26a
commit 851e0585cf
4 changed files with 84 additions and 11 deletions

View File

@@ -281,7 +281,20 @@
(advance-tok!)
(list :pcons lhs (parse-pattern-cons))))
(else lhs)))))
(set! parse-pattern (fn () (parse-pattern-cons)))
;; Top-level pattern is the cons-pat layer wrapped with optional
;; `pat as name` aliasing. Or-patterns are not supported at the
;; top level due to ambiguity with the match clause separator;
;; use `(A | B)` if needed in the future via a parens-only or.
(set! parse-pattern
(fn ()
(let ((p (parse-pattern-cons)))
(cond
((at-kw? "as")
(begin
(advance-tok!)
(let ((n (ocaml-tok-value (consume! "ident" nil))))
(list :pas p n))))
(else p)))))
(define peek-tok-at
(fn (n)
@@ -673,12 +686,20 @@
(fn
()
(let
((p (parse-pattern)))
((p (parse-pattern)) (guard nil))
(begin
(when (at-kw? "when")
(begin
(advance-tok!)
(set! guard (parse-expr-no-seq))))
(consume! "op" "->")
(let
((body (parse-expr)))
(append! cases (list :case p body)))))))
(cond
((= guard nil)
(append! cases (list :case p body)))
(else
(append! cases (list :case-when p guard body)))))))))
(one)
(define
loop