Docs
This commit is contained in:
File diff suppressed because one or more lines are too long
+144
@@ -0,0 +1,144 @@
|
||||
|
||||
-----
|
||||
|
||||
# High-Performance Backend (Bytecode VM)
|
||||
|
||||
**Datum:** 21.11.2025
|
||||
**Status:** Entwurf / Planungsphase
|
||||
**Zielarchitektur:** Stack-based Virtual Machine (ähnlich Lua 5.x / Python)
|
||||
|
||||
## 1\. Motivation & Architektur-Ziele
|
||||
|
||||
* **Status Quo:** Der aktuelle AST-Evaluator ist mächtig, flexibel und ideal für Debugging, leidet aber unter "Pointer Chasing" (Cache Misses) und Rekursions-Overhead (CPU Stack Frames).
|
||||
* **Ziel:** Maximale Ausführungsgeschwindigkeit für typisierte, numerische Operationen bei gleichzeitiger Beibehaltung der vollen Sprachflexibilität (Closures, dynamische Typen).
|
||||
* **Strategie:** Implementierung einer linearen Stack-Maschine.
|
||||
* **Compiler:** Transformiert den *spezialisierten* AST in ein flaches Array von Instruktionen.
|
||||
* **VM:** Eine "Dispatch Loop", die Instruktionen abarbeitet und Delphi-Funktionen für komplexe Datentypen (Records, Series) als "Fernsteuerung" nutzt.
|
||||
|
||||
-----
|
||||
|
||||
## 2\. Phasenplan
|
||||
|
||||
### Phase 1: Das Fundament (Datenstrukturen)
|
||||
|
||||
**Ziel:** Definition der binären Repräsentation des Codes und des Laufzeit-Stacks.
|
||||
|
||||
* **Task 1.1: Stack-Architektur definieren**
|
||||
* Implementierung von `TStackSlot` als **Tagged Union** (Variant Record).
|
||||
* Größe: Max. 16 Bytes (Alignment-freundlich).
|
||||
* Typen: `skEmpty`, `skInt64`, `skDouble`, `skBoolean`, `skPointer` (für RefCounted Objekte).
|
||||
* **Task 1.2: OpCodes definieren (`TOpCode`)**
|
||||
* Kategorisierung in: Stack Ops, Arithmetik (Getrennt nach `_Int`, `_Flt`, `_Dyn`), Flow Control, Calls.
|
||||
* **Task 1.3: Instruktions-Format (`TInstruction`)**
|
||||
* Record mit `OpCode` (Byte/Enum) und Argumenten (`Arg1`, `Arg2`, `Arg3`: Integer).
|
||||
* **Task 1.4: Container (`TBytecodeChunk`)**
|
||||
* Klasse, die `TArray<TInstruction>`, `TArray<TDataValue>` (Constant Pool) und Metadaten (MaxStackSize) hält.
|
||||
|
||||
### Phase 2: Der Compiler (Core Arithmetic)
|
||||
|
||||
**Ziel:** Kompilierung einfacher mathematischer Ausdrücke ohne Kontrollfluss.
|
||||
|
||||
* **Task 2.1: Compiler-Gerüst (`TBytecodeCompiler`)**
|
||||
* Implementierung als `TAstVisitor` (oder `IAstVisitor`).
|
||||
* Verwaltung des `TBytecodeChunk`.
|
||||
* Verwaltung einer virtuellen "Stack Height" zur Berechnung von `MaxStackSize`.
|
||||
* **Task 2.2: Konstanten laden**
|
||||
* Visitor für `VisitConstant`.
|
||||
* Logik: Konstante im Pool suchen/einfügen $\to$ `opLdConst <Index>` emittieren.
|
||||
* **Task 2.3: Arithmetik & Typ-Spezialisierung**
|
||||
* Visitor für `FunctionCall` (Spezialfall: Binäre Operatoren).
|
||||
* Nutzung der `IStaticType`-Informationen aus dem AST.
|
||||
* Entscheidunglogik:
|
||||
* Sind Operanden `Int64`? $\to$ `opAddInt`.
|
||||
* Sind Operanden `Double`? $\to$ `opAddFlt`.
|
||||
* Sonst $\to$ `opAdd` (Fallback).
|
||||
|
||||
### Phase 3: Die Virtual Machine (The Engine)
|
||||
|
||||
**Ziel:** Ausführung des in Phase 2 generierten Codes.
|
||||
|
||||
* **Task 3.1: Die VM-Klasse (`TVM`)**
|
||||
* Aufbau des `OperandStack` (Array of `TStackSlot`).
|
||||
* Register: `IP` (Instruction Pointer), `SP` (Stack Pointer), `BP` (Base/Frame Pointer).
|
||||
* **Task 3.2: Dispatch Loop**
|
||||
* Implementierung der `Run(Chunk)` Methode.
|
||||
* Großes `case Instruction.OpCode of ...`.
|
||||
* **Task 3.3: Implementierung der Core-OpCodes**
|
||||
* `opLdConst`: Kopieren von Constant-Pool auf Stack.
|
||||
* `opAddInt`: Roher Zugriff auf `Stack[SP].AsInt`. (Performance-kritisch\!).
|
||||
* `opAdd`: Generischer Pfad (Unboxing, Operation, Boxing).
|
||||
|
||||
### Phase 4: Variablen & Kontrollfluss
|
||||
|
||||
**Ziel:** Unterstützung von `if`, lokalen Variablen und einfachen Schleifen (`recur`).
|
||||
|
||||
* **Task 4.1: Lokale Variablen**
|
||||
* Mapping im Compiler: AST `SlotIndex` $\to$ Stack-Relativ-Index.
|
||||
* OpCodes: `opLdLocal <Idx>`, `opStLocal <Idx>`.
|
||||
* **Task 4.2: Sprünge (Jumps)**
|
||||
* Compiler: Handling von `VisitIfExpression`.
|
||||
* Logik: Emittieren von Platzhalter-Jumps, Patching der Sprungziele nach Generierung des Branches.
|
||||
* OpCodes: `opJmp`, `opJmpFalse`.
|
||||
* **Task 4.3: TCO / Recur**
|
||||
* `VisitRecurNode`: Generierung von `Move` Instruktionen (Argumente an Position der Parameter kopieren) + `opJmp` zum Start der Funktion.
|
||||
|
||||
### Phase 5: Funktionen & Closures (Die Kür)
|
||||
|
||||
**Ziel:** First-Class Functions und Upvalue-Handling.
|
||||
|
||||
* **Task 5.1: Funktions-Prototypen**
|
||||
* Erweiterung `TBytecodeChunk` um Sub-Chunks (Prototypen für innere Funktionen).
|
||||
* **Task 5.2: Upvalue-Analyse Integration**
|
||||
* Nutzung der Ergebnisse des Binders/UpvalueAnalyzers.
|
||||
* Compiler muss wissen, welche Variable Stack-Local ist und welche ein Upvalue ist.
|
||||
* **Task 5.3: Closure-Instanziierung**
|
||||
* OpCode: `opClosure <ProtoIdx>`.
|
||||
* VM: Erzeugt `TClosure` Objekt, sammelt "Capture"-Variablen vom Stack ein (Hoisting) und speichert sie im Closure-Objekt.
|
||||
* **Task 5.4: Calls (`opCall`)**
|
||||
* VM: Stack-Frame Management (Sichern von `BP`, `IP` auf dem Call-Stack).
|
||||
* Umschalten des aktiven Chunks.
|
||||
|
||||
### Phase 6: Interop & komplexe Typen
|
||||
|
||||
**Ziel:** Brückenschlag zur existierenden Delphi-Logik.
|
||||
|
||||
* **Task 6.1: Native Calls (`opCallNative`)**
|
||||
* Aufruf von RTL-Funktionen via Funktionszeiger.
|
||||
* Konvertierung `TStackSlot` $\leftrightarrow$ Argumente.
|
||||
* **Task 6.2: Records & Series**
|
||||
* OpCodes: `opNewRecord`, `opSeriesAdd`.
|
||||
* VM: Ruft direkt `TScalarRecord.Create` etc. auf. Hier wird keine Logik dupliziert, nur delegiert.
|
||||
|
||||
-----
|
||||
|
||||
## 3\. Technische Eckpfeiler
|
||||
|
||||
### Das Datenmodell (VM Stack)
|
||||
|
||||
```pascal
|
||||
type
|
||||
TStackSlot = record
|
||||
case Kind: TDataValueKind of
|
||||
vkOrdinal: (AsInt: Int64);
|
||||
vkFloat: (AsFloat: Double);
|
||||
vkObj: (AsPtr: Pointer); // IInterface / TObject / String
|
||||
end;
|
||||
```
|
||||
|
||||
### Die Optimierungs-Strategie
|
||||
|
||||
1. **Binder/TypeChecker:** Leisten die Vorarbeit (Auflösung von Namen zu Indizes, Typ-Inferenz).
|
||||
2. **Compiler:** Entscheidet statisch über OpCodes (`ADD_INT` vs `ADD`).
|
||||
3. **VM:** Führt "blind" und schnell aus. Typprüfungen nur im `_DYN` Pfad oder als Assert.
|
||||
|
||||
-----
|
||||
|
||||
## 4\. Nächste Schritte (Todo)
|
||||
|
||||
1. [ ] Anlegen der Unit `Myc.Bytecode.Types` (Definition OpCodes, Instruction, StackSlot).
|
||||
2. [ ] Implementierung `TBytecodeCompiler` (Skeleton: Nur Constants & Return).
|
||||
3. [ ] Implementierung `TVM` (Skeleton: Stack setup, Dispatch loop für Const/Ret).
|
||||
4. [ ] Erster Integrationstest: `42` kompiliert $\to$ VM führt aus $\to$ Resultat 42.
|
||||
5. [ ] Erweiterung um `BinaryOp` (Add/Sub) inkl. Typ-Spezialisierung.
|
||||
|
||||
-----
|
||||
@@ -0,0 +1,41 @@
|
||||
# Projektplan: Myc Compiler & Visual Editor Integration
|
||||
|
||||
**Datum:** 28.11.2025 12:42
|
||||
|
||||
### Motivation
|
||||
Der Compiler-Kern wurde erfolgreich auf eine robuste, immutable Architektur umgestellt ("Green Tree / Red Tree"). Durch die Einführung von `IAstIdentity` und einem Logging-basierten Fehlersystem ("Fail-Safe") gehen Metadaten während der Transformationen (Binder, TypeChecker, Optimierung) nicht mehr verloren.
|
||||
Der nächste logische Schritt ist die **Integration dieser Intelligenz in den visuellen Editor**. Der Editor soll nicht nur dumme Blöcke darstellen, sondern Live-Feedback (Fehler, Typen) geben, indem er die stabilen Identitäten für den "Round-Trip" nutzt.
|
||||
|
||||
### Ziel
|
||||
Herstellung einer **bidirektionalen Verbindung** zwischen dem visuellen `TAuraNode`-Graphen und dem logischen `IAstNode`-Baum.
|
||||
1. **Rekonstruktion:** Der visuelle Baum erzeugt einen logischen AST (inkl. Mapping).
|
||||
2. **Kompilierung:** Der Compiler verarbeitet den AST und liefert Fehler/Typen referenziert auf `IAstIdentity`.
|
||||
3. **Visualisierung:** Der Editor projiziert diese Informationen zurück auf die entsprechenden UI-Knoten.
|
||||
|
||||
### Ergebnis (Status Quo)
|
||||
* **Compiler Core:** Vollständig refaktoriert. Binder, TypeChecker, TCO und Specializer unterstützen `ICompilerLog` und nutzen "Poison Pills" (`Unknown`-Typen) statt Exceptions.
|
||||
* **AST Architektur:** `IAstIdentity` trennt erfolgreich Syntax-Daten von Semantik. Factories (`TAst`) erzwingen den Erhalt der Provenance (Herkunft) bei Transformationen.
|
||||
* **Editor Basis:** `Myc.Fmx.AstEditor.Node` wurde angepasst, um die neuen Factories zu nutzen. `ReconstructAst` funktioniert prinzipiell.
|
||||
|
||||
### Nächster Schritt: Implementierung der Editor-Intelligenz
|
||||
|
||||
Die Umsetzung erfolgt in drei logischen Phasen:
|
||||
|
||||
#### Phase 1: Visuelle Feedback-Mechanismen (View)
|
||||
Erweiterung von `TAuraNode` um die Fähigkeit, Status-Informationen darzustellen, ohne die Kernlogik zu überladen.
|
||||
* Implementierung von **Adorners/Decorators** für `TAuraNode`.
|
||||
* Visualisierung von **Fehlern** (z.B. roter Rahmen, Warnsymbol, Tooltip mit Fehlermeldung).
|
||||
* Visualisierung von **Typ-Informationen** (z.B. kleines Badge mit "Int64", "Series" etc.).
|
||||
* Methoden zum Setzen und Löschen dieser Zustände (`SetErrorState`, `SetTypeInfo`, `ClearStatus`).
|
||||
|
||||
#### Phase 2: Mapping-Infrastruktur (Glue Code)
|
||||
Implementierung der externen Verknüpfung zwischen Logik und UI, um den AST "rein" zu halten.
|
||||
* Definition eines `TAstMapping`-Kontextes (enthält `Dictionary<IAstIdentity, TAuraNode>`).
|
||||
* Anpassung des Rekonstruktions-Prozesses: Während `ReconstructAst` läuft, muss die Verbindung zwischen der (wiederverwendeten oder neuen) `Identity` und dem `TAuraNode` im Mapping registriert werden.
|
||||
|
||||
#### Phase 3: Der Editor-Controller (Brain)
|
||||
Erstellung einer neuen Unit `Myc.Fmx.AstEditor.Controller`, die den Workflow steuert.
|
||||
* Orchestrierung: `Workspace` -> `AST` -> `Compiler` -> `UI-Update`.
|
||||
* Verarbeitung des `ICompilerLog`: Iteration über Fehler, Lookup im Mapping, Update der UI-Nodes.
|
||||
* Verarbeitung des `TypedAst`: Extraktion von Typen für Mouse-Over oder permanente Anzeige.
|
||||
|
||||
Reference in New Issue
Block a user