Generic Visitors
This commit is contained in:
+2
-408
@@ -6,7 +6,8 @@ uses
|
||||
System.SysUtils,
|
||||
Myc.Data.Value,
|
||||
Myc.Ast.Nodes,
|
||||
Myc.Ast.Visitor;
|
||||
Myc.Ast.Visitor,
|
||||
Myc.Ast.Script.Print;
|
||||
|
||||
type
|
||||
EParserException = class(EAstException)
|
||||
@@ -116,57 +117,6 @@ type
|
||||
function Parse: IAstNode;
|
||||
end;
|
||||
|
||||
TPrettyPrintVisitor = class(TAstVisitor)
|
||||
private
|
||||
FBuilder: TStringBuilder;
|
||||
FIndentLevel: Integer;
|
||||
procedure Indent;
|
||||
procedure Unindent;
|
||||
procedure Append(const S: string);
|
||||
procedure NewLine;
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
function GetResult: string;
|
||||
function Execute(const RootNode: IAstNode): TDataValue;
|
||||
|
||||
function VisitConstant(const Node: IConstantNode): TVoid; override;
|
||||
function VisitIdentifier(const Node: IIdentifierNode): TVoid; override;
|
||||
function VisitKeyword(const Node: IKeywordNode): TVoid; override;
|
||||
|
||||
function VisitParameterList(const Node: IParameterList): TVoid; override;
|
||||
function VisitArgumentList(const Node: IArgumentList): TVoid; override;
|
||||
function VisitExpressionList(const Node: IExpressionList): TVoid; override;
|
||||
function VisitRecordFieldList(const Node: IRecordFieldList): TVoid; override;
|
||||
function VisitRecordField(const Node: IRecordFieldNode): TVoid; override;
|
||||
|
||||
function VisitIfExpression(const Node: IIfExpressionNode): TVoid; override;
|
||||
function VisitCondExpression(const Node: ICondExpressionNode): TVoid; override;
|
||||
function VisitLambdaExpression(const Node: ILambdaExpressionNode): TVoid; override;
|
||||
function VisitMacroDefinition(const Node: IMacroDefinitionNode): TVoid; override;
|
||||
function VisitQuasiquote(const Node: IQuasiquoteNode): TVoid; override;
|
||||
function VisitUnquote(const Node: IUnquoteNode): TVoid; override;
|
||||
function VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): TVoid; override;
|
||||
function VisitFunctionCall(const Node: IFunctionCallNode): TVoid; override;
|
||||
function VisitMacroExpansionNode(const Node: IMacroExpansionNode): TVoid; override;
|
||||
function VisitBlockExpression(const Node: IBlockExpressionNode): TVoid; override;
|
||||
function VisitVariableDeclaration(const Node: IVariableDeclarationNode): TVoid; override;
|
||||
function VisitAssignment(const Node: IAssignmentNode): TVoid; override;
|
||||
function VisitIndexer(const Node: IIndexerNode): TVoid; override;
|
||||
function VisitMemberAccess(const Node: IMemberAccessNode): TVoid; override;
|
||||
function VisitRecordLiteral(const Node: IRecordLiteralNode): TVoid; override;
|
||||
function VisitCreateSeries(const Node: ICreateSeriesNode): TVoid; override;
|
||||
function VisitAddSeriesItem(const Node: IAddSeriesItemNode): TVoid; override;
|
||||
function VisitSeriesLength(const Node: ISeriesLengthNode): TVoid; override;
|
||||
function VisitRecurNode(const Node: IRecurNode): TVoid; override;
|
||||
function VisitNop(const Node: INopNode): TVoid; override;
|
||||
|
||||
function VisitPipeInput(const Node: IPipeInputNode): TVoid; override;
|
||||
function VisitPipeSelectorList(const Node: IPipeSelectorList): TVoid; override;
|
||||
function VisitPipeInputList(const Node: IPipeInputList): TVoid; override;
|
||||
function VisitPipe(const Node: IPipeNode): TVoid; override;
|
||||
end;
|
||||
|
||||
{ TTokenKindHelper }
|
||||
function TTokenKindHelper.ToString: String;
|
||||
begin
|
||||
@@ -812,362 +762,6 @@ begin
|
||||
Result := expr.Node;
|
||||
end;
|
||||
|
||||
{ TPrettyPrintVisitor }
|
||||
|
||||
constructor TPrettyPrintVisitor.Create;
|
||||
begin
|
||||
inherited Create;
|
||||
FBuilder := TStringBuilder.Create;
|
||||
FIndentLevel := 0;
|
||||
end;
|
||||
|
||||
destructor TPrettyPrintVisitor.Destroy;
|
||||
begin
|
||||
FBuilder.Free;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.GetResult: string;
|
||||
begin
|
||||
Result := FBuilder.ToString;
|
||||
end;
|
||||
|
||||
procedure TPrettyPrintVisitor.Indent;
|
||||
begin
|
||||
Inc(FIndentLevel, 2);
|
||||
end;
|
||||
|
||||
procedure TPrettyPrintVisitor.Unindent;
|
||||
begin
|
||||
Dec(FIndentLevel, 2);
|
||||
end;
|
||||
|
||||
procedure TPrettyPrintVisitor.Append(const S: string);
|
||||
begin
|
||||
FBuilder.Append(S);
|
||||
end;
|
||||
|
||||
procedure TPrettyPrintVisitor.NewLine;
|
||||
begin
|
||||
FBuilder.AppendLine;
|
||||
FBuilder.Append(''.PadLeft(FIndentLevel));
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.Execute(const RootNode: IAstNode): TDataValue;
|
||||
begin
|
||||
if Assigned(RootNode) then
|
||||
RootNode.Accept(Self);
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitPipeInput(const Node: IPipeInputNode): TVoid;
|
||||
begin
|
||||
Node.StreamSource.Accept(Self);
|
||||
Append(' ');
|
||||
// Printer Logic for Vector syntax
|
||||
Node.Selectors.Accept(Self); // Selectors is IPipeSelectorList which is visited as list
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitPipeSelectorList(const Node: IPipeSelectorList): TVoid;
|
||||
begin
|
||||
Append('[');
|
||||
for var i := 0 to Node.Count - 1 do
|
||||
begin
|
||||
if i > 0 then
|
||||
Append(' ');
|
||||
Node[i].Accept(Self);
|
||||
end;
|
||||
Append(']');
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitPipeInputList(const Node: IPipeInputList): TVoid;
|
||||
begin
|
||||
Append('[');
|
||||
for var i := 0 to Node.Count - 1 do
|
||||
begin
|
||||
if i > 0 then
|
||||
Append(' ');
|
||||
Node[i].Accept(Self);
|
||||
end;
|
||||
Append(']');
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitPipe(const Node: IPipeNode): TVoid;
|
||||
begin
|
||||
Append('(pipe ');
|
||||
Node.Inputs.Accept(Self);
|
||||
Indent;
|
||||
NewLine;
|
||||
Node.Transformation.Accept(Self);
|
||||
Unindent;
|
||||
NewLine;
|
||||
Append(')');
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitConstant(const Node: IConstantNode): TVoid;
|
||||
begin
|
||||
if Node.Value.Kind = vkText then
|
||||
Append('"' + Node.Value.AsText + '"')
|
||||
else
|
||||
Append(Node.Value.ToString);
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitIdentifier(const Node: IIdentifierNode): TVoid;
|
||||
begin
|
||||
Append(Node.Name);
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitKeyword(const Node: IKeywordNode): TVoid;
|
||||
begin
|
||||
Append(':' + Node.Value.Name);
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitNop(const Node: INopNode): TVoid;
|
||||
begin
|
||||
Append('...');
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitParameterList(const Node: IParameterList): TVoid;
|
||||
begin
|
||||
Append('[');
|
||||
for var i := 0 to Node.Count - 1 do
|
||||
begin
|
||||
if i > 0 then
|
||||
Append(' ');
|
||||
Node[i].Accept(Self);
|
||||
end;
|
||||
Append(']');
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitArgumentList(const Node: IArgumentList): TVoid;
|
||||
begin
|
||||
for var i := 0 to Node.Count - 1 do
|
||||
begin
|
||||
Append(' ');
|
||||
Node[i].Accept(Self);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitExpressionList(const Node: IExpressionList): TVoid;
|
||||
begin
|
||||
Indent;
|
||||
for var item in Node do
|
||||
begin
|
||||
NewLine;
|
||||
item.Accept(Self);
|
||||
end;
|
||||
Unindent;
|
||||
NewLine;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitRecordFieldList(const Node: IRecordFieldList): TVoid;
|
||||
begin
|
||||
Indent;
|
||||
for var item in Node do
|
||||
begin
|
||||
NewLine;
|
||||
item.Accept(Self);
|
||||
end;
|
||||
Unindent;
|
||||
NewLine;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitRecordField(const Node: IRecordFieldNode): TVoid;
|
||||
begin
|
||||
Node.Key.Accept(Self);
|
||||
Append(' ');
|
||||
Node.Value.Accept(Self);
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitIfExpression(const Node: IIfExpressionNode): TVoid;
|
||||
begin
|
||||
Append('(if ');
|
||||
Node.Condition.Accept(Self);
|
||||
Indent;
|
||||
NewLine;
|
||||
Node.ThenBranch.Accept(Self);
|
||||
if Assigned(Node.ElseBranch) then
|
||||
begin
|
||||
NewLine;
|
||||
Node.ElseBranch.Accept(Self);
|
||||
end;
|
||||
Unindent;
|
||||
NewLine;
|
||||
Append(')');
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitCondExpression(const Node: ICondExpressionNode): TVoid;
|
||||
begin
|
||||
Append('(?');
|
||||
Indent;
|
||||
for var pair in Node.Pairs do
|
||||
begin
|
||||
NewLine;
|
||||
pair.Condition.Accept(Self);
|
||||
Append(' ');
|
||||
pair.Branch.Accept(Self);
|
||||
end;
|
||||
NewLine;
|
||||
Node.ElseBranch.Accept(Self);
|
||||
Unindent;
|
||||
NewLine;
|
||||
Append(')');
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitLambdaExpression(const Node: ILambdaExpressionNode): TVoid;
|
||||
begin
|
||||
Append('(fn ');
|
||||
Node.Parameters.Accept(Self);
|
||||
Indent;
|
||||
NewLine;
|
||||
Node.Body.Accept(Self);
|
||||
Unindent;
|
||||
NewLine;
|
||||
Append(')');
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitMacroDefinition(const Node: IMacroDefinitionNode): TVoid;
|
||||
begin
|
||||
Append('(defmacro ');
|
||||
Node.Name.Accept(Self);
|
||||
Append(' ');
|
||||
Node.Parameters.Accept(Self);
|
||||
Indent;
|
||||
NewLine;
|
||||
Node.Body.Accept(Self);
|
||||
Unindent;
|
||||
NewLine;
|
||||
Append(')');
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitQuasiquote(const Node: IQuasiquoteNode): TVoid;
|
||||
begin
|
||||
Append('`');
|
||||
Node.Expression.Accept(Self);
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitUnquote(const Node: IUnquoteNode): TVoid;
|
||||
begin
|
||||
Append('~');
|
||||
Node.Expression.Accept(Self);
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): TVoid;
|
||||
begin
|
||||
Append('~@');
|
||||
Node.Expression.Accept(Self);
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitFunctionCall(const Node: IFunctionCallNode): TVoid;
|
||||
begin
|
||||
if (Node.Callee.Kind = akIdentifier) and (Node.Callee.AsIdentifier.Name = 'quote') and (Node.Arguments.Count = 1) then
|
||||
begin
|
||||
Append('''');
|
||||
Node.Arguments[0].Accept(Self);
|
||||
exit;
|
||||
end;
|
||||
Append('(');
|
||||
Node.Callee.Accept(Self);
|
||||
Node.Arguments.Accept(Self);
|
||||
Append(')');
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitMacroExpansionNode(const Node: IMacroExpansionNode): TVoid;
|
||||
begin
|
||||
VisitFunctionCall(Node.CallNode);
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitRecurNode(const Node: IRecurNode): TVoid;
|
||||
begin
|
||||
Append('(recur');
|
||||
Node.Arguments.Accept(Self);
|
||||
Append(')');
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitBlockExpression(const Node: IBlockExpressionNode): TVoid;
|
||||
begin
|
||||
Append('(do');
|
||||
Node.Expressions.Accept(Self);
|
||||
Append(')');
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitVariableDeclaration(const Node: IVariableDeclarationNode): TVoid;
|
||||
begin
|
||||
Append('(def ');
|
||||
Node.Target.Accept(Self);
|
||||
if Assigned(Node.Initializer) then
|
||||
begin
|
||||
Append(' ');
|
||||
Node.Initializer.Accept(Self);
|
||||
end;
|
||||
Append(')');
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitAssignment(const Node: IAssignmentNode): TVoid;
|
||||
begin
|
||||
Append('(assign ');
|
||||
Node.Target.Accept(Self);
|
||||
Append(' ');
|
||||
Node.Value.Accept(Self);
|
||||
Append(')');
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitIndexer(const Node: IIndexerNode): TVoid;
|
||||
begin
|
||||
Append('(get ');
|
||||
Node.Base.Accept(Self);
|
||||
Append(' ');
|
||||
Node.Index.Accept(Self);
|
||||
Append(')');
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitMemberAccess(const Node: IMemberAccessNode): TVoid;
|
||||
begin
|
||||
Append('(.');
|
||||
Node.Member.Accept(Self);
|
||||
Append(' ');
|
||||
Node.Base.Accept(Self);
|
||||
Append(')');
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitRecordLiteral(const Node: IRecordLiteralNode): TVoid;
|
||||
begin
|
||||
if Node.Fields.Count = 0 then
|
||||
begin
|
||||
Append('{}');
|
||||
exit;
|
||||
end;
|
||||
Append('{');
|
||||
Node.Fields.Accept(Self);
|
||||
Append('}');
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitCreateSeries(const Node: ICreateSeriesNode): TVoid;
|
||||
begin
|
||||
Append(Format('(new-series "%s")', [Node.Definition]));
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitAddSeriesItem(const Node: IAddSeriesItemNode): TVoid;
|
||||
begin
|
||||
Append('(add-item ');
|
||||
Node.Series.Accept(Self);
|
||||
Append(' ');
|
||||
Node.Value.Accept(Self);
|
||||
if Assigned(Node.Lookback) then
|
||||
begin
|
||||
Append(' ');
|
||||
Node.Lookback.Accept(Self);
|
||||
end;
|
||||
Append(')');
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitSeriesLength(const Node: ISeriesLengthNode): TVoid;
|
||||
begin
|
||||
Append('(count ');
|
||||
Node.Series.Accept(Self);
|
||||
Append(')');
|
||||
end;
|
||||
|
||||
{ TAstScript }
|
||||
|
||||
class function TAstScript.Parse(const ASource: string): IAstNode;
|
||||
|
||||
Reference in New Issue
Block a user