Fixed macro def expansion

This commit is contained in:
Michael Schimmel
2025-11-05 10:39:15 +01:00
parent edd3e83377
commit 60358365cd
6 changed files with 11 additions and 53 deletions
+3 -17
View File
@@ -236,23 +236,9 @@ object Form1: TForm1
DataDetectorTypes = []
Lines.Strings = (
'(do'
'(defmacro repeat [n body]'
' `(do'
' (def loop (fn [counter]'
' (if (> counter 0)'
' (do'
' ~body'
' (recur (- counter 1))'
' )'
' (do'
' )'
' )'
' ))'
' (loop ~n)'
' )'
')'
''
'(repeat 5 "hi")'
'(defmacro test [body] `(fn [] ~body ))'
'(defmacro test2 [body] `(fn [] ~body ))'
'(test2 "hi")'
')')
StyledSettings = [Size, Style, FontColor]
TextSettings.Font.Family = 'Consolas'
-17
View File
@@ -46,8 +46,6 @@ type
// --- Standard Traversal (Use inherited) ---
function VisitKeyword(const Node: IKeywordNode): IAstNode; override;
function VisitMacroDefinition(const Node: IMacroDefinitionNode): IAstNode; override;
function VisitMacroExpansionNode(const Node: IMacroExpansionNode): IAstNode; override;
function VisitRecurNode(const Node: IRecurNode): IAstNode; override;
function VisitConstant(const Node: IConstantNode): IAstNode; override;
function VisitCreateSeries(const Node: ICreateSeriesNode): IAstNode; override;
@@ -171,21 +169,6 @@ begin
end;
end;
function TAstBinder.VisitMacroDefinition(const Node: IMacroDefinitionNode): IAstNode;
begin
// Macros are compile-time only. The Binder (Phase 2) should not see them.
raise Exception.Create('TMyAstBinder: MacroDefinition node encountered.');
end;
function TAstBinder.VisitMacroExpansionNode(const Node: IMacroExpansionNode): IAstNode;
begin
// The MacroExpander (Phase 1) created this node.
// We must bind the ExpandedBody, but keep the MacroExpansionNode wrapper.
// The base TAstTransformer implementation already does exactly this
// by visiting Callee, Arguments, and ExpandedBody.
Result := inherited VisitMacroExpansionNode(Node);
end;
function TAstBinder.VisitFunctionCall(const Node: IFunctionCallNode): IAstNode;
begin
// --- Transformation: Keyword-as-Function ---
+4 -4
View File
@@ -249,10 +249,10 @@ end;
function TEvaluatorVisitor.VisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue;
begin
// Macro definitions are compile-time constructs and should have been
// processed and removed from the AST by the TMacroExpander.
// If we encounter one here, it's a compiler pipeline error.
raise Exception.Create('Macro definitions cannot be evaluated at runtime.');
// Macro definitions are compile-time constructs.
// The MacroExpander leaves them in the AST for the Visualizer.
// The Evaluator must simply ignore them.
Result := TDataValue.Void;
end;
function TEvaluatorVisitor.VisitQuasiquote(const Node: IQuasiquoteNode): TDataValue;
+3 -2
View File
@@ -259,8 +259,9 @@ function TMacroExpander.VisitMacroDefinition(const Node: IMacroDefinitionNode):
begin
// Register the macro in the current descriptor
FCurrentDescriptor.DefineMacro(Node.Name.Name, Node);
// Remove the (defmacro ...) node from the AST; it's compile-time only.
Result := nil;
// Keep the node in the AST (for the visualizer).
Result := Node;
end;
function TMacroExpander.VisitFunctionCall(const Node: IFunctionCallNode): IAstNode;
-7
View File
@@ -50,8 +50,6 @@ type
function VisitConstant(const Node: IConstantNode): IAstNode; override;
function VisitKeyword(const Node: IKeywordNode): IAstNode; override;
// Compile-time nodes (should not be present)
function VisitMacroDefinition(const Node: IMacroDefinitionNode): IAstNode; override;
public
constructor Create(const ADescriptor: IScopeDescriptor);
function Execute(const RootNode: IAstNode; const ADescriptor: IScopeDescriptor): IAstNode;
@@ -142,11 +140,6 @@ begin
Result := TRecurNode.Create(newArgs, TTypes.Void);
end;
function TTypeChecker.VisitMacroDefinition(const Node: IMacroDefinitionNode): IAstNode;
begin
raise Exception.Create('TTypeChecker: MacroDefinition node encountered.');
end;
function TTypeChecker.VisitVariableDeclaration(const Node: IVariableDeclarationNode): IAstNode;
var
initType: IStaticType;
+1 -6
View File
@@ -543,13 +543,8 @@ begin
end;
function TAstTransformer.VisitMacroDefinition(const Node: IMacroDefinitionNode): IAstNode;
var
N: TMacroDefinitionNode;
begin
N := (Node as TMacroDefinitionNode);
N.Name := Accept(N.Name).AsIdentifier;
N.Parameters := AcceptParameters(N.Parameters);
N.Body := Accept(N.Body);
// Do nothing, just pass the node through
Result := Node;
end;