diff --git a/lib/ocaml/baseline/lru_cache.ml b/lib/ocaml/baseline/lru_cache.ml index 9153db10..51fb6533 100644 --- a/lib/ocaml/baseline/lru_cache.ml +++ b/lib/ocaml/baseline/lru_cache.ml @@ -27,11 +27,10 @@ let put k v = let cleaned = remove !cache in let trimmed = if List.length cleaned >= cap then - let rec take n lst = - if n = 0 then [] - else match lst with - | [] -> [] - | h :: r -> h :: take (n - 1) r + let rec take n lst = match n, lst with + | 0, _ -> [] + | _, [] -> [] + | _, h :: r -> h :: take (n - 1) r in take (cap - 1) cleaned else cleaned diff --git a/lib/ocaml/parser.sx b/lib/ocaml/parser.sx index 941507ea..25d795c1 100644 --- a/lib/ocaml/parser.sx +++ b/lib/ocaml/parser.sx @@ -328,14 +328,38 @@ ;; use `(A | B)` if needed in the future via a parens-only or. (set! parse-pattern (fn () - (let ((p (parse-pattern-cons))) + ;; Top-level pattern: cons-pat, optionally followed by + ;; comma-separated patterns for ad-hoc tuple matching + ;; (`match e1, e2 with | p1, p2 -> …`), optionally aliased + ;; with `as name`. + (let ((first (parse-pattern-cons))) (cond + ((at-op? ",") + (let ((items (list first))) + (begin + (define loop-comma + (fn () + (when (at-op? ",") + (begin + (advance-tok!) + (append! items (parse-pattern-cons)) + (loop-comma))))) + (loop-comma) + (let ((p (cons :ptuple items))) + (cond + ((at-kw? "as") + (begin + (advance-tok!) + (let ((n (ocaml-tok-value + (consume! "ident" nil)))) + (list :pas p n)))) + (else p)))))) ((at-kw? "as") (begin (advance-tok!) (let ((n (ocaml-tok-value (consume! "ident" nil)))) - (list :pas p n)))) - (else p))))) + (list :pas first n)))) + (else first))))) (define peek-tok-at (fn (n) diff --git a/plans/ocaml-on-sx.md b/plans/ocaml-on-sx.md index 5f209ede..24604c06 100644 --- a/plans/ocaml-on-sx.md +++ b/plans/ocaml-on-sx.md @@ -407,6 +407,14 @@ _Newest first._ binary search tree (`type 'a tree = Leaf | Node of 'a * 'a tree * 'a tree`) with insert + in-order traversal. Tests parametric ADT, recursive match, List.append, List.fold_left. +- 2026-05-11 Phase 5.1 — parser: top-level tuple patterns + (`match e1, e2 with | p1, p2 -> …`). `parse-pattern` now collects + comma-separated patterns into a `:ptuple`, mirroring the scrutinee + side which already builds tuples via `parse-tuple`. Real OCaml + accepts this ad-hoc tuple shorthand without surrounding parens. + lru_cache.ml reverts the iter-258 workaround back to the natural + `match n, lst with | 0, _ -> [] | _, [] -> [] | _, h :: r -> …` + form. 607/607 regressions clean. - 2026-05-11 Phase 5.1 — lru_cache.ml baseline (list-backed LRU cache of capacity 3, fingerprint 100 + (-1) + 300 + 100 = 499). Each `get` / `put` removes the existing entry then conses the @@ -414,10 +422,8 @@ _Newest first._ Tests `match … with [] -> … | (k', v) :: rest when k' = k -> …` pattern matching with `when` guards over tuple-cons patterns, `function` keyword for short scrutinee-free matches, recursive - `find` / `remove` / `take` over the same list. Note: parser does - not yet handle `match n, lst with` ad-hoc tuple-scrutinee (got - "expected op -> got op ,"); workaround uses an outer `if` then - inner `match lst with`. 171 baseline programs total. + `find` / `remove` / `take` over the same list. 171 baseline + programs total. - 2026-05-11 Phase 5.1 — convex_hull.ml baseline (Andrew's monotone chain over 8 points → 5-vertex convex hull). Sorts points lexicographically, then builds lower hull left-to-right and upper