Iter 3: ADTs + Pattern Matching
- AST: Def::Type mit Ctors; Term::Ctor (Konstruktion) und Term::Match
mit Arm/Pattern. Patterns: Wild, Var, Lit, Ctor { ctor, fields } —
Sub-Patterns im MVP auf Var/Wild beschränkt.
- Typchecker: Type-Registry, ctor_index für O(1)-Resolution, Pattern-
Bindings, Exhaustiveness-Check gegen volle Konstruktormenge plus
Negativ-Tests.
- Codegen: Boxed-Heap-Layout via malloc; Tag in Offset 0, Felder ab
Offset 8 in 8-Byte-Slots. Match lowert zu load tag + switch + Phi
am Join. Default-Block ist unreachable, wenn vom Typchecker geprüft.
- examples/list.ail.json: rekursive Int-Liste mit sum_list via match.
E2E-Test + Exhaustiveness-Tests. 19/19 Tests grün.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -23,6 +23,7 @@ pub struct Import {
|
||||
pub enum Def {
|
||||
Fn(FnDef),
|
||||
Const(ConstDef),
|
||||
Type(TypeDef),
|
||||
}
|
||||
|
||||
impl Def {
|
||||
@@ -30,10 +31,26 @@ impl Def {
|
||||
match self {
|
||||
Def::Fn(f) => &f.name,
|
||||
Def::Const(c) => &c.name,
|
||||
Def::Type(t) => &t.name,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct TypeDef {
|
||||
pub name: String,
|
||||
pub ctors: Vec<Ctor>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub doc: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Ctor {
|
||||
pub name: String,
|
||||
#[serde(default)]
|
||||
pub fields: Vec<Type>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct FnDef {
|
||||
pub name: String,
|
||||
@@ -80,6 +97,44 @@ pub enum Term {
|
||||
op: String,
|
||||
args: Vec<Term>,
|
||||
},
|
||||
/// Konstruktor-Anwendung. `type_name` bindet die ADT an, `ctor` den Variant.
|
||||
/// Beispiel: `Some(42)` -> `{ "t": "ctor", "type": "Option", "ctor": "Some",
|
||||
/// "args": [{"t":"lit","lit":{"kind":"int","value":42}}] }`.
|
||||
Ctor {
|
||||
#[serde(rename = "type")]
|
||||
type_name: String,
|
||||
ctor: String,
|
||||
#[serde(default)]
|
||||
args: Vec<Term>,
|
||||
},
|
||||
/// Pattern matching über einen Wert.
|
||||
Match {
|
||||
scrutinee: Box<Term>,
|
||||
arms: Vec<Arm>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Arm {
|
||||
pub pat: Pattern,
|
||||
pub body: Term,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(tag = "p", rename_all = "lowercase")]
|
||||
pub enum Pattern {
|
||||
/// `_` — bindet nichts, matcht alles.
|
||||
Wild,
|
||||
/// `x` — bindet den Wert an einen Namen.
|
||||
Var { name: String },
|
||||
/// Match auf ein Literal.
|
||||
Lit { lit: Literal },
|
||||
/// Match auf einen Konstruktor mit Sub-Patterns für seine Felder.
|
||||
Ctor {
|
||||
ctor: String,
|
||||
#[serde(default)]
|
||||
fields: Vec<Pattern>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
|
||||
Reference in New Issue
Block a user