Binder refactoring - extracted lowering

This commit is contained in:
Michael Schimmel
2025-11-01 14:56:38 +01:00
parent 734b7b1d5e
commit 915deb4dc0
7 changed files with 319 additions and 103 deletions
+15 -13
View File
@@ -38,13 +38,14 @@ uses
Myc.Ast.Debugger,
Myc.Fmx.AstEditor.Node,
Myc.Fmx.AstEditor.Workspace,
Myc.Ast.MacroExpander,
Myc.Ast.TypeChecker,
Myc.Ast.Lowering,
FMX.DialogService,
FMX.ListView.Types,
FMX.ListView.Appearances,
FMX.ListView.Adapters.Base,
FMX.ListView, // Added for platform-independent dialogs
Myc.Ast.MacroExpander,
Myc.Ast.TypeChecker;
FMX.ListView;
type
// A test record
@@ -121,7 +122,7 @@ type
FScriptUpdate: Boolean;
procedure WorkspaceMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
function CreateEvaluator(const Scope: IExecutionScope): IEvaluatorVisitor;
// Helper function to encapsulate the 3-stage compilation pipeline
// Helper function to encapsulate the compilation pipeline
function CompileAst(const ANode: IAstNode; const AParentScope: IExecutionScope; out ADescriptor: IScopeDescriptor): IAstNode;
// Helper function to encapsulate the Compile -> Evaluate pattern
function ExecuteAst(const ANode: IAstNode; const AParentScope: IExecutionScope): TDataValue;
@@ -213,18 +214,19 @@ end;
function TForm1.CompileAst(const ANode: IAstNode; const AParentScope: IExecutionScope; out ADescriptor: IScopeDescriptor): IAstNode;
var
macroDescriptor: IScopeDescriptor;
expandedAst, boundAst: IAstNode;
expandedAst, boundAst, typedAst: IAstNode;
begin
// Step 1: Expand macros (Phase 1)
expandedAst := TMacroExpander.ExpandMacros(AParentScope, ANode, macroDescriptor, CreateEvaluator);
// Step 2: Bind names and addresses (Phase 2)
// The binder uses the parent scope, but produces the final descriptor
boundAst := TAstBinder.Bind(AParentScope, expandedAst, ADescriptor);
// Step 3: Check and infer types (Phase 3)
// The type checker runs on the bound AST and the final descriptor
Result := TTypeChecker.CheckTypes(boundAst, ADescriptor);
typedAst := TTypeChecker.CheckTypes(boundAst, ADescriptor);
// Step 4: Lowering / Canonicalization (Phase 4)
Result := TAstLowerer.Lower(typedAst);
end;
function TForm1.ExecuteAst(const ANode: IAstNode; const AParentScope: IExecutionScope): TDataValue;
@@ -232,21 +234,21 @@ var
descriptor: IScopeDescriptor;
evalScope: IExecutionScope;
visitor: IEvaluatorVisitor;
typedAst: IAstNode;
compiledAst: IAstNode;
begin
FCurrUnboundAst := ANode;
// Call the new helper function for the 3-stage pipeline
typedAst := CompileAst(ANode, AParentScope, descriptor);
// Call the helper function for the full 4-stage pipeline
compiledAst := CompileAst(ANode, AParentScope, descriptor);
// Store the final bound AST for visualization and debugging.
FCurrAst := typedAst;
FCurrAst := compiledAst; // <-- Store the fully compiled AST
FCurrDesc := descriptor;
// Create the final scope and evaluator for runtime execution.
evalScope := descriptor.CreateScope(AParentScope);
visitor := CreateEvaluator(evalScope);
Result := visitor.Execute(typedAst);
Result := visitor.Execute(compiledAst);
end;
procedure TForm1.FormCreate(Sender: TObject);