0e90709a94
Lifts the gate that rejected `(pat-ctor Cons a (pat-ctor Cons b _))`.
Approach: a pure AST → AST pass `ailang_core::desugar::desugar_module`
that flattens nested-Ctor sub-patterns into chains of single-level
matches with let-bound fresh vars and duplicate fall-through. Both
ailang-check and ailang-codegen call the pass at pipeline entry.
Hash-relevant canonical bytes are untouched: the pass runs after
load_module, in memory only. `check`'s returned CheckedModule.symbols
still carries hashes of the original defs so `ail diff` / `ail manifest`
see on-disk identities.
Lit sub-patterns inside a Ctor still rejected — that's the narrower
scope of `nested-ctor-pattern-not-allowed` post-16a; the variant doc
reflects the new meaning.
Fresh-name safety: `$` is a valid ident character in form (A), so
the Desugarer pre-walks every Term::Var / Pattern::Var name into a
BTreeSet and bumps its counter past any user-spelled `$mp_N`.
Already-flat matches go through `is_flat()` and emit identical AST
shapes; every existing fixture produces the same output as before.
New: examples/nested_pat.{ailx,ail.json} prints 30 from
first_two_sum on [10, 20, 30]. e2e test
`nested_ctor_pattern_first_two_sum` guards the path.
Tests: 92/92 (e2e 32→33, ailang-core unit 10→12).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
31 lines
893 B
Plaintext
31 lines
893 B
Plaintext
; Iter 16a — first program to use a nested constructor pattern.
|
|
; Without this iter, the inner `(pat-ctor Cons b _)` would be
|
|
; rejected by the checker as `nested-ctor-pattern-not-allowed`.
|
|
|
|
(module nested_pat
|
|
|
|
(import std_list)
|
|
|
|
(fn first_two_sum
|
|
(doc "Sum of the first two elements of an Int list, or 0 if shorter than two.")
|
|
(type
|
|
(fn-type
|
|
(params (con std_list.List (con Int)))
|
|
(ret (con Int))))
|
|
(params xs)
|
|
(body
|
|
(match xs
|
|
(case (pat-ctor Cons a (pat-ctor Cons b _))
|
|
(app + a b))
|
|
(case _ 0))))
|
|
|
|
(fn main
|
|
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
|
(params)
|
|
(body
|
|
(do io/print_int (app first_two_sum
|
|
(term-ctor std_list.List Cons 10
|
|
(term-ctor std_list.List Cons 20
|
|
(term-ctor std_list.List Cons 30
|
|
(term-ctor std_list.List Nil)))))))))
|