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:
@@ -67,3 +67,52 @@ wird, was eine andere Form ist als der AST.
|
||||
|
||||
**Architektur-Check:** Keine strukturellen Abweichungen. Codegen liest noch
|
||||
direkt das Quell-AST (TIR-Stufe wird mit ADTs in Iteration 3 nötig).
|
||||
|
||||
## 2026-05-07 — Iteration 3 fertig: ADTs
|
||||
|
||||
- TypeDef im AST mit Ctors. Ein Ctor hat `name` und `fields: [Type...]`.
|
||||
- Term::Ctor (Konstruktion) und Term::Match (Pattern Matching).
|
||||
- Patterns: `Wild`, `Var`, `Lit`, `Ctor { ctor, fields }`. Im MVP sind nested
|
||||
Ctor-Patterns NICHT erlaubt — Sub-Patterns müssen `Var` oder `Wild` sein.
|
||||
- Typchecker mit Type-Registry und `ctor_index` (ctor-name → ADT). Im Match
|
||||
wird Exhaustiveness gegen die volle Konstruktormenge geprüft. Negativ-Test
|
||||
schützt das.
|
||||
- Codegen: Boxed-Heap-Layout. Pro Ctor-Anwendung `malloc(8 + 8*n)` Bytes;
|
||||
Tag in offset 0, Felder ab offset 8 (8-Byte-Slots, native typed
|
||||
load/store). Match: load tag + switch + arm-blocks + phi am Join.
|
||||
- `examples/list.ail.json` (Cons/Nil-Liste, sum_list über match) liefert 42.
|
||||
|
||||
**Erstaunlich problemlos.** Die Architekturentscheidungen aus Tag 0 haben
|
||||
sich ausgezahlt: opaque ptr in LLVM 22 macht Boxed-Layout fast ohne
|
||||
Glue-Code möglich; das Effekt-Tracking blieb von ADTs unberührt; der
|
||||
JSON-AST nimmt neue Knoten-Typen sauber auf.
|
||||
|
||||
**Gewachsene Schulden:**
|
||||
|
||||
1. **Codegen liest immer noch direkt den Quell-AST.** Die Versuchung war
|
||||
stark, ohne TIR weiterzumachen — und hat funktioniert, weil meine
|
||||
Match-Restriktionen flach sind (keine nested Patterns). Sobald nested
|
||||
Patterns kommen, braucht es ein Decision-Tree-Lowering, das ohne TIR
|
||||
nicht sauber wird. Schulden anerkannt; nicht jetzt fällig.
|
||||
2. **Kein GC.** Heap leakt. Akzeptabel für Demo-Programme; muss vor jedem
|
||||
längerläufigen Programm angegangen werden. Optionen für Phase 4:
|
||||
Refcount, Boehm-GC-Linkage, Region-Inference.
|
||||
3. **Pretty-Printer für ADT-Werte zur Laufzeit fehlt.** `io/print_int`
|
||||
reicht für Demos, aber ein generisches `show :: a -> Str` für ADTs
|
||||
wäre wertvoll. Erfordert dispatch über tag — machbar, aber nicht jetzt.
|
||||
|
||||
**Plan Iteration 4:**
|
||||
|
||||
Die nächsten Schritte sind weniger eindeutig. Drei Kandidaten in
|
||||
Prioritätsreihenfolge:
|
||||
|
||||
1. **Modulsystem (Imports).** Aktuell ist alles in einem Modul. Mit
|
||||
mehreren Modulen + Cross-Module-Hashing wird die Sprache erst
|
||||
praktikabel für mehrere Defs.
|
||||
2. **Strukturierte Fehlerausgabe (`ail check --json`).** Damit Tools auf
|
||||
Typfehler reagieren können, ohne Text zu parsen.
|
||||
3. **Closures / höherwertige Funktionen.** Erfordert Closure-Konvertierung
|
||||
und ist ein größerer Schritt.
|
||||
|
||||
Iteration 4 wird (1) + (2) — beides macht das LLM-Tooling stärker und
|
||||
hat moderates Risiko.
|
||||
|
||||
Reference in New Issue
Block a user