Binder refactoring, Monster refactoring

This commit is contained in:
Michael Schimmel
2025-11-02 19:38:52 +01:00
parent 8f29212cba
commit ea39a57b77
22 changed files with 3061 additions and 2638 deletions
File diff suppressed because one or more lines are too long
-1
View File
@@ -22,7 +22,6 @@ uses
Myc.Ast.Script in '..\Src\AST\Myc.Ast.Script.pas',
Myc.Ast.Types in '..\Src\AST\Myc.Ast.Types.pas',
Myc.Data.Keyword in '..\Src\Data\Myc.Data.Keyword.pas',
Myc.Ast.Binding.Nodes in '..\Src\AST\Myc.Ast.Binding.Nodes.pas',
Myc.Ast.MacroExpander in '..\Src\AST\Myc.Ast.MacroExpander.pas',
Myc.Ast.TypeChecker in '..\Src\AST\Myc.Ast.TypeChecker.pas',
Myc.Ast.Lowering in '..\Src\AST\Myc.Ast.Lowering.pas',
-1
View File
@@ -152,7 +152,6 @@
<DCCReference Include="..\Src\AST\Myc.Ast.Script.pas"/>
<DCCReference Include="..\Src\AST\Myc.Ast.Types.pas"/>
<DCCReference Include="..\Src\Data\Myc.Data.Keyword.pas"/>
<DCCReference Include="..\Src\AST\Myc.Ast.Binding.Nodes.pas"/>
<DCCReference Include="..\Src\AST\Myc.Ast.MacroExpander.pas"/>
<DCCReference Include="..\Src\AST\Myc.Ast.TypeChecker.pas"/>
<DCCReference Include="..\Src\AST\Myc.Ast.Lowering.pas"/>
+3 -2
View File
@@ -27,6 +27,7 @@ uses
Myc.Ast.Nodes,
Myc.Ast.Scope,
Myc.Ast,
Myc.Ast.Visitor,
Myc.Ast.Evaluator,
Myc.Ast.Dumper,
Myc.Data.Decimal,
@@ -262,7 +263,7 @@ begin
FWorkspace.Align := TAlignLayout.Client;
FWorkspace.ClipChildren := true;
FWorkspace.OnMouseDown := WorkspaceMouseDown;
{
TAst.RegisterLibrary(
procedure(const Scope: IExecutionScope)
var
@@ -356,7 +357,7 @@ begin
);
end
);
}
ClearButtonClick(Self);
end;
+76 -83
View File
@@ -49,7 +49,8 @@ type
property Workspace: TAuraWorkspace read GetWorkspace;
end;
TAstVisualizer = class(TAstVisitor, IAstVisualizer)
// Inherits from the new generic TAstVisitor<TAuraNode>
TAstVisualizer = class(TAstVisitor<TAuraNode>, IAstVisualizer)
private
FExprDepth: Integer;
FParentControl: TControl;
@@ -63,30 +64,30 @@ type
procedure SetParentControl(const Value: TControl);
protected
// Visitor implementations for each AST node type.
function VisitConstant(const Node: IConstantNode): TDataValue; override;
function VisitIdentifier(const Node: IIdentifierNode): TDataValue; override;
function VisitKeyword(const Node: IKeywordNode): TDataValue; override;
function VisitBinaryExpression(const Node: IBinaryExpressionNode): TDataValue; override;
function VisitUnaryExpression(const Node: IUnaryExpressionNode): TDataValue; override;
function VisitIfExpression(const Node: IIfExpressionNode): TDataValue; override;
function VisitTernaryExpression(const Node: ITernaryExpressionNode): TDataValue; override;
function VisitLambdaExpression(const Node: ILambdaExpressionNode): TDataValue; override;
function VisitFunctionCall(const Node: IFunctionCallNode): TDataValue; override;
function VisitMacroExpansionNode(const Node: IMacroExpansionNode): TDataValue; override;
function VisitBlockExpression(const Node: IBlockExpressionNode): TDataValue; override;
function VisitVariableDeclaration(const Node: IVariableDeclarationNode): TDataValue; override;
function VisitAssignment(const Node: IAssignmentNode): TDataValue; override;
function VisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue; override;
function VisitQuasiquote(const Node: IQuasiquoteNode): TDataValue; override;
function VisitUnquote(const Node: IUnquoteNode): TDataValue; override;
function VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): TDataValue; override;
function VisitIndexer(const Node: IIndexerNode): TDataValue; override;
function VisitMemberAccess(const Node: IMemberAccessNode): TDataValue; override;
function VisitRecordLiteral(const Node: IRecordLiteralNode): TDataValue; override;
function VisitCreateSeries(const Node: ICreateSeriesNode): TDataValue; override;
function VisitAddSeriesItem(const Node: IAddSeriesItemNode): TDataValue; override;
function VisitSeriesLength(const Node: ISeriesLengthNode): TDataValue; override;
function VisitRecurNode(const Node: IRecurNode): TDataValue; override;
function VisitConstant(const Node: IConstantNode): TAuraNode; override;
function VisitIdentifier(const Node: IIdentifierNode): TAuraNode; override;
function VisitKeyword(const Node: IKeywordNode): TAuraNode; override;
function VisitBinaryExpression(const Node: IBinaryExpressionNode): TAuraNode; override;
function VisitUnaryExpression(const Node: IUnaryExpressionNode): TAuraNode; override;
function VisitIfExpression(const Node: IIfExpressionNode): TAuraNode; override;
function VisitTernaryExpression(const Node: ITernaryExpressionNode): TAuraNode; override;
function VisitLambdaExpression(const Node: ILambdaExpressionNode): TAuraNode; override;
function VisitFunctionCall(const Node: IFunctionCallNode): TAuraNode; override;
function VisitMacroExpansionNode(const Node: IMacroExpansionNode): TAuraNode; override;
function VisitBlockExpression(const Node: IBlockExpressionNode): TAuraNode; override;
function VisitVariableDeclaration(const Node: IVariableDeclarationNode): TAuraNode; override;
function VisitAssignment(const Node: IAssignmentNode): TAuraNode; override;
function VisitMacroDefinition(const Node: IMacroDefinitionNode): TAuraNode; override;
function VisitQuasiquote(const Node: IQuasiquoteNode): TAuraNode; override;
function VisitUnquote(const Node: IUnquoteNode): TAuraNode; override;
function VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): TAuraNode; override;
function VisitIndexer(const Node: IIndexerNode): TAuraNode; override;
function VisitMemberAccess(const Node: IMemberAccessNode): TAuraNode; override;
function VisitRecordLiteral(const Node: IRecordLiteralNode): TAuraNode; override;
function VisitCreateSeries(const Node: ICreateSeriesNode): TAuraNode; override;
function VisitAddSeriesItem(const Node: IAddSeriesItemNode): TAuraNode; override;
function VisitSeriesLength(const Node: ISeriesLengthNode): TAuraNode; override;
function VisitRecurNode(const Node: IRecurNode): TAuraNode; override;
public
constructor Create(AWorkspace: TAuraWorkspace; AParentControl: TControl; AExprDepth: Integer);
@@ -593,126 +594,126 @@ begin
FParentControl := Value;
end;
function TAstVisualizer.VisitAddSeriesItem(const Node: IAddSeriesItemNode): TDataValue;
function TAstVisualizer.VisitAddSeriesItem(const Node: IAddSeriesItemNode): TAuraNode;
begin
Result := TDataValue.FromGeneric<TAuraNode>(TAuraAddSeriesItemNode.Create(Self, Node));
Result := TAuraAddSeriesItemNode.Create(Self, Node);
end;
function TAstVisualizer.VisitAssignment(const Node: IAssignmentNode): TDataValue;
function TAstVisualizer.VisitAssignment(const Node: IAssignmentNode): TAuraNode;
begin
Result := TDataValue.FromGeneric<TAuraNode>(TAuraAssignmentNode.Create(Self, Node));
Result := TAuraAssignmentNode.Create(Self, Node);
end;
// --- Visitor Implementations ---
function TAstVisualizer.VisitConstant(const Node: IConstantNode): TDataValue;
function TAstVisualizer.VisitConstant(const Node: IConstantNode): TAuraNode;
begin
Result := TDataValue.FromGeneric<TAuraNode>(TAuraConstantNode.Create(Self, Node));
Result := TAuraConstantNode.Create(Self, Node);
end;
function TAstVisualizer.VisitIdentifier(const Node: IIdentifierNode): TDataValue;
function TAstVisualizer.VisitIdentifier(const Node: IIdentifierNode): TAuraNode;
begin
Result := TDataValue.FromGeneric<TAuraNode>(TAuraIdentifierNode.Create(Self, Node));
Result := TAuraIdentifierNode.Create(Self, Node);
end;
function TAstVisualizer.VisitKeyword(const Node: IKeywordNode): TDataValue;
function TAstVisualizer.VisitKeyword(const Node: IKeywordNode): TAuraNode;
begin
Result := TDataValue.FromGeneric<TAuraNode>(TAuraKeywordNode.Create(Self, Node));
Result := TAuraKeywordNode.Create(Self, Node);
end;
function TAstVisualizer.VisitBinaryExpression(const Node: IBinaryExpressionNode): TDataValue;
function TAstVisualizer.VisitBinaryExpression(const Node: IBinaryExpressionNode): TAuraNode;
begin
Result := TDataValue.FromGeneric<TAuraNode>(TAuraBinaryExpressionNode.Create(Self, Node));
Result := TAuraBinaryExpressionNode.Create(Self, Node);
end;
function TAstVisualizer.VisitBlockExpression(const Node: IBlockExpressionNode): TDataValue;
function TAstVisualizer.VisitBlockExpression(const Node: IBlockExpressionNode): TAuraNode;
begin
Result := TDataValue.FromGeneric<TAuraNode>(TAuraBlockExpressionNode.Create(Self, Node));
Result := TAuraBlockExpressionNode.Create(Self, Node);
end;
function TAstVisualizer.VisitCreateSeries(const Node: ICreateSeriesNode): TDataValue;
function TAstVisualizer.VisitCreateSeries(const Node: ICreateSeriesNode): TAuraNode;
begin
Result := TDataValue.FromGeneric<TAuraNode>(TAuraCreateSeriesNode.Create(Self, Node));
Result := TAuraCreateSeriesNode.Create(Self, Node);
end;
function TAstVisualizer.VisitFunctionCall(const Node: IFunctionCallNode): TDataValue;
function TAstVisualizer.VisitFunctionCall(const Node: IFunctionCallNode): TAuraNode;
begin
Result := TDataValue.FromGeneric<TAuraNode>(TAuraFunctionCallNode.Create(Self, Node));
Result := TAuraFunctionCallNode.Create(Self, Node);
end;
function TAstVisualizer.VisitUnaryExpression(const Node: IUnaryExpressionNode): TDataValue;
function TAstVisualizer.VisitUnaryExpression(const Node: IUnaryExpressionNode): TAuraNode;
begin
Result := TDataValue.FromGeneric<TAuraNode>(TAuraUnaryExpressionNode.Create(Self, Node));
Result := TAuraUnaryExpressionNode.Create(Self, Node);
end;
function TAstVisualizer.VisitIfExpression(const Node: IIfExpressionNode): TDataValue;
function TAstVisualizer.VisitIfExpression(const Node: IIfExpressionNode): TAuraNode;
begin
Result := TDataValue.FromGeneric<TAuraNode>(TAuraIfExpressionNode.Create(Self, Node));
Result := TAuraIfExpressionNode.Create(Self, Node);
end;
function TAstVisualizer.VisitIndexer(const Node: IIndexerNode): TDataValue;
function TAstVisualizer.VisitIndexer(const Node: IIndexerNode): TAuraNode;
begin
Result := TDataValue.FromGeneric<TAuraNode>(TAuraIndexerNode.Create(Self, Node));
Result := TAuraIndexerNode.Create(Self, Node);
end;
function TAstVisualizer.VisitLambdaExpression(const Node: ILambdaExpressionNode): TDataValue;
function TAstVisualizer.VisitLambdaExpression(const Node: ILambdaExpressionNode): TAuraNode;
begin
Result := TDataValue.FromGeneric<TAuraNode>(TAuraLambdaExpressionNode.Create(Self, Node));
Result := TAuraLambdaExpressionNode.Create(Self, Node);
end;
function TAstVisualizer.VisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue;
function TAstVisualizer.VisitMacroDefinition(const Node: IMacroDefinitionNode): TAuraNode;
begin
Result := TDataValue.FromGeneric<TAuraNode>(TAuraMacroDefinitionNode.Create(Self, Node));
Result := TAuraMacroDefinitionNode.Create(Self, Node);
end;
function TAstVisualizer.VisitMacroExpansionNode(const Node: IMacroExpansionNode): TDataValue;
function TAstVisualizer.VisitMacroExpansionNode(const Node: IMacroExpansionNode): TAuraNode;
begin
Result := TDataValue.FromGeneric<TAuraNode>(TAuraMacroExpansionNode.Create(Self, Node));
Result := TAuraMacroExpansionNode.Create(Self, Node);
end;
function TAstVisualizer.VisitMemberAccess(const Node: IMemberAccessNode): TDataValue;
function TAstVisualizer.VisitMemberAccess(const Node: IMemberAccessNode): TAuraNode;
begin
Result := TDataValue.FromGeneric<TAuraNode>(TAuraMemberAccessNode.Create(Self, Node));
Result := TAuraMemberAccessNode.Create(Self, Node);
end;
function TAstVisualizer.VisitRecordLiteral(const Node: IRecordLiteralNode): TDataValue;
function TAstVisualizer.VisitRecordLiteral(const Node: IRecordLiteralNode): TAuraNode;
begin
Result := TDataValue.FromGeneric<TAuraNode>(TAuraRecordLiteralNode.Create(Self, Node));
Result := TAuraRecordLiteralNode.Create(Self, Node);
end;
function TAstVisualizer.VisitQuasiquote(const Node: IQuasiquoteNode): TDataValue;
function TAstVisualizer.VisitQuasiquote(const Node: IQuasiquoteNode): TAuraNode;
begin
Result := TDataValue.FromGeneric<TAuraNode>(TAuraQuasiquoteNode.Create(Self, Node));
Result := TAuraQuasiquoteNode.Create(Self, Node);
end;
function TAstVisualizer.VisitRecurNode(const Node: IRecurNode): TDataValue;
function TAstVisualizer.VisitRecurNode(const Node: IRecurNode): TAuraNode;
begin
Result := TDataValue.FromGeneric<TAuraNode>(TAuraRecurNode.Create(Self, Node));
Result := TAuraRecurNode.Create(Self, Node);
end;
function TAstVisualizer.VisitSeriesLength(const Node: ISeriesLengthNode): TDataValue;
function TAstVisualizer.VisitSeriesLength(const Node: ISeriesLengthNode): TAuraNode;
begin
Result := TDataValue.FromGeneric<TAuraNode>(TAuraSeriesLengthNode.Create(Self, Node));
Result := TAuraSeriesLengthNode.Create(Self, Node);
end;
function TAstVisualizer.VisitTernaryExpression(const Node: ITernaryExpressionNode): TDataValue;
function TAstVisualizer.VisitTernaryExpression(const Node: ITernaryExpressionNode): TAuraNode;
begin
Result := TDataValue.FromGeneric<TAuraNode>(TAuraTernaryExpressionNode.Create(Self, Node));
Result := TAuraTernaryExpressionNode.Create(Self, Node);
end;
function TAstVisualizer.VisitUnquote(const Node: IUnquoteNode): TDataValue;
function TAstVisualizer.VisitUnquote(const Node: IUnquoteNode): TAuraNode;
begin
Result := TDataValue.FromGeneric<TAuraNode>(TAuraUnquoteNode.Create(Self, Node));
Result := TAuraUnquoteNode.Create(Self, Node);
end;
function TAstVisualizer.VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): TDataValue;
function TAstVisualizer.VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): TAuraNode;
begin
Result := TDataValue.FromGeneric<TAuraNode>(TAuraUnquoteSplicingNode.Create(Self, Node));
Result := TAuraUnquoteSplicingNode.Create(Self, Node);
end;
function TAstVisualizer.VisitVariableDeclaration(const Node: IVariableDeclarationNode): TDataValue;
function TAstVisualizer.VisitVariableDeclaration(const Node: IVariableDeclarationNode): TAuraNode;
begin
Result := TDataValue.FromGeneric<TAuraNode>(TAuraVariableDeclarationNode.Create(Self, Node));
Result := TAuraVariableDeclarationNode.Create(Self, Node);
end;
{ TAutoFitControl }
@@ -1517,16 +1518,8 @@ begin
end;
function TAuraLambdaExpressionNode.CreateAst: IAstNode;
var
params: TArray<IIdentifierNode>;
i: Integer;
begin
// Re-use FNode.Parameters which is the source of truth
SetLength(params, Length(FNode.Parameters));
for i := 0 to High(FNode.Parameters) do
params[i] := TAst.Identifier(FNode.Parameters[i].Name);
Result := TAst.LambdaExpr(params, FBodyNode.CreateAst);
Result := TAst.LambdaExpr(FNode.Parameters, FBodyNode.CreateAst);
end;
procedure TAuraLambdaExpressionNode.SetupNode;
@@ -1966,7 +1959,7 @@ end;
function TAuraUnquoteSplicingNode.CreateAst: IAstNode;
begin
Result := TAst.UnquoteSplicing(FExpressionNode.CreateAst);
Result := TAst.UnquoteSplicing(FExpressionNode.CreateAst.AsQuasiquote);
end;
procedure TAuraUnquoteSplicingNode.SetupNode;
+86 -69
View File
@@ -11,82 +11,89 @@ uses
type
// This visitor converts an AST expression subtree into a single string.
TAstToTextVisitor = class(TAstVisitor)
public
function VisitConstant(const Node: IConstantNode): TDataValue; override;
function VisitIdentifier(const Node: IIdentifierNode): TDataValue; override;
function VisitBinaryExpression(const Node: IBinaryExpressionNode): TDataValue; override;
function VisitUnaryExpression(const Node: IUnaryExpressionNode): TDataValue; override;
function VisitIfExpression(const Node: IIfExpressionNode): TDataValue; override;
function VisitTernaryExpression(const Node: ITernaryExpressionNode): TDataValue; override;
function VisitLambdaExpression(const Node: ILambdaExpressionNode): TDataValue; override;
function VisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue; override;
function VisitFunctionCall(const Node: IFunctionCallNode): TDataValue; override;
function VisitMacroExpansionNode(const Node: IMacroExpansionNode): TDataValue; override;
function VisitBlockExpression(const Node: IBlockExpressionNode): TDataValue; override;
function VisitVariableDeclaration(const Node: IVariableDeclarationNode): TDataValue; override;
function VisitAssignment(const Node: IAssignmentNode): TDataValue; override;
function VisitIndexer(const Node: IIndexerNode): TDataValue; override;
function VisitMemberAccess(const Node: IMemberAccessNode): TDataValue; override;
function VisitQuasiquote(const Node: IQuasiquoteNode): TDataValue; override;
function VisitUnquote(const Node: IUnquoteNode): TDataValue; override;
function VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): TDataValue; override;
function VisitCreateSeries(const Node: ICreateSeriesNode): TDataValue; override;
function VisitAddSeriesItem(const Node: IAddSeriesItemNode): TDataValue; override;
function VisitSeriesLength(const Node: ISeriesLengthNode): TDataValue; override;
function VisitRecurNode(const Node: IRecurNode): TDataValue; override;
// It inherits from the generic visitor, returning a 'string' for each node.
TAstToTextVisitor = class(TAstVisitor<string>)
protected
function VisitConstant(const Node: IConstantNode): string; override;
function VisitIdentifier(const Node: IIdentifierNode): string; override;
function VisitKeyword(const Node: IKeywordNode): string; override;
function VisitBinaryExpression(const Node: IBinaryExpressionNode): string; override;
function VisitUnaryExpression(const Node: IUnaryExpressionNode): string; override;
function VisitIfExpression(const Node: IIfExpressionNode): string; override;
function VisitTernaryExpression(const Node: ITernaryExpressionNode): string; override;
function VisitLambdaExpression(const Node: ILambdaExpressionNode): string; override;
function VisitMacroDefinition(const Node: IMacroDefinitionNode): string; override;
function VisitFunctionCall(const Node: IFunctionCallNode): string; override;
function VisitMacroExpansionNode(const Node: IMacroExpansionNode): string; override;
function VisitBlockExpression(const Node: IBlockExpressionNode): string; override;
function VisitVariableDeclaration(const Node: IVariableDeclarationNode): string; override;
function VisitAssignment(const Node: IAssignmentNode): string; override;
function VisitIndexer(const Node: IIndexerNode): string; override;
function VisitMemberAccess(const Node: IMemberAccessNode): string; override;
function VisitQuasiquote(const Node: IQuasiquoteNode): string; override;
function VisitUnquote(const Node: IUnquoteNode): string; override;
function VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): string; override;
function VisitCreateSeries(const Node: ICreateSeriesNode): string; override;
function VisitAddSeriesItem(const Node: IAddSeriesItemNode): string; override;
function VisitSeriesLength(const Node: ISeriesLengthNode): string; override;
function VisitRecurNode(const Node: IRecurNode): string; override;
function VisitRecordLiteral(const Node: IRecordLiteralNode): string; override;
end;
implementation
uses
System.Classes, // For TStringBuilder
Myc.Data.Keyword;
{ TAstToTextVisitor }
function TAstToTextVisitor.VisitAddSeriesItem(const Node: IAddSeriesItemNode): TDataValue;
function TAstToTextVisitor.VisitAddSeriesItem(const Node: IAddSeriesItemNode): string;
var
seriesStr, valueStr, lookbackStr: string;
begin
seriesStr := Node.Series.Accept(Self).AsText;
valueStr := Node.Value.Accept(Self).AsText;
seriesStr := Accept(Node.Series);
valueStr := Accept(Node.Value);
lookbackStr := '';
if Assigned(Node.Lookback) then
lookbackStr := ', ' + Node.Lookback.Accept(Self).AsText;
lookbackStr := ', ' + Accept(Node.Lookback);
Result := Format('%s.add(%s%s)', [seriesStr, valueStr, lookbackStr]);
end;
function TAstToTextVisitor.VisitAssignment(const Node: IAssignmentNode): TDataValue;
function TAstToTextVisitor.VisitAssignment(const Node: IAssignmentNode): string;
begin
Result := Node.Identifier.Name + ' := ' + Node.Value.Accept(Self).AsText;
Result := Node.Identifier.Name + ' := ' + Accept(Node.Value);
end;
function TAstToTextVisitor.VisitBinaryExpression(const Node: IBinaryExpressionNode): TDataValue;
function TAstToTextVisitor.VisitBinaryExpression(const Node: IBinaryExpressionNode): string;
begin
var leftStr := Node.Left.Accept(Self).AsText;
var rightStr := Node.Right.Accept(Self).AsText;
var leftStr := Accept(Node.Left);
var rightStr := Accept(Node.Right);
Result := '(' + leftStr + ' ' + Node.Operator.ToString + ' ' + rightStr + ')';
end;
function TAstToTextVisitor.VisitBlockExpression(const Node: IBlockExpressionNode): TDataValue;
function TAstToTextVisitor.VisitBlockExpression(const Node: IBlockExpressionNode): string;
begin
Result := '{...}';
end;
function TAstToTextVisitor.VisitConstant(const Node: IConstantNode): TDataValue;
function TAstToTextVisitor.VisitConstant(const Node: IConstantNode): string;
begin
Result := Node.Value.ToString;
end;
function TAstToTextVisitor.VisitCreateSeries(const Node: ICreateSeriesNode): TDataValue;
function TAstToTextVisitor.VisitCreateSeries(const Node: ICreateSeriesNode): string;
begin
Result := 'new series(' + Node.Definition + ')';
end;
function TAstToTextVisitor.VisitFunctionCall(const Node: IFunctionCallNode): TDataValue;
function TAstToTextVisitor.VisitFunctionCall(const Node: IFunctionCallNode): string;
var
i: Integer;
sb: TStringBuilder;
calleeStr: string;
begin
calleeStr := Node.Callee.Accept(Self).AsText;
calleeStr := Accept(Node.Callee);
sb := TStringBuilder.Create;
try
@@ -94,7 +101,7 @@ begin
sb.Append('(');
for i := 0 to High(Node.Arguments) do
begin
sb.Append(Node.Arguments[i].Accept(Self).AsText);
sb.Append(Accept(Node.Arguments[i]));
if i < High(Node.Arguments) then
sb.Append(', ');
end;
@@ -105,7 +112,7 @@ begin
end;
end;
function TAstToTextVisitor.VisitMacroExpansionNode(const Node: IMacroExpansionNode): TDataValue;
function TAstToTextVisitor.VisitMacroExpansionNode(const Node: IMacroExpansionNode): string;
begin
// To represent a macro expansion as a single line of text, the most
// informative representation is the original call itself. We can simply
@@ -113,7 +120,7 @@ begin
Result := VisitFunctionCall(Node);
end;
function TAstToTextVisitor.VisitRecurNode(const Node: IRecurNode): TDataValue;
function TAstToTextVisitor.VisitRecurNode(const Node: IRecurNode): string;
var
i: Integer;
sb: TStringBuilder;
@@ -123,7 +130,7 @@ begin
sb.Append('recur(');
for i := 0 to High(Node.Arguments) do
begin
sb.Append(Node.Arguments[i].Accept(Self).AsText);
sb.Append(Accept(Node.Arguments[i]));
if i < High(Node.Arguments) then
sb.Append(', ');
end;
@@ -134,33 +141,38 @@ begin
end;
end;
function TAstToTextVisitor.VisitIdentifier(const Node: IIdentifierNode): TDataValue;
function TAstToTextVisitor.VisitIdentifier(const Node: IIdentifierNode): string;
begin
Result := Node.Name;
end;
function TAstToTextVisitor.VisitIfExpression(const Node: IIfExpressionNode): TDataValue;
function TAstToTextVisitor.VisitIfExpression(const Node: IIfExpressionNode): string;
begin
Result := Node.Condition.Accept(Self).AsText;
Result := Accept(Node.Condition);
end;
function TAstToTextVisitor.VisitIndexer(const Node: IIndexerNode): TDataValue;
function TAstToTextVisitor.VisitIndexer(const Node: IIndexerNode): string;
var
baseStr, indexStr: string;
begin
baseStr := Node.Base.Accept(Self).AsText;
indexStr := Node.Index.Accept(Self).AsText;
baseStr := Accept(Node.Base);
indexStr := Accept(Node.Index);
Result := Format('%s[%s]', [baseStr, indexStr]);
end;
function TAstToTextVisitor.VisitLambdaExpression(const Node: ILambdaExpressionNode): TDataValue;
function TAstToTextVisitor.VisitKeyword(const Node: IKeywordNode): string;
begin
Result := ':' + Node.Value.Name;
end;
function TAstToTextVisitor.VisitLambdaExpression(const Node: ILambdaExpressionNode): string;
var
i: Integer;
sb: TStringBuilder;
begin
sb := TStringBuilder.Create;
try
sb.Append(#$03BB + '(');
sb.Append(WideChar($03BB) + '('); // Lambda char
if Length(Node.Parameters) > 0 then
begin
for i := 0 to High(Node.Parameters) do
@@ -177,7 +189,7 @@ begin
end;
end;
function TAstToTextVisitor.VisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue;
function TAstToTextVisitor.VisitMacroDefinition(const Node: IMacroDefinitionNode): string;
var
i: Integer;
sb: TStringBuilder;
@@ -204,56 +216,61 @@ begin
end;
end;
function TAstToTextVisitor.VisitMemberAccess(const Node: IMemberAccessNode): TDataValue;
function TAstToTextVisitor.VisitMemberAccess(const Node: IMemberAccessNode): string;
var
baseStr: string;
begin
baseStr := Node.Base.Accept(Self).AsText;
baseStr := Accept(Node.Base);
Result := Format('%s.%s', [baseStr, Node.Member.Value.Name]);
end;
function TAstToTextVisitor.VisitQuasiquote(const Node: IQuasiquoteNode): TDataValue;
function TAstToTextVisitor.VisitQuasiquote(const Node: IQuasiquoteNode): string;
begin
Result := '`' + Node.Expression.Accept(Self).AsText;
Result := '`' + Accept(Node.Expression);
end;
function TAstToTextVisitor.VisitUnquote(const Node: IUnquoteNode): TDataValue;
function TAstToTextVisitor.VisitRecordLiteral(const Node: IRecordLiteralNode): string;
begin
Result := '~' + Node.Expression.Accept(Self).AsText;
Result := '{...}';
end;
function TAstToTextVisitor.VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): TDataValue;
function TAstToTextVisitor.VisitUnquote(const Node: IUnquoteNode): string;
begin
Result := '~@' + Node.Expression.Accept(Self).AsText;
Result := '~' + Accept(Node.Expression);
end;
function TAstToTextVisitor.VisitSeriesLength(const Node: ISeriesLengthNode): TDataValue;
function TAstToTextVisitor.VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): string;
begin
Result := '~@' + Accept(Node.Expression);
end;
function TAstToTextVisitor.VisitSeriesLength(const Node: ISeriesLengthNode): string;
var
seriesStr: string;
begin
seriesStr := Node.Series.Accept(Self).AsText;
seriesStr := Accept(Node.Series);
Result := Format('length(%s)', [seriesStr]);
end;
function TAstToTextVisitor.VisitTernaryExpression(const Node: ITernaryExpressionNode): TDataValue;
function TAstToTextVisitor.VisitTernaryExpression(const Node: ITernaryExpressionNode): string;
begin
var condStr := Node.Condition.Accept(Self).AsText;
var thenStr := Node.ThenBranch.Accept(Self).AsText;
var elseStr := Node.ElseBranch.Accept(Self).AsText;
var condStr := Accept(Node.Condition);
var thenStr := Accept(Node.ThenBranch);
var elseStr := Accept(Node.ElseBranch);
Result := Format('(%s ? %s : %s)', [condStr, thenStr, elseStr]);
end;
function TAstToTextVisitor.VisitUnaryExpression(const Node: IUnaryExpressionNode): TDataValue;
function TAstToTextVisitor.VisitUnaryExpression(const Node: IUnaryExpressionNode): string;
begin
Result := Node.Operator.ToString + ' ' + Node.Right.Accept(Self).AsText;
Result := Node.Operator.ToString + ' ' + Accept(Node.Right);
end;
function TAstToTextVisitor.VisitVariableDeclaration(const Node: IVariableDeclarationNode): TDataValue;
function TAstToTextVisitor.VisitVariableDeclaration(const Node: IVariableDeclarationNode): string;
var
initStr: string;
begin
if Assigned(Node.Initializer) then
initStr := ' := ' + Node.Initializer.Accept(Self).AsText
initStr := ' := ' + Accept(Node.Initializer)
else
initStr := '';
Result := 'var ' + Node.Identifier.Name + initStr;