Macro expander integrated in binder
This commit is contained in:
+23
-29
@@ -33,7 +33,6 @@ uses
|
||||
Myc.Ast.Binding,
|
||||
Myc.Ast.RTL,
|
||||
Myc.Ast.Script,
|
||||
Myc.Ast.MacroExpander,
|
||||
FMX.Layouts,
|
||||
FMX.Objects,
|
||||
Myc.Ast.Debugger,
|
||||
@@ -114,7 +113,7 @@ type
|
||||
FTriggerScope: IExecutionScope;
|
||||
FScriptUpdate: Boolean;
|
||||
procedure WorkspaceMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
|
||||
function CreateEvaluator(Scope: IExecutionScope): IEvaluatorVisitor;
|
||||
function CreateEvaluator(const Scope: IExecutionScope): IEvaluatorVisitor;
|
||||
// Helper function to encapsulate the Bind -> Evaluate pattern
|
||||
function ExecuteAst(const ANode: IAstNode; const AParentScope: IExecutionScope): TDataValue;
|
||||
procedure UpdateScript;
|
||||
@@ -212,31 +211,26 @@ end;
|
||||
function TForm1.ExecuteAst(const ANode: IAstNode; const AParentScope: IExecutionScope): TDataValue;
|
||||
var
|
||||
binder: IAstBinder;
|
||||
scriptScope: IExecutionScope;
|
||||
boundAst: IAstNode;
|
||||
descriptor: IScopeDescriptor;
|
||||
evalScope: IExecutionScope;
|
||||
visitor: IEvaluatorVisitor;
|
||||
begin
|
||||
var macroExpander :=
|
||||
TMacroExpander.Create(
|
||||
function(const ANode: IAstNode): TDataValue
|
||||
begin
|
||||
var binder := TAstBinder.Create(AParentScope) as IAstBinder;
|
||||
// The new, streamlined pipeline: The binder handles macro expansion internally.
|
||||
|
||||
var descriptor: IScopeDescriptor;
|
||||
var boundAst := binder.Execute(ANode, descriptor);
|
||||
// Step 1: Create a binder, passing the evaluator factory for compile-time evaluations.
|
||||
binder := TAstBinder.Create(AParentScope, CreateEvaluator);
|
||||
|
||||
var evalScope := descriptor.CreateScope(AParentScope);
|
||||
var evaluator := CreateEvaluator(evalScope);
|
||||
boundAst := binder.Execute(ANode, descriptor);
|
||||
|
||||
Result := evaluator.Execute(boundAst);
|
||||
end)
|
||||
as IMacroExpander;
|
||||
// Store the final bound AST for visualization and debugging.
|
||||
FCurrAst := ANode;
|
||||
FCurrDesc := descriptor;
|
||||
|
||||
binder := TAstBinder.Create(AParentScope);
|
||||
FCurrAst := binder.Execute(macroExpander.Execute(ANode), FCurrDesc);
|
||||
|
||||
scriptScope := FCurrDesc.CreateScope(AParentScope);
|
||||
visitor := CreateEvaluator(scriptScope);
|
||||
Result := visitor.Execute(FCurrAst);
|
||||
// Step 2: Create the final scope and evaluator for runtime execution.
|
||||
evalScope := descriptor.CreateScope(AParentScope);
|
||||
visitor := CreateEvaluator(evalScope);
|
||||
Result := visitor.Execute(boundAst);
|
||||
end;
|
||||
|
||||
procedure TForm1.FormCreate(Sender: TObject);
|
||||
@@ -307,7 +301,7 @@ begin
|
||||
)
|
||||
);
|
||||
|
||||
binder := TAstBinder.Create(Scope);
|
||||
binder := TAstBinder.Create(Scope, CreateEvaluator);
|
||||
boundSmaAst := binder.Execute(smaAst, smaDescriptor);
|
||||
|
||||
smaScope := smaDescriptor.CreateScope(Scope);
|
||||
@@ -496,7 +490,7 @@ begin
|
||||
raise EJSONParseException.Create('Invalid JSON format.');
|
||||
|
||||
try
|
||||
var binder := TAstBinder.Create(FGScope);
|
||||
var binder := TAstBinder.Create(FGScope, CreateEvaluator);
|
||||
var unboundAst := converter.Deserialize(jsonObj);
|
||||
FCurrAst := binder.Execute(unboundAst, FCurrDesc);
|
||||
Memo1.Lines.Add('AST deserialized successfully from JSON.');
|
||||
@@ -566,7 +560,7 @@ begin
|
||||
end;
|
||||
|
||||
// Re-bind the current AST against the global scope to ensure up-to-date binding info for the dump.
|
||||
binder := TAstBinder.Create(FGScope);
|
||||
binder := TAstBinder.Create(FGScope, CreateEvaluator);
|
||||
boundNode := binder.Execute(FCurrAst, FCurrDesc);
|
||||
TAstDumper.Dump(boundNode, Memo1.Lines);
|
||||
end;
|
||||
@@ -608,7 +602,7 @@ begin
|
||||
]
|
||||
);
|
||||
|
||||
binder := TAstBinder.Create(FGScope);
|
||||
binder := TAstBinder.Create(FGScope, CreateEvaluator);
|
||||
var desc: IScopeDescriptor;
|
||||
boundFibAst := binder.Execute(fibAst, desc);
|
||||
fibScope := desc.CreateScope(FGScope);
|
||||
@@ -902,7 +896,7 @@ begin
|
||||
);
|
||||
|
||||
// 1. Bind and execute the setup script.
|
||||
binder := TAstBinder.Create(FGScope);
|
||||
binder := TAstBinder.Create(FGScope, CreateEvaluator);
|
||||
boundSetupAst := binder.Execute(setupAst, setupDescriptor);
|
||||
|
||||
scope := setupDescriptor.CreateScope(FGScope);
|
||||
@@ -915,7 +909,7 @@ begin
|
||||
callAst := TAst.FunctionCall(TAst.Identifier('maCrossStrategy'), [currentSeriesIdent]);
|
||||
|
||||
// 3. Re-bind the call AST within the now-populated scope to resolve the new variable.
|
||||
binder := TAstBinder.Create(scope);
|
||||
binder := TAstBinder.Create(scope, CreateEvaluator);
|
||||
boundCallAst := binder.Execute(callAst, callDescriptor);
|
||||
|
||||
// 4. Get the address of 'current_series' from the new descriptor.
|
||||
@@ -1041,7 +1035,7 @@ begin
|
||||
]
|
||||
);
|
||||
|
||||
binder := TAstBinder.Create(FGScope);
|
||||
binder := TAstBinder.Create(FGScope, CreateEvaluator);
|
||||
FCurrAst := binder.Execute(blk, FCurrDesc);
|
||||
FTriggerScope := FCurrDesc.CreateScope(FGScope);
|
||||
|
||||
@@ -1053,7 +1047,7 @@ begin
|
||||
UpdateScript;
|
||||
end;
|
||||
|
||||
function TForm1.CreateEvaluator(Scope: IExecutionScope): IEvaluatorVisitor;
|
||||
function TForm1.CreateEvaluator(const Scope: IExecutionScope): IEvaluatorVisitor;
|
||||
begin
|
||||
if DebugBox.IsChecked then
|
||||
Result := TDebugEvaluatorVisitor.Create(Scope, Memo1.Lines, ShowScopeBox.IsChecked)
|
||||
|
||||
Reference in New Issue
Block a user