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

2.9 KiB

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.