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).
TExpansionVisitor = class(TAstTransformer)
type
TEvaluateProc = reference to function(const Node: IAstNode): TDataValue;
private
FEvaluate: TEvaluateProc;
FMacroEvaluator: TMacroEvaluatorProc;
FMacroScope: IExecutionScope;
FRenameMap: TDictionary<string, string>;
class var
@@ -48,10 +46,14 @@ type
function VisitLambdaExpression(const Node: ILambdaExpressionNode): IAstNode; override;
function VisitIdentifier(const Node: IIdentifierNode): IAstNode; override;
public
constructor Create(const AMacroScope: IExecutionScope; const AEvaluate: TEvaluateProc);
constructor Create(const AMacroScope: IExecutionScope; const AMacroEvaluator: TMacroEvaluatorProc);
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;
// Handles the expansion of macro calls within the AST.
@@ -116,11 +118,11 @@ uses
{ TExpansionVisitor }
constructor TExpansionVisitor.Create(const AMacroScope: IExecutionScope; const AEvaluate: TEvaluateProc);
constructor TExpansionVisitor.Create(const AMacroScope: IExecutionScope; const AMacroEvaluator: TMacroEvaluatorProc);
begin
inherited Create;
FMacroScope := AMacroScope;
FEvaluate := AEvaluate;
FMacroEvaluator := AMacroEvaluator;
FRenameMap := TDictionary<string, string>.Create;
end;
@@ -147,10 +149,10 @@ end;
class function TExpansionVisitor.Expand(
const MacroScope: IExecutionScope;
const RootNode: IAstNode;
const AEvaluate: TEvaluateProc
const MacroEvaluator: TMacroEvaluatorProc
): IAstNode;
begin
var expander := TExpansionVisitor.Create(MacroScope, AEvaluate);
var expander := TExpansionVisitor.Create(MacroScope, MacroEvaluator);
try
Result := expander.Accept(RootNode);
finally
@@ -171,7 +173,7 @@ begin
if node.Kind = akUnquoteSplicing then
begin
var spliceExpr := node.AsUnquoteSplicing.Expression;
var evaluatedSpliceValue := FEvaluate(spliceExpr);
var evaluatedSpliceValue := FMacroEvaluator(FMacroScope, spliceExpr);
if (not evaluatedSpliceValue.IsVoid) and (evaluatedSpliceValue.Kind = vkInterface) then
begin
@@ -282,7 +284,7 @@ begin
end;
// Evaluate the expression at compile time
value := FEvaluate(expr);
value := FMacroEvaluator(FMacroScope, expr);
if value.Kind = vkInterface then
begin
@@ -438,17 +440,9 @@ begin
for i := 0 to High(params) do
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
// 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
var macroNode := TAst.MacroExpansionNode(Node, expandedBody);