AST-Playground
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
unit Myc.Ast.Printer;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
System.SysUtils,
|
||||
System.Classes,
|
||||
System.Generics.Collections,
|
||||
Myc.Data.Types,
|
||||
Myc.Ast;
|
||||
|
||||
type
|
||||
TPrettyPrintVisitor = class(TInterfacedObject, IAstVisitor)
|
||||
private
|
||||
FBuilder: TStringBuilder;
|
||||
FIndentLevel: Integer;
|
||||
procedure Indent;
|
||||
procedure Unindent;
|
||||
procedure AppendLine(const S: string);
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
function GetResult: string;
|
||||
// IAstVisitor
|
||||
function VisitConstant(const Node: IConstantNode): IDataValue;
|
||||
function VisitIdentifier(const Node: IIdentifierNode): IDataValue;
|
||||
function VisitBinaryExpression(const Node: IBinaryExpressionNode): IDataValue;
|
||||
function VisitUnaryExpression(const Node: IUnaryExpressionNode): IDataValue;
|
||||
function VisitIfExpression(const Node: IIfExpressionNode): IDataValue;
|
||||
function VisitLambdaExpression(const Node: ILambdaExpressionNode): IDataValue;
|
||||
function VisitFunctionCall(const Node: IFunctionCallNode): IDataValue;
|
||||
function VisitBlockExpression(const Node: IBlockExpressionNode): IDataValue;
|
||||
function VisitVariableDeclaration(const Node: IVariableDeclarationNode): IDataValue;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TPrettyPrintVisitor }
|
||||
|
||||
constructor TPrettyPrintVisitor.Create;
|
||||
begin
|
||||
inherited Create;
|
||||
FBuilder := TStringBuilder.Create;
|
||||
FIndentLevel := 0;
|
||||
end;
|
||||
|
||||
destructor TPrettyPrintVisitor.Destroy;
|
||||
begin
|
||||
FBuilder.Free;
|
||||
inherited Destroy;
|
||||
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.AppendLine(const S: string);
|
||||
begin
|
||||
FBuilder.Append(''.PadLeft(FIndentLevel));
|
||||
FBuilder.AppendLine(S);
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitConstant(const Node: IConstantNode): IDataValue;
|
||||
begin
|
||||
AppendLine(Format('Constant (%s)', [Node.Value.AsString]));
|
||||
Result := TDataType.Void.Value;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitIdentifier(const Node: IIdentifierNode): IDataValue;
|
||||
begin
|
||||
AppendLine(Format('Identifier (%s)', [Node.Name]));
|
||||
Result := TDataType.Void.Value;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitBinaryExpression(const Node: IBinaryExpressionNode): IDataValue;
|
||||
begin
|
||||
AppendLine(Format('BinaryExpr (%s)', [Node.Operator.ToString]));
|
||||
Indent;
|
||||
Node.Left.Accept(Self);
|
||||
Node.Right.Accept(Self);
|
||||
Unindent;
|
||||
Result := TDataType.Void.Value;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitUnaryExpression(const Node: IUnaryExpressionNode): IDataValue;
|
||||
begin
|
||||
AppendLine(Format('UnaryExpr (%s)', [Node.Operator.ToString]));
|
||||
Indent;
|
||||
Node.Right.Accept(Self);
|
||||
Unindent;
|
||||
Result := TDataType.Void.Value;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitIfExpression(const Node: IIfExpressionNode): IDataValue;
|
||||
begin
|
||||
AppendLine('IfExpr');
|
||||
Indent;
|
||||
AppendLine('Condition:');
|
||||
Indent;
|
||||
Node.Condition.Accept(Self);
|
||||
Unindent;
|
||||
AppendLine('Then:');
|
||||
Indent;
|
||||
Node.ThenBranch.Accept(Self);
|
||||
Unindent;
|
||||
AppendLine('Else:');
|
||||
Indent;
|
||||
Node.ElseBranch.Accept(Self);
|
||||
Unindent;
|
||||
Unindent;
|
||||
Result := TDataType.Void.Value;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitLambdaExpression(const Node: ILambdaExpressionNode): IDataValue;
|
||||
var
|
||||
param: IIdentifierNode;
|
||||
paramNames: TStringList;
|
||||
begin
|
||||
paramNames := TStringList.Create;
|
||||
try
|
||||
for param in Node.Parameters do
|
||||
paramNames.Add(param.Name);
|
||||
AppendLine(Format('Lambda (params: %s)', [paramNames.CommaText]));
|
||||
finally
|
||||
paramNames.Free;
|
||||
end;
|
||||
|
||||
Indent;
|
||||
AppendLine('Body:');
|
||||
Indent;
|
||||
Node.Body.Accept(Self);
|
||||
Unindent;
|
||||
Unindent;
|
||||
Result := TDataType.Void.Value;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitFunctionCall(const Node: IFunctionCallNode): IDataValue;
|
||||
var
|
||||
arg: IExpressionNode;
|
||||
begin
|
||||
AppendLine('FunctionCall');
|
||||
Indent;
|
||||
AppendLine('Callee:');
|
||||
Indent;
|
||||
Node.Callee.Accept(Self);
|
||||
Unindent;
|
||||
AppendLine('Arguments:');
|
||||
Indent;
|
||||
for arg in Node.Arguments do
|
||||
arg.Accept(Self);
|
||||
Unindent;
|
||||
Unindent;
|
||||
Result := TDataType.Void.Value;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitBlockExpression(const Node: IBlockExpressionNode): IDataValue;
|
||||
var
|
||||
expr: IExpressionNode;
|
||||
begin
|
||||
AppendLine('Block');
|
||||
Indent;
|
||||
for expr in Node.Expressions do
|
||||
expr.Accept(Self);
|
||||
Unindent;
|
||||
Result := TDataType.Void.Value;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitVariableDeclaration(const Node: IVariableDeclarationNode): IDataValue;
|
||||
begin
|
||||
AppendLine(Format('VarDecl (%s)', [Node.Identifier.Name]));
|
||||
if Assigned(Node.Initializer) then
|
||||
begin
|
||||
Indent;
|
||||
Node.Initializer.Accept(Self);
|
||||
Unindent;
|
||||
end;
|
||||
Result := TDataType.Void.Value;
|
||||
end;
|
||||
|
||||
end.
|
||||
Reference in New Issue
Block a user