ocaml: phase 4 'let PATTERN = expr in body' tuple destructuring (+3 tests, 541 total)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 44s

When 'let' is followed by '(', parse-let now reads a full pattern
(via the existing parse-pattern used by match), expects '=', then
'in', and desugars to:

  let PATTERN = EXPR in BODY  =>  match EXPR with PATTERN -> BODY

This reuses the entire pattern-matching machinery, so any pattern
the match parser accepts works here too — paren-tuples, nested
tuples, cons patterns, list patterns. No 'rec' allowed for pattern
bindings (real OCaml's restriction).

  let (a, b) = (1, 2) in a + b              = 3
  let (a, b, c) = (10, 20, 30) in a + b + c = 60
  let pair = (5, 7) in
  let (x, y) = pair in x * y                = 35

Also retroactively cleaned up Printf's iter-97 width-pos packing
hack ('width * 1000000 + spec_pos') — it's now
'let (width, spec_pos) = parse_width_loop after_flags in ...' like
real OCaml.
This commit is contained in:
2026-05-09 03:40:38 +00:00
parent 7e64695a74
commit dab8718289
4 changed files with 36 additions and 4 deletions

View File

@@ -765,6 +765,19 @@
(consume! "keyword" "in")
(let ((body (parse-expr)))
(list :let-open path body))))))
;; `let PATTERN = expr in body` — non-trivial pattern
;; desugars to `match expr with PATTERN -> body`. Triggers
;; on `(` (paren-tuple, possibly nested) immediately after
;; `let` (no `rec` allowed for pattern bindings).
((at-op? "(")
(let ((pat (parse-pattern)))
(begin
(consume! "op" "=")
(let ((rhs (parse-expr)))
(begin
(consume! "keyword" "in")
(let ((body (parse-expr)))
(list :match rhs (list (list :case pat body)))))))))
(else
(let ((reccy false) (bindings (list)))
(begin