Files
RustAst/docs/macros_and_templates.md
T
Michael Schimmel 94fc6bf56d feat: Implement AST macros and templates
This commit introduces support for AST macros and templates, enabling
users to define and use custom, reusable components within the visual
DSL.

Key changes include:
- A new `MacroRegistry` to manage macro definitions.
- A `MacroExpander` to process macro calls and expand templates.
- A `MacroEvaluator` trait for evaluating expressions during expansion.
- The `Expansion` node in `BoundKind` to preserve the original macro
  call and its expanded form for debugging.
- Updates to the `Binder`, `Dumper`, and `UpvalueAnalyzer` to handle the
  new macro constructs.
- New examples demonstrating various macro functionalities like
  `unless`, splicing, and nested macros.
2026-02-18 12:51:07 +01:00

49 lines
2.9 KiB
Markdown

# AST Macros & Templates (Portierung von Delphi nach Rust)
Dieses Dokument beschreibt die Architektur und Nomenklatur für das Makro- und Template-System im Rust-AST-Compiler.
## 1. Motivation: Warum Makros in einer visuellen DSL?
In einer visuellen DSL dienen Makros als **Benutzerdefinierte Komponenten**. Ein User baut einen Graphen (den Body), definiert Eingänge (Placeholder) und deklariert dieses Template unter einem Namen. Bei der Kompilierung wird dieses Template an den Aufrufstellen "expandiert".
**Vorteile:**
- **Abstraktion:** Komplexe Logik wird hinter einem einzigen Block in der UI versteckt.
- **Wiederverwendbarkeit:** Einmal deklarierte Finanz-Indikatoren können überall eingesetzt werden.
- **Kompilierzeit-Optimierung:** Strukturelle Transformationen (z.B. Loop-Unrolling) können über Makros abgebildet werden.
## 2. Nomenklatur (Visuelle Ebene statt Lisp-Ebene)
Um die Kluft zwischen Text-Logik (Lisp) und visueller Logik zu schließen, wurde folgende Nomenklatur gewählt:
| Konzept | Name in Rust | Funktion |
| :--- | :--- | :--- |
| `akMacroDefinition` | `MacroDecl` | Deklariert ein benanntes Template als Compiler-Erweiterung. |
| `akQuasiquote` | `Template` | Ein Rahmen (Sub-Graph), in dem Placeholder ersetzt werden können. |
| `akUnquote` | `Placeholder` | Ein "Loch" oder "Input-Pin" innerhalb eines Templates. |
| `akUnquoteSplicing` | `Splice` | Ein spezialisierter Placeholder, der Inhalte "auspackt" und verschmilzt. |
| `akMacroExpansion` | `Expansion` | Ein Hybrid-Knoten, der den Original-Aufruf und das Ergebnis speichert. |
## 3. Semantik von "Splice" (Die Verschmelzung)
Ein `Splice(X)`-Knoten löst die äußere Hülle von $X$ auf und fügt dessen Elemente direkt in den Ziel-Container ein.
### 3.1 Striktes Verhalten (Entscheidung)
In dieser Implementierung gilt ein **striktes** Splicing. Das bedeutet, dass $X$ zur Kompilierzeit als Container erkannt werden muss.
- **In Sequenzen (Tuple / Block):**
- $X$ muss ein `Tuple` oder ein `Block` sein.
- Die Elemente von $X$ werden flach in die Ziel-Sequenz eingefügt.
- **In Records (Map):**
- $X$ muss eine `Map` sein.
- Die Key-Value-Paare von $X$ werden mit der Ziel-Map verschmolzen (Merging).
- **Fehlverhalten:** Falls $X$ kein unterstützter Container ist (z.B. eine Konstante oder ein If-Ausdruck), bricht der Compiler mit einem Fehler ab. Dies verhindert logische Inkonsistenzen im Makro-Design.
## 4. Transparenz & Debugging (Der Expansion-Knoten)
Der `Expansion`-Knoten ist das Herzstück für ein sauberes User-Erlebnis:
1. **Origin-Tracking:** Er behält die `Identity` (Span/NodeId) des ursprünglichen Aufrufs.
2. **Transparenz:** Die UI kann im Fehlerfall auf den High-Level-Block verweisen, während der Compiler den hocheffizienten, expandierten Code sieht.
3. **Visualisierung:** Er ermöglicht ein "Aufklappen" von Makro-Blöcken in der GUI, um die innere Funktionsweise des expandierten Codes zu inspizieren.