Iter 16c — literal patterns via desugar
Desugar `Pattern::Lit` (top-level and nested in Ctor) to
`Term::If { cond = (== sv lit), then = body, else_ = fall_k }`.
After 16c, no Pattern::Lit survives the desugar pass; codegen
and typechecker never see one. `is_flat` reclassifies Lit as
non-flat to force the chain machinery; new `build_eq` helper
constructs the equality test per literal kind.
Tests: 99 → 103 (+1 e2e lit_pat_demo, +3 desugar unit). Demo
fixture exercises top-level lit arms (classify) and nested
lit-in-Ctor (categorize_first) with a local IntList; output
100/200/999/-1/0/7.
Known limitations documented in DESIGN.md and JOURNAL: (a)
chain machinery's Unit terminator means non-Wild-terminated
exhaustive matches with lit arms still need a trailing `_`
catch-all to type-check; (b) `==` is currently Int-only, so
Bool/Str/Unit lit patterns desugar correctly but error at
typecheck.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+17
-12
@@ -758,8 +758,10 @@ Iter 14h via qualified `module.Type` / `module.Ctor` references in
|
||||
both `(con ...)` and `(term-ctor ...)` / `(pat-ctor ...)` positions);
|
||||
GC for ADT boxes, lambda envs, and closure pairs (Boehm conservative
|
||||
collector wired up in Iter 14f, see Decision 9); nested constructor
|
||||
sub-patterns inside `match` (lifted in Iter 16a via the desugar pass —
|
||||
literal sub-patterns are still rejected, see below).
|
||||
sub-patterns inside `match` (lifted in Iter 16a via the desugar pass);
|
||||
literal sub-patterns inside a Ctor pattern (lifted in Iter 16c — the
|
||||
desugar pass rewrites every `Pattern::Lit` to a `Term::If` on `==`,
|
||||
both at the top level of an arm and inside a Ctor sub-pattern).
|
||||
|
||||
- No effect handlers — only the built-in IO and Diverge ops.
|
||||
- No refinements / SMT escalation.
|
||||
@@ -772,10 +774,6 @@ literal sub-patterns are still rejected, see below).
|
||||
instantiation, deferred.
|
||||
- No higher-rank polymorphism. Passing a polymorphic fn to another
|
||||
polymorphic fn (`apply(id, 42)`) is not supported.
|
||||
- No literal sub-patterns inside a Ctor pattern. `(pat-ctor Cons 0 _)`
|
||||
is rejected (`nested-ctor-pattern-not-allowed` from `ailang-check`)
|
||||
because the pattern-match backend has no switch-on-i64 yet.
|
||||
Workaround: bind a var and test in the arm body.
|
||||
- No local recursive `let`. `let f = ... in ...` only sees `f`'s
|
||||
binding inside the body, not inside its own RHS — recursion needs
|
||||
a top-level def.
|
||||
@@ -788,12 +786,19 @@ What **is** supported (and used as the smoke test for the pipeline):
|
||||
- `if`, `let`, function calls, recursion.
|
||||
- Effects on function signatures, with `do op(args)` for direct effect
|
||||
ops (`io/print_int`, `io/print_bool`, `io/print_str`).
|
||||
- **ADTs + pattern matching** (Iter 3, extended in Iter 16a). Sub-patterns
|
||||
of a Ctor pattern may be `Var`, `Wild`, **or another `Ctor`** (the
|
||||
desugar pass flattens nested Ctor patterns into a chain of let + match
|
||||
before typecheck/codegen — see `ailang-core::desugar` and Pipeline
|
||||
above). Literal sub-patterns (`(pat-ctor Cons 0 _)`) are still rejected
|
||||
by `ailang-check`.
|
||||
- **ADTs + pattern matching** (Iter 3, extended in Iter 16a/16c).
|
||||
Sub-patterns of a Ctor pattern may be `Var`, `Wild`, another `Ctor`
|
||||
(Iter 16a), or a literal (Iter 16c). The desugar pass flattens
|
||||
nested Ctor patterns into a chain of let + match and rewrites every
|
||||
`Pattern::Lit` (top-level or sub-) to a `Term::If` on `==` before
|
||||
typecheck/codegen — see `ailang-core::desugar` and Pipeline above.
|
||||
- Literal patterns at top level and inside Ctor sub-patterns (Iter 16c,
|
||||
via desugar). `(pat-lit 0)` and `(pat-ctor Cons (pat-lit 0) _)` both
|
||||
parse and lower; the rewrite is to `Term::If { cond = (== sv lit) }`,
|
||||
so any literal kind whose `==` is supported by the typechecker is
|
||||
authorable. Today that means `Int`; `Bool`/`Str`/`Unit` lit patterns
|
||||
are accepted by desugar but reach typecheck as a type error because
|
||||
`==` is `(Int, Int) -> Bool` only.
|
||||
- **Imports + qualified cross-module references** via dotted names
|
||||
(Iter 5). Extends to **types and constructors** (Iter 14h): a foreign
|
||||
module's ADT is referenced as `(con std_pair.Pair a b)`, its ctors as
|
||||
|
||||
Reference in New Issue
Block a user