Simplified macro expansion

This commit is contained in:
Michael Schimmel
2025-11-23 17:19:56 +01:00
parent 738e595f95
commit 7c761e86e5
+14 -20
View File
@@ -26,10 +26,8 @@ type
// Handles the expansion of the macro body template (Quasiquotes/Unquotes). // Handles the expansion of the macro body template (Quasiquotes/Unquotes).
TExpansionVisitor = class(TAstTransformer) TExpansionVisitor = class(TAstTransformer)
type
TEvaluateProc = reference to function(const Node: IAstNode): TDataValue;
private private
FEvaluate: TEvaluateProc; FMacroEvaluator: TMacroEvaluatorProc;
FMacroScope: IExecutionScope; FMacroScope: IExecutionScope;
FRenameMap: TDictionary<string, string>; FRenameMap: TDictionary<string, string>;
class var class var
@@ -48,10 +46,14 @@ type
function VisitLambdaExpression(const Node: ILambdaExpressionNode): IAstNode; override; function VisitLambdaExpression(const Node: ILambdaExpressionNode): IAstNode; override;
function VisitIdentifier(const Node: IIdentifierNode): IAstNode; override; function VisitIdentifier(const Node: IIdentifierNode): IAstNode; override;
public public
constructor Create(const AMacroScope: IExecutionScope; const AEvaluate: TEvaluateProc); constructor Create(const AMacroScope: IExecutionScope; const AMacroEvaluator: TMacroEvaluatorProc);
destructor Destroy; override; destructor Destroy; override;
class function Expand(const MacroScope: IExecutionScope; const RootNode: IAstNode; const AEvaluate: TEvaluateProc): IAstNode; class function Expand(
const MacroScope: IExecutionScope;
const RootNode: IAstNode;
const MacroEvaluator: TMacroEvaluatorProc
): IAstNode;
end; end;
// Handles the expansion of macro calls within the AST. // Handles the expansion of macro calls within the AST.
@@ -116,11 +118,11 @@ uses
{ TExpansionVisitor } { TExpansionVisitor }
constructor TExpansionVisitor.Create(const AMacroScope: IExecutionScope; const AEvaluate: TEvaluateProc); constructor TExpansionVisitor.Create(const AMacroScope: IExecutionScope; const AMacroEvaluator: TMacroEvaluatorProc);
begin begin
inherited Create; inherited Create;
FMacroScope := AMacroScope; FMacroScope := AMacroScope;
FEvaluate := AEvaluate; FMacroEvaluator := AMacroEvaluator;
FRenameMap := TDictionary<string, string>.Create; FRenameMap := TDictionary<string, string>.Create;
end; end;
@@ -147,10 +149,10 @@ end;
class function TExpansionVisitor.Expand( class function TExpansionVisitor.Expand(
const MacroScope: IExecutionScope; const MacroScope: IExecutionScope;
const RootNode: IAstNode; const RootNode: IAstNode;
const AEvaluate: TEvaluateProc const MacroEvaluator: TMacroEvaluatorProc
): IAstNode; ): IAstNode;
begin begin
var expander := TExpansionVisitor.Create(MacroScope, AEvaluate); var expander := TExpansionVisitor.Create(MacroScope, MacroEvaluator);
try try
Result := expander.Accept(RootNode); Result := expander.Accept(RootNode);
finally finally
@@ -171,7 +173,7 @@ begin
if node.Kind = akUnquoteSplicing then if node.Kind = akUnquoteSplicing then
begin begin
var spliceExpr := node.AsUnquoteSplicing.Expression; var spliceExpr := node.AsUnquoteSplicing.Expression;
var evaluatedSpliceValue := FEvaluate(spliceExpr); var evaluatedSpliceValue := FMacroEvaluator(FMacroScope, spliceExpr);
if (not evaluatedSpliceValue.IsVoid) and (evaluatedSpliceValue.Kind = vkInterface) then if (not evaluatedSpliceValue.IsVoid) and (evaluatedSpliceValue.Kind = vkInterface) then
begin begin
@@ -282,7 +284,7 @@ begin
end; end;
// Evaluate the expression at compile time // Evaluate the expression at compile time
value := FEvaluate(expr); value := FMacroEvaluator(FMacroScope, expr);
if value.Kind = vkInterface then if value.Kind = vkInterface then
begin begin
@@ -438,17 +440,9 @@ begin
for i := 0 to High(params) do for i := 0 to High(params) do
expansionScope.Define(params[i].Name, TDataValue.FromIntf<IAstNode>(Node.Arguments[i])); expansionScope.Define(params[i].Name, TDataValue.FromIntf<IAstNode>(Node.Arguments[i]));
// 3. Create simple callback for TExpansionVisitor
var evaluatorProc: TExpansionVisitor.TEvaluateProc :=
function(const ANodeToEvaluate: IAstNode): TDataValue
begin
// Delegate complex binding/execution logic to the environment via FMacroEvaluator
Result := FMacroEvaluator(expansionScope, ANodeToEvaluate);
end;
// 4. Expand the Macro Body // 4. Expand the Macro Body
// We assume the macro body is a Quasiquote. We expand it using the visitor. // We assume the macro body is a Quasiquote. We expand it using the visitor.
var expandedBody := TExpansionVisitor.Expand(expansionScope, macroDef.Body.AsQuasiquote.Expression, evaluatorProc); var expandedBody := TExpansionVisitor.Expand(expansionScope, macroDef.Body.AsQuasiquote.Expression, FMacroEvaluator);
// 5. Create a MacroExpansionNode to preserve source mapping // 5. Create a MacroExpansionNode to preserve source mapping
var macroNode := TAst.MacroExpansionNode(Node, expandedBody); var macroNode := TAst.MacroExpansionNode(Node, expandedBody);