Resolved circular depependancy between macro expander and binder
This commit is contained in:
@@ -560,12 +560,36 @@ end;
|
||||
function TEnvironment.ExpandMacros(const Node: IAstNode): IAstNode;
|
||||
begin
|
||||
var cExecutionStrategy := FExecutionStrategy;
|
||||
|
||||
// The Glue: This callback performs the full compilation pipeline for a macro argument expression.
|
||||
// It binds the node to the layout of the temporary macro scope and then executes it.
|
||||
var macroEvaluator: TMacroEvaluatorProc :=
|
||||
function(const Scope: IExecutionScope; const ANode: IAstNode): TDataValue
|
||||
var
|
||||
tmpLayout: IScopeLayout;
|
||||
evaluator: IEvaluatorVisitor;
|
||||
boundSubAst: IAstNode;
|
||||
scratchScope: IExecutionScope;
|
||||
begin
|
||||
// 1. Binding
|
||||
// Note: Scope is dynamic (from TMacroExpander), so Descriptor.Layout describes current variables.
|
||||
boundSubAst := TAstBinder.Bind(Scope.Descriptor.Layout, ANode, tmpLayout);
|
||||
|
||||
// 2. Scope Matching
|
||||
// Create a child scope to ensure correct depth resolution (Binder sees Layout at depth 0 relative to itself)
|
||||
scratchScope := TScope.CreateScope(Scope, nil, nil);
|
||||
|
||||
// 3. Execution
|
||||
evaluator := cExecutionStrategy.CreateVisitor(scratchScope);
|
||||
Result := evaluator.Execute(boundSubAst);
|
||||
end;
|
||||
|
||||
Result :=
|
||||
TMacroExpander.ExpandMacros(
|
||||
FMacroRegistry,
|
||||
FRootScope,
|
||||
Node,
|
||||
function(const Scope: IExecutionScope): IEvaluatorVisitor begin Result := cExecutionStrategy.CreateVisitor(Scope); end
|
||||
macroEvaluator // Injected single dependency
|
||||
);
|
||||
end;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user