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

@@ -193,6 +193,13 @@
(= (len (rest val)) (len arg-pats)))
(ocaml-match-list arg-pats (rest val) env))
(else ocaml-match-fail))))
((= tag "pas")
;; (:pas INNER NAME) — match inner pattern, also bind NAME → val.
(let ((inner (nth pat 1)) (alias (nth pat 2)))
(let ((env2 (ocaml-match-pat inner val env)))
(cond
((= env2 ocaml-match-fail) ocaml-match-fail)
(else (ocaml-env-extend env2 alias val))))))
((= tag "pcons")
;; (:pcons HEAD TAIL) — val must be a non-empty list.
(cond
@@ -239,11 +246,24 @@
(error (str "ocaml-eval: match failure on " val)))
(else
(let ((clause (first cs)))
(let ((pat (nth clause 1)) (body (nth clause 2)))
(let ((env2 (ocaml-match-pat pat val env)))
(cond
((= env2 ocaml-match-fail) (try-clauses (rest cs)))
(else (ocaml-eval body env2))))))))))
(let ((ctag (nth clause 0)))
(cond
((= ctag "case")
(let ((pat (nth clause 1)) (body (nth clause 2)))
(let ((env2 (ocaml-match-pat pat val env)))
(cond
((= env2 ocaml-match-fail) (try-clauses (rest cs)))
(else (ocaml-eval body env2))))))
((= ctag "case-when")
(let ((pat (nth clause 1))
(guard (nth clause 2))
(body (nth clause 3)))
(let ((env2 (ocaml-match-pat pat val env)))
(cond
((= env2 ocaml-match-fail) (try-clauses (rest cs)))
((not (ocaml-eval guard env2)) (try-clauses (rest cs)))
(else (ocaml-eval body env2))))))
(else (error (str "ocaml-match: bad clause tag " ctag))))))))))
(try-clauses clauses))))
(define ocaml-match-eval