unit Myc.Ast.Visitor; interface uses System.SysUtils, System.Generics.Collections, Myc.Data.Value, Myc.Ast, Myc.Ast.Nodes; type TAstVisitor = class abstract(TInterfacedObject, IAstVisitor) strict private // IAstVisitor explicit implementation (bridge methods) function IAstVisitor.VisitConstant = DoVisitConstant; function IAstVisitor.VisitIdentifier = DoVisitIdentifier; function IAstVisitor.VisitKeyword = DoVisitKeyword; function IAstVisitor.VisitBinaryExpression = DoVisitBinaryExpression; function IAstVisitor.VisitUnaryExpression = DoVisitUnaryExpression; function IAstVisitor.VisitIfExpression = DoVisitIfExpression; function IAstVisitor.VisitTernaryExpression = DoVisitTernaryExpression; function IAstVisitor.VisitLambdaExpression = DoVisitLambdaExpression; function IAstVisitor.VisitFunctionCall = DoVisitFunctionCall; function IAstVisitor.VisitMacroExpansionNode = DoVisitMacroExpansionNode; function IAstVisitor.VisitBlockExpression = DoVisitBlockExpression; function IAstVisitor.VisitVariableDeclaration = DoVisitVariableDeclaration; function IAstVisitor.VisitAssignment = DoVisitAssignment; function IAstVisitor.VisitMacroDefinition = DoVisitMacroDefinition; function IAstVisitor.VisitQuasiquote = DoVisitQuasiquote; function IAstVisitor.VisitUnquote = DoVisitUnquote; function IAstVisitor.VisitUnquoteSplicing = DoVisitUnquoteSplicing; function IAstVisitor.VisitIndexer = DoVisitIndexer; function IAstVisitor.VisitMemberAccess = DoVisitMemberAccess; function IAstVisitor.VisitRecordLiteral = DoVisitRecordLiteral; function IAstVisitor.VisitCreateSeries = DoVisitCreateSeries; function IAstVisitor.VisitAddSeriesItem = DoVisitAddSeriesItem; function IAstVisitor.VisitSeriesLength = DoVisitSeriesLength; function IAstVisitor.VisitRecurNode = DoVisitRecurNode; function IAstVisitor.VisitNop = DoVisitNop; // Added Nop // Private bridge method implementations function DoVisitConstant(const Node: IConstantNode): TDataValue; function DoVisitIdentifier(const Node: IIdentifierNode): TDataValue; function DoVisitKeyword(const Node: IKeywordNode): TDataValue; function DoVisitBinaryExpression(const Node: IBinaryExpressionNode): TDataValue; function DoVisitUnaryExpression(const Node: IUnaryExpressionNode): TDataValue; function DoVisitIfExpression(const Node: IIfExpressionNode): TDataValue; function DoVisitTernaryExpression(const Node: ITernaryExpressionNode): TDataValue; function DoVisitLambdaExpression(const Node: ILambdaExpressionNode): TDataValue; function DoVisitFunctionCall(const Node: IFunctionCallNode): TDataValue; function DoVisitMacroExpansionNode(const Node: IMacroExpansionNode): TDataValue; function DoVisitBlockExpression(const Node: IBlockExpressionNode): TDataValue; function DoVisitVariableDeclaration(const Node: IVariableDeclarationNode): TDataValue; function DoVisitAssignment(const Node: IAssignmentNode): TDataValue; function DoVisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue; function DoVisitQuasiquote(const Node: IQuasiquoteNode): TDataValue; function DoVisitUnquote(const Node: IUnquoteNode): TDataValue; function DoVisitUnquoteSplicing(const Node: IUnquoteSplicingNode): TDataValue; function DoVisitIndexer(const Node: IIndexerNode): TDataValue; function DoVisitMemberAccess(const Node: IMemberAccessNode): TDataValue; function DoVisitRecordLiteral(const Node: IRecordLiteralNode): TDataValue; function DoVisitCreateSeries(const Node: ICreateSeriesNode): TDataValue; function DoVisitAddSeriesItem(const Node: IAddSeriesItemNode): TDataValue; function DoVisitSeriesLength(const Node: ISeriesLengthNode): TDataValue; function DoVisitRecurNode(const Node: IRecurNode): TDataValue; function DoVisitNop(const Node: INopNode): TDataValue; // Added Nop protected // Visit a node. function Accept(const Node: IAstNode): T; virtual; function VisitConstant(const Node: IConstantNode): T; virtual; abstract; function VisitIdentifier(const Node: IIdentifierNode): T; virtual; abstract; function VisitKeyword(const Node: IKeywordNode): T; virtual; abstract; function VisitBinaryExpression(const Node: IBinaryExpressionNode): T; virtual; abstract; function VisitUnaryExpression(const Node: IUnaryExpressionNode): T; virtual; abstract; function VisitIfExpression(const Node: IIfExpressionNode): T; virtual; abstract; function VisitTernaryExpression(const Node: ITernaryExpressionNode): T; virtual; abstract; function VisitLambdaExpression(const Node: ILambdaExpressionNode): T; virtual; abstract; function VisitFunctionCall(const Node: IFunctionCallNode): T; virtual; abstract; function VisitMacroExpansionNode(const Node: IMacroExpansionNode): T; virtual; abstract; function VisitBlockExpression(const Node: IBlockExpressionNode): T; virtual; abstract; function VisitVariableDeclaration(const Node: IVariableDeclarationNode): T; virtual; abstract; function VisitAssignment(const Node: IAssignmentNode): T; virtual; abstract; function VisitMacroDefinition(const Node: IMacroDefinitionNode): T; virtual; abstract; function VisitQuasiquote(const Node: IQuasiquoteNode): T; virtual; abstract; function VisitUnquote(const Node: IUnquoteNode): T; virtual; abstract; function VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): T; virtual; abstract; function VisitIndexer(const Node: IIndexerNode): T; virtual; abstract; function VisitMemberAccess(const Node: IMemberAccessNode): T; virtual; abstract; function VisitRecordLiteral(const Node: IRecordLiteralNode): T; virtual; abstract; function VisitCreateSeries(const Node: ICreateSeriesNode): T; virtual; abstract; function VisitAddSeriesItem(const Node: IAddSeriesItemNode): T; virtual; abstract; function VisitSeriesLength(const Node: ISeriesLengthNode): T; virtual; abstract; function VisitRecurNode(const Node: IRecurNode): T; virtual; abstract; function VisitNop(const Node: INopNode): T; virtual; abstract; // Added Nop end; TAstTransformer = class abstract(TAstVisitor) protected function AcceptParameters(const Nodes: TArray): TArray; function AcceptNodes(const Nodes: TArray): TArray; function VisitConstant(const Node: IConstantNode): IAstNode; override; function VisitIdentifier(const Node: IIdentifierNode): IAstNode; override; function VisitKeyword(const Node: IKeywordNode): IAstNode; override; function VisitBinaryExpression(const Node: IBinaryExpressionNode): IAstNode; override; function VisitUnaryExpression(const Node: IUnaryExpressionNode): IAstNode; override; function VisitIfExpression(const Node: IIfExpressionNode): IAstNode; override; function VisitTernaryExpression(const Node: ITernaryExpressionNode): IAstNode; override; function VisitLambdaExpression(const Node: ILambdaExpressionNode): IAstNode; override; function VisitFunctionCall(const Node: IFunctionCallNode): IAstNode; override; function VisitMacroExpansionNode(const Node: IMacroExpansionNode): IAstNode; override; function VisitBlockExpression(const Node: IBlockExpressionNode): IAstNode; override; function VisitVariableDeclaration(const Node: IVariableDeclarationNode): IAstNode; override; function VisitAssignment(const Node: IAssignmentNode): IAstNode; override; function VisitMacroDefinition(const Node: IMacroDefinitionNode): IAstNode; override; function VisitQuasiquote(const Node: IQuasiquoteNode): IAstNode; override; function VisitUnquote(const Node: IUnquoteNode): IAstNode; override; function VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): IAstNode; override; function VisitIndexer(const Node: IIndexerNode): IAstNode; override; function VisitMemberAccess(const Node: IMemberAccessNode): IAstNode; override; function VisitRecordLiteral(const Node: IRecordLiteralNode): IAstNode; override; function VisitCreateSeries(const Node: ICreateSeriesNode): IAstNode; override; function VisitAddSeriesItem(const Node: IAddSeriesItemNode): IAstNode; override; function VisitSeriesLength(const Node: ISeriesLengthNode): IAstNode; override; function VisitRecurNode(const Node: IRecurNode): IAstNode; override; function VisitNop(const Node: INopNode): IAstNode; override; // Added Nop end; TAstVisitor = class abstract(TInterfacedObject, IAstVisitor) strict private // IAstVisitor explicit implementation (bridge methods) function IAstVisitor.VisitConstant = DoVisitConstant; function IAstVisitor.VisitIdentifier = DoVisitIdentifier; function IAstVisitor.VisitKeyword = DoVisitKeyword; function IAstVisitor.VisitBinaryExpression = DoVisitBinaryExpression; function IAstVisitor.VisitUnaryExpression = DoVisitUnaryExpression; function IAstVisitor.VisitIfExpression = DoVisitIfExpression; function IAstVisitor.VisitTernaryExpression = DoVisitTernaryExpression; function IAstVisitor.VisitLambdaExpression = DoVisitLambdaExpression; function IAstVisitor.VisitFunctionCall = DoVisitFunctionCall; function IAstVisitor.VisitMacroExpansionNode = DoVisitMacroExpansionNode; function IAstVisitor.VisitBlockExpression = DoVisitBlockExpression; function IAstVisitor.VisitVariableDeclaration = DoVisitVariableDeclaration; function IAstVisitor.VisitAssignment = DoVisitAssignment; function IAstVisitor.VisitMacroDefinition = DoVisitMacroDefinition; function IAstVisitor.VisitQuasiquote = DoVisitQuasiquote; function IAstVisitor.VisitUnquote = DoVisitUnquote; function IAstVisitor.VisitUnquoteSplicing = DoVisitUnquoteSplicing; function IAstVisitor.VisitIndexer = DoVisitIndexer; function IAstVisitor.VisitMemberAccess = DoVisitMemberAccess; function IAstVisitor.VisitRecordLiteral = DoVisitRecordLiteral; function IAstVisitor.VisitCreateSeries = DoVisitCreateSeries; function IAstVisitor.VisitAddSeriesItem = DoVisitAddSeriesItem; function IAstVisitor.VisitSeriesLength = DoVisitSeriesLength; function IAstVisitor.VisitRecurNode = DoVisitRecurNode; function IAstVisitor.VisitNop = DoVisitNop; // Added Nop // Private bridge method implementations function DoVisitConstant(const Node: IConstantNode): TDataValue; function DoVisitIdentifier(const Node: IIdentifierNode): TDataValue; function DoVisitKeyword(const Node: IKeywordNode): TDataValue; function DoVisitBinaryExpression(const Node: IBinaryExpressionNode): TDataValue; function DoVisitUnaryExpression(const Node: IUnaryExpressionNode): TDataValue; function DoVisitIfExpression(const Node: IIfExpressionNode): TDataValue; function DoVisitTernaryExpression(const Node: ITernaryExpressionNode): TDataValue; function DoVisitLambdaExpression(const Node: ILambdaExpressionNode): TDataValue; function DoVisitFunctionCall(const Node: IFunctionCallNode): TDataValue; function DoVisitMacroExpansionNode(const Node: IMacroExpansionNode): TDataValue; function DoVisitBlockExpression(const Node: IBlockExpressionNode): TDataValue; function DoVisitVariableDeclaration(const Node: IVariableDeclarationNode): TDataValue; function DoVisitAssignment(const Node: IAssignmentNode): TDataValue; function DoVisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue; function DoVisitQuasiquote(const Node: IQuasiquoteNode): TDataValue; function DoVisitUnquote(const Node: IUnquoteNode): TDataValue; function DoVisitUnquoteSplicing(const Node: IUnquoteSplicingNode): TDataValue; function DoVisitIndexer(const Node: IIndexerNode): TDataValue; function DoVisitMemberAccess(const Node: IMemberAccessNode): TDataValue; function DoVisitRecordLiteral(const Node: IRecordLiteralNode): TDataValue; function DoVisitCreateSeries(const Node: ICreateSeriesNode): TDataValue; function DoVisitAddSeriesItem(const Node: IAddSeriesItemNode): TDataValue; function DoVisitSeriesLength(const Node: ISeriesLengthNode): TDataValue; function DoVisitRecurNode(const Node: IRecurNode): TDataValue; function DoVisitNop(const Node: INopNode): TDataValue; // Added Nop protected // Virtual procedures for descendants (Interpreters/Side-effects) to override procedure VisitConstant(const Node: IConstantNode); virtual; abstract; procedure VisitIdentifier(const Node: IIdentifierNode); virtual; abstract; procedure VisitKeyword(const Node: IKeywordNode); virtual; abstract; procedure VisitBinaryExpression(const Node: IBinaryExpressionNode); virtual; abstract; procedure VisitUnaryExpression(const Node: IUnaryExpressionNode); virtual; abstract; procedure VisitIfExpression(const Node: IIfExpressionNode); virtual; abstract; procedure VisitTernaryExpression(const Node: ITernaryExpressionNode); virtual; abstract; procedure VisitLambdaExpression(const Node: ILambdaExpressionNode); virtual; abstract; procedure VisitFunctionCall(const Node: IFunctionCallNode); virtual; abstract; procedure VisitMacroExpansionNode(const Node: IMacroExpansionNode); virtual; abstract; procedure VisitBlockExpression(const Node: IBlockExpressionNode); virtual; abstract; procedure VisitVariableDeclaration(const Node: IVariableDeclarationNode); virtual; abstract; procedure VisitAssignment(const Node: IAssignmentNode); virtual; abstract; procedure VisitMacroDefinition(const Node: IMacroDefinitionNode); virtual; abstract; procedure VisitQuasiquote(const Node: IQuasiquoteNode); virtual; abstract; procedure VisitUnquote(const Node: IUnquoteNode); virtual; abstract; procedure VisitUnquoteSplicing(const Node: IUnquoteSplicingNode); virtual; abstract; procedure VisitIndexer(const Node: IIndexerNode); virtual; abstract; procedure VisitMemberAccess(const Node: IMemberAccessNode); virtual; abstract; procedure VisitRecordLiteral(const Node: IRecordLiteralNode); virtual; abstract; procedure VisitCreateSeries(const Node: ICreateSeriesNode); virtual; abstract; procedure VisitAddSeriesItem(const Node: IAddSeriesItemNode); virtual; abstract; procedure VisitSeriesLength(const Node: ISeriesLengthNode); virtual; abstract; procedure VisitRecurNode(const Node: IRecurNode); virtual; abstract; procedure VisitNop(const Node: INopNode); virtual; abstract; // Added Nop end; implementation { TAstVisitor } function TAstVisitor.Accept(const Node: IAstNode): T; begin if Assigned(Node) then Result := Node.Accept(Self).AsGeneric else Result := Default(T); end; { TAstVisitor } function TAstVisitor.DoVisitConstant(const Node: IConstantNode): TDataValue; begin Result := TDataValue.FromGeneric(VisitConstant(Node)); end; function TAstVisitor.DoVisitIdentifier(const Node: IIdentifierNode): TDataValue; begin Result := TDataValue.FromGeneric(VisitIdentifier(Node)); end; function TAstVisitor.DoVisitKeyword(const Node: IKeywordNode): TDataValue; begin Result := TDataValue.FromGeneric(VisitKeyword(Node)); end; function TAstVisitor.DoVisitBinaryExpression(const Node: IBinaryExpressionNode): TDataValue; begin Result := TDataValue.FromGeneric(VisitBinaryExpression(Node)); end; function TAstVisitor.DoVisitUnaryExpression(const Node: IUnaryExpressionNode): TDataValue; begin Result := TDataValue.FromGeneric(VisitUnaryExpression(Node)); end; function TAstVisitor.DoVisitIfExpression(const Node: IIfExpressionNode): TDataValue; begin Result := TDataValue.FromGeneric(VisitIfExpression(Node)); end; function TAstVisitor.DoVisitTernaryExpression(const Node: ITernaryExpressionNode): TDataValue; begin Result := TDataValue.FromGeneric(VisitTernaryExpression(Node)); end; function TAstVisitor.DoVisitLambdaExpression(const Node: ILambdaExpressionNode): TDataValue; begin Result := TDataValue.FromGeneric(VisitLambdaExpression(Node)); end; function TAstVisitor.DoVisitFunctionCall(const Node: IFunctionCallNode): TDataValue; begin Result := TDataValue.FromGeneric(VisitFunctionCall(Node)); end; function TAstVisitor.DoVisitMacroExpansionNode(const Node: IMacroExpansionNode): TDataValue; begin Result := TDataValue.FromGeneric(VisitMacroExpansionNode(Node)); end; function TAstVisitor.DoVisitBlockExpression(const Node: IBlockExpressionNode): TDataValue; begin Result := TDataValue.FromGeneric(VisitBlockExpression(Node)); end; function TAstVisitor.DoVisitVariableDeclaration(const Node: IVariableDeclarationNode): TDataValue; begin Result := TDataValue.FromGeneric(VisitVariableDeclaration(Node)); end; function TAstVisitor.DoVisitAssignment(const Node: IAssignmentNode): TDataValue; begin Result := TDataValue.FromGeneric(VisitAssignment(Node)); end; function TAstVisitor.DoVisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue; begin Result := TDataValue.FromGeneric(VisitMacroDefinition(Node)); end; function TAstVisitor.DoVisitQuasiquote(const Node: IQuasiquoteNode): TDataValue; begin Result := TDataValue.FromGeneric(VisitQuasiquote(Node)); end; function TAstVisitor.DoVisitUnquote(const Node: IUnquoteNode): TDataValue; begin Result := TDataValue.FromGeneric(VisitUnquote(Node)); end; function TAstVisitor.DoVisitUnquoteSplicing(const Node: IUnquoteSplicingNode): TDataValue; begin Result := TDataValue.FromGeneric(VisitUnquoteSplicing(Node)); end; function TAstVisitor.DoVisitIndexer(const Node: IIndexerNode): TDataValue; begin Result := TDataValue.FromGeneric(VisitIndexer(Node)); end; function TAstVisitor.DoVisitMemberAccess(const Node: IMemberAccessNode): TDataValue; begin Result := TDataValue.FromGeneric(VisitMemberAccess(Node)); end; function TAstVisitor.DoVisitRecordLiteral(const Node: IRecordLiteralNode): TDataValue; begin Result := TDataValue.FromGeneric(VisitRecordLiteral(Node)); end; function TAstVisitor.DoVisitCreateSeries(const Node: ICreateSeriesNode): TDataValue; begin Result := TDataValue.FromGeneric(VisitCreateSeries(Node)); end; function TAstVisitor.DoVisitAddSeriesItem(const Node: IAddSeriesItemNode): TDataValue; begin Result := TDataValue.FromGeneric(VisitAddSeriesItem(Node)); end; function TAstVisitor.DoVisitSeriesLength(const Node: ISeriesLengthNode): TDataValue; begin Result := TDataValue.FromGeneric(VisitSeriesLength(Node)); end; function TAstVisitor.DoVisitRecurNode(const Node: IRecurNode): TDataValue; begin Result := TDataValue.FromGeneric(VisitRecurNode(Node)); end; function TAstVisitor.DoVisitNop(const Node: INopNode): TDataValue; begin // Added Nop implementation Result := TDataValue.FromGeneric(VisitNop(Node)); end; function TAstTransformer.AcceptParameters(const Nodes: TArray): TArray; var i: Integer; begin SetLength(Result, Length(Nodes)); for i := 0 to High(Nodes) do Result[i] := Accept(Nodes[i]).AsIdentifier; end; function TAstTransformer.AcceptNodes(const Nodes: TArray): TArray; var i: Integer; newNode: IAstNode; // Changed from TDataValue newList: TList; // Used if nodes are removed (e.g. defmacro) begin Result := Nodes; // Assume no changes newList := nil; for i := 0 to High(Nodes) do begin newNode := Accept(Nodes[i]); // Calls new Accept, returns IAstNode (or nil) if not Assigned(newNode) then // Node was removed (e.g. defmacro) begin if newList = nil then // First change begin newList := TList.Create; for var j := 0 to i - 1 do newList.Add(Nodes[j]); end; // else: just skip adding it end else begin if newNode <> Nodes[i] then // Node was replaced begin if newList = nil then // First change begin newList := TList.Create; for var j := 0 to i - 1 do newList.Add(Nodes[j]); end; newList.Add(newNode); end else begin if newList <> nil then // No change, but we are already copying newList.Add(Nodes[i]); end; end; end; if newList <> nil then begin Result := newList.ToArray; newList.Free; end; end; // --- Base Virtual Implementations (IAstNode-based) --- // --- Implemented with traversal logic from old TAstTransformer --- function TAstTransformer.VisitConstant(const Node: IConstantNode): IAstNode; begin Result := Node; // Leaf node end; function TAstTransformer.VisitIdentifier(const Node: IIdentifierNode): IAstNode; begin Result := Node; // Leaf node end; function TAstTransformer.VisitKeyword(const Node: IKeywordNode): IAstNode; begin Result := Node; // Leaf node end; function TAstTransformer.VisitNop(const Node: INopNode): IAstNode; begin // Added Nop implementation Result := Node; // Leaf node end; function TAstTransformer.VisitBinaryExpression(const Node: IBinaryExpressionNode): IAstNode; var N: TBinaryExpressionNode; begin N := (Node as TBinaryExpressionNode); N.Left := Accept(N.Left); N.Right := Accept(N.Right); Result := Node; end; function TAstTransformer.VisitUnaryExpression(const Node: IUnaryExpressionNode): IAstNode; var N: TUnaryExpressionNode; begin N := (Node as TUnaryExpressionNode); N.Right := Accept(N.Right); Result := Node; end; function TAstTransformer.VisitIfExpression(const Node: IIfExpressionNode): IAstNode; var N: TIfExpressionNode; begin N := (Node as TIfExpressionNode); N.Condition := Accept(N.Condition); N.ThenBranch := Accept(N.ThenBranch); N.ElseBranch := Accept(N.ElseBranch); // Accept handles nil Result := Node; end; function TAstTransformer.VisitTernaryExpression(const Node: ITernaryExpressionNode): IAstNode; var N: TTernaryExpressionNode; begin N := (Node as TTernaryExpressionNode); N.Condition := Accept(N.Condition); N.ThenBranch := Accept(N.ThenBranch); N.ElseBranch := Accept(N.ElseBranch); Result := Node; end; function TAstTransformer.VisitLambdaExpression(const Node: ILambdaExpressionNode): IAstNode; var N: TLambdaExpressionNode; begin N := (Node as TLambdaExpressionNode); N.Parameters := AcceptParameters(N.Parameters); N.Body := Accept(N.Body); Result := Node; end; function TAstTransformer.VisitFunctionCall(const Node: IFunctionCallNode): IAstNode; var N: TFunctionCallNode; begin N := (Node as TFunctionCallNode); N.Callee := Accept(N.Callee); N.Arguments := AcceptNodes(N.Arguments); Result := Node; end; function TAstTransformer.VisitMacroExpansionNode(const Node: IMacroExpansionNode): IAstNode; var N: TMacroExpansionNode; begin N := (Node as TMacroExpansionNode); // ONLY visit the expanded body, as this is the "real" AST node. N.ExpandedBody := Accept(N.ExpandedBody); // Callee and Arguments are metadata for the visualizer and must NOT be visited // by subsequent phases (Binder, TypeChecker, etc.). Result := Node; // Return the (mutated) wrapper end; function TAstTransformer.VisitBlockExpression(const Node: IBlockExpressionNode): IAstNode; var N: TBlockExpressionNode; begin N := (Node as TBlockExpressionNode); N.Expressions := AcceptNodes(N.Expressions); Result := Node; end; function TAstTransformer.VisitVariableDeclaration(const Node: IVariableDeclarationNode): IAstNode; var N: TVariableDeclarationNode; begin N := (Node as TVariableDeclarationNode); N.Identifier := Accept(N.Identifier).AsIdentifier; N.Initializer := Accept(N.Initializer); // Accept handles nil Result := Node; end; function TAstTransformer.VisitAssignment(const Node: IAssignmentNode): IAstNode; var N: TAssignmentNode; begin N := (Node as TAssignmentNode); N.Value := Accept(N.Value); N.Identifier := Accept(N.Identifier).AsIdentifier; Result := Node; 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); Result := Node; end; function TAstTransformer.VisitQuasiquote(const Node: IQuasiquoteNode): IAstNode; var N: TQuasiquoteNode; begin N := (Node as TQuasiquoteNode); N.Expression := Accept(N.Expression); Result := Node; end; function TAstTransformer.VisitUnquote(const Node: IUnquoteNode): IAstNode; var N: TUnquoteNode; begin N := (Node as TUnquoteNode); N.Expression := Accept(N.Expression); Result := Node; end; function TAstTransformer.VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): IAstNode; var N: TUnquoteSplicingNode; begin N := (Node as TUnquoteSplicingNode); N.Expression := Accept(N.Expression).AsQuasiquote; Result := Node; end; function TAstTransformer.VisitIndexer(const Node: IIndexerNode): IAstNode; var N: TIndexerNode; begin N := (Node as TIndexerNode); N.Base := Accept(N.Base); N.Index := Accept(N.Index); Result := Node; end; function TAstTransformer.VisitMemberAccess(const Node: IMemberAccessNode): IAstNode; var N: TMemberAccessNode; begin N := (Node as TMemberAccessNode); N.Base := Accept(N.Base); N.Member := Accept(N.Member).AsKeyword; Result := Node; end; function TAstTransformer.VisitRecordLiteral(const Node: IRecordLiteralNode): IAstNode; var N: TRecordLiteralNode; i: Integer; newFields: TArray; begin N := (Node as TRecordLiteralNode); // TRecordFieldLiteral ist ein Record, kein IAstNode, wir müssen manuell traversieren SetLength(newFields, Length(N.Fields)); for i := 0 to High(N.Fields) do begin newFields[i].Key := Accept(N.Fields[i].Key).AsKeyword; newFields[i].Value := Accept(N.Fields[i].Value); end; N.Fields := newFields; Result := Node; end; function TAstTransformer.VisitCreateSeries(const Node: ICreateSeriesNode): IAstNode; begin Result := Node; // Leaf node end; function TAstTransformer.VisitAddSeriesItem(const Node: IAddSeriesItemNode): IAstNode; var N: TAddSeriesItemNode; begin N := (Node as TAddSeriesItemNode); N.Series := Accept(N.Series).AsIdentifier; N.Value := Accept(N.Value); N.Lookback := Accept(N.Lookback); // Accept handles nil Result := Node; end; function TAstTransformer.VisitSeriesLength(const Node: ISeriesLengthNode): IAstNode; var N: TSeriesLengthNode; begin N := (Node as TSeriesLengthNode); N.Series := Accept(N.Series).AsIdentifier; Result := Node; end; function TAstTransformer.VisitRecurNode(const Node: IRecurNode): IAstNode; var N: TRecurNode; begin N := (Node as TRecurNode); N.Arguments := AcceptNodes(N.Arguments); Result := Node; end; { TAstVisitor } function TAstVisitor.DoVisitConstant(const Node: IConstantNode): TDataValue; begin VisitConstant(Node); end; function TAstVisitor.DoVisitIdentifier(const Node: IIdentifierNode): TDataValue; begin VisitIdentifier(Node); end; function TAstVisitor.DoVisitKeyword(const Node: IKeywordNode): TDataValue; begin VisitKeyword(Node); end; function TAstVisitor.DoVisitBinaryExpression(const Node: IBinaryExpressionNode): TDataValue; begin VisitBinaryExpression(Node); end; function TAstVisitor.DoVisitUnaryExpression(const Node: IUnaryExpressionNode): TDataValue; begin VisitUnaryExpression(Node); end; function TAstVisitor.DoVisitIfExpression(const Node: IIfExpressionNode): TDataValue; begin VisitIfExpression(Node); end; function TAstVisitor.DoVisitTernaryExpression(const Node: ITernaryExpressionNode): TDataValue; begin VisitTernaryExpression(Node); end; function TAstVisitor.DoVisitLambdaExpression(const Node: ILambdaExpressionNode): TDataValue; begin VisitLambdaExpression(Node); end; function TAstVisitor.DoVisitFunctionCall(const Node: IFunctionCallNode): TDataValue; begin VisitFunctionCall(Node); end; function TAstVisitor.DoVisitMacroExpansionNode(const Node: IMacroExpansionNode): TDataValue; begin VisitMacroExpansionNode(Node); end; function TAstVisitor.DoVisitBlockExpression(const Node: IBlockExpressionNode): TDataValue; begin VisitBlockExpression(Node); end; function TAstVisitor.DoVisitVariableDeclaration(const Node: IVariableDeclarationNode): TDataValue; begin VisitVariableDeclaration(Node); end; function TAstVisitor.DoVisitAssignment(const Node: IAssignmentNode): TDataValue; begin VisitAssignment(Node); end; function TAstVisitor.DoVisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue; begin VisitMacroDefinition(Node); end; function TAstVisitor.DoVisitQuasiquote(const Node: IQuasiquoteNode): TDataValue; begin VisitQuasiquote(Node); end; function TAstVisitor.DoVisitUnquote(const Node: IUnquoteNode): TDataValue; begin VisitUnquote(Node); end; function TAstVisitor.DoVisitUnquoteSplicing(const Node: IUnquoteSplicingNode): TDataValue; begin VisitUnquoteSplicing(Node); end; function TAstVisitor.DoVisitIndexer(const Node: IIndexerNode): TDataValue; begin VisitIndexer(Node); end; function TAstVisitor.DoVisitMemberAccess(const Node: IMemberAccessNode): TDataValue; begin VisitMemberAccess(Node); end; function TAstVisitor.DoVisitRecordLiteral(const Node: IRecordLiteralNode): TDataValue; begin VisitRecordLiteral(Node); end; function TAstVisitor.DoVisitCreateSeries(const Node: ICreateSeriesNode): TDataValue; begin VisitCreateSeries(Node); end; function TAstVisitor.DoVisitAddSeriesItem(const Node: IAddSeriesItemNode): TDataValue; begin VisitAddSeriesItem(Node); end; function TAstVisitor.DoVisitSeriesLength(const Node: ISeriesLengthNode): TDataValue; begin VisitSeriesLength(Node); end; function TAstVisitor.DoVisitRecurNode(const Node: IRecurNode): TDataValue; begin VisitRecurNode(Node); end; function TAstVisitor.DoVisitNop(const Node: INopNode): TDataValue; begin // Added Nop implementation VisitNop(Node); end; end.