# 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.