ocaml: phase 1+3 or-patterns (P1 | P2 | ...) parens-only (+5 tests, 394 total)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 41s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 41s
Parser: when | follows a pattern inside parens, build (:por ALT1 ALT2 ...). Eval: try alternatives, succeed on first match. Top-level | remains the clause separator — parens-only avoids ambiguity without lookahead. Examples now work: match n with | (1 | 2 | 3) -> 100 | _ -> 0 match c with | (Red | Green) -> 1 | Blue -> 2
This commit is contained in:
@@ -259,6 +259,22 @@
|
||||
(= (len (rest val)) (len arg-pats)))
|
||||
(ocaml-match-list arg-pats (rest val) env))
|
||||
(else ocaml-match-fail))))
|
||||
((= tag "por")
|
||||
;; (:por ALT1 ALT2 ...) — try each alternative; succeed on the
|
||||
;; first match. Note: for now, alternatives must bind the same
|
||||
;; set of variables (OCaml constraint) — we don't enforce this.
|
||||
(let ((alts (rest pat)) (result ocaml-match-fail) (done false))
|
||||
(begin
|
||||
(define try-alts
|
||||
(fn (xs)
|
||||
(when (and (not done) (not (= xs (list))))
|
||||
(let ((env2 (ocaml-match-pat (first xs) val env)))
|
||||
(cond
|
||||
((not (= env2 ocaml-match-fail))
|
||||
(begin (set! result env2) (set! done true)))
|
||||
(else (try-alts (rest xs))))))))
|
||||
(try-alts alts)
|
||||
result)))
|
||||
((= tag "pas")
|
||||
;; (:pas INNER NAME) — match inner pattern, also bind NAME → val.
|
||||
(let ((inner (nth pat 1)) (alias (nth pat 2)))
|
||||
|
||||
Reference in New Issue
Block a user