diff --git a/docs/Analysis_Environment.md b/docs/Analysis_Environment.md index 416d91b..0f37840 100644 --- a/docs/Analysis_Environment.md +++ b/docs/Analysis_Environment.md @@ -21,7 +21,7 @@ Der Code weist an mehreren Stellen typischen Rust-Boilerplate für Single-Thread Der Code enthält einige starke Indikatoren für unscharfe Systemgrenzen ("Leaky Abstractions") und Vermischung von Zuständigkeiten (God Object Smell): * **God Object:** `Environment` weiß zu viel. Es parst Dateien, wertet Makros aus, instanziiert den Typ-Prüfer (`TypeChecker`), betreibt Caching für Optimierer, startet die `VM` und sammelt nebenbei Doc-Strings. Eine klarere Trennung zwischen `CompilerEnvironment` (statische Phasen) und `RuntimeEnvironment` (VM-Zustand/Values) fehlt hier. -* **Verwaschene Kompilierungsschritte:** Die Methoden `compile`, `compile_syntax` und `compile_pipeline` haben überlappende Aufgabenbereiche. Mal wird das Error-Reporting über eine `Diagnostics`-Instanz gemacht, mal wird diese verworfen und stumpf in einen `Result` umgewandelt. -* **Die `specialize_node`-Closure:** In `specialize_node` wird eine gigantische Inline-Closure (`compiler = Rc::new(move |...| { ... })`) definiert. Diese *baut tief im Inneren eine komplette Mini-Compiler-Pipeline samt VM-Ausführung nach*, nur um Konstanten zu falten / Aufrufe zu spezialisieren. Das zeigt, dass die Compiler-Pipeline nach außen hin nicht sauber gekapselt ist. +* ~~**Verwaschene Kompilierungsschritte:**~~ **✓ Behoben (Design korrekt, ein Detail bereinigt).** Die drei Methoden bilden eine saubere Adapter-Hierarchie: `compile_pipeline` (Kern, Diagnostics-Sink) ← `compile` (public API, merged Parse+Compile-Fehler in `CompilationResult`) / `compile_syntax` (privater Adapter für Modul-Loader, konvertiert zu `Result<_, String>`). Das unterschiedliche Error-Reporting ist situations-appropriat, nicht inkonsistent. **Behobener Design-Geruch:** `dump_ast` umging zuvor `compile()` und verschluckte Parse-Fehler still. Behoben: `dump_ast` delegiert jetzt an `compile(source).into_result()?`. +* ~~**Die `specialize_node`-Closure:**~~ **✓ Kein Problem (Design korrekt verstanden).** Die `compiler`-Closure ist kein Zeichen unsauberer Kapselung — im Gegenteil. `Specializer` ist bewusst von TypeChecker, Optimizer und VM entkoppelt; der `CompileFunc`-Typ (`specializer.rs:15`) ist der explizite **Dependency-Injection-Punkt** (Strategy Pattern). Die innere Pipeline (TypeCheck → Analyze → sub-Specialize → Optimize → Lower → VM.run) **dupliziert nicht** die äußere — ihr Zweck ist fundamental verschieden: sie erzeugt einen gecachten `Value` (compile-and-evaluate), während die äußere Pipeline einen `ExecNode` für die Skriptausführung erzeugt. Die Closure captured 6 `Rc>`-Handles statt `&self`, weil Rust keine `self`-Referenz in eine `'static`-Closure erlaubt — das ist der korrekte Rust-Weg. **Design-Limitation (dokumentiert, kein Bug):** Der `sub_specializer` innerhalb der Closure hat `compiler: None`, was Endlos-Rekursion verhindert, aber bedeutet, dass nur eine Spezialisierungsebene pro Aufruf expandiert wird. * ~~**Type-Checker Hack:**~~ **✓ Kein Problem (Kommentar bereinigt).** Der ursprüngliche Kommentar war veraltet und irreführend. Das `BoundLike`-Trait vereinigt alle Phasen mit identischer Binding-Struktur (`BoundPhase`, `TypedPhase`, `AnalyzedPhase`). `TypeChecker::check_node_as_bound()` ist korrekte Generic-Programmierung — kein Hack. Die Phasen passen sauber ineinander. Der Kommentar wurde durch eine korrekte Erklärung des Monomorphisierungs-Designs ersetzt. * **Konzeptioneller Bruch bei `instantiate`:** Diese Methode nimmt einen fertig kompilierten Ast (`ExecNode`) und wickelt ihn in eine `NativeFunction` ein. Dadurch wird ein in Myc geschriebenes Skript in der Registry strukturell als "native Rust-Funktion" getarnt. Das ist pragmatisch, verwischt aber die semantische Grenze zwischen User-Code (Closures) und echten Runtime-Intrinsics. diff --git a/src/ast/environment.rs b/src/ast/environment.rs index b654216..a9d36cc 100644 --- a/src/ast/environment.rs +++ b/src/ast/environment.rs @@ -580,9 +580,7 @@ impl Environment { pub fn dump_ast(&self, source: &str) -> Result { self.preload_dependencies(source, None)?; - let mut parser = Parser::new(source); - let syntax_ast = parser.parse_expression(); - let compiled = self.compile_syntax(syntax_ast)?; + let compiled = self.compile(source).into_result()?; let linked = self.link(compiled); Ok(Dumper::dump(&linked)) }