Global data value refactoring + 1st scripting version
This commit is contained in:
+100
-101
@@ -11,15 +11,17 @@ uses
|
||||
Myc.Ast;
|
||||
|
||||
type
|
||||
// A visitor that converts an AST into a LISP-like (Clojure-style) string representation.
|
||||
TPrettyPrintVisitor = class(TInterfacedObject, IAstVisitor)
|
||||
private
|
||||
FBuilder: TStringBuilder;
|
||||
FIndentLevel: Integer;
|
||||
procedure Indent;
|
||||
procedure Unindent;
|
||||
procedure AppendLine(const S: string);
|
||||
procedure Append(const S: string);
|
||||
procedure NewLine;
|
||||
public
|
||||
constructor Create(AIndentLevel: Integer = 0);
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
function GetResult: string;
|
||||
// IAstVisitor
|
||||
@@ -46,17 +48,15 @@ type
|
||||
implementation
|
||||
|
||||
uses
|
||||
Myc.Data.Scalar,
|
||||
Myc.Data.Decimal;
|
||||
Myc.Data.Scalar;
|
||||
|
||||
{ TPrettyPrintVisitor }
|
||||
|
||||
constructor TPrettyPrintVisitor.Create(AIndentLevel: Integer);
|
||||
constructor TPrettyPrintVisitor.Create;
|
||||
begin
|
||||
inherited Create;
|
||||
FBuilder := TStringBuilder.Create;
|
||||
FIndentLevel := 0;
|
||||
FIndentLevel := AIndentLevel;
|
||||
end;
|
||||
|
||||
destructor TPrettyPrintVisitor.Destroy;
|
||||
@@ -72,119 +72,126 @@ end;
|
||||
|
||||
procedure TPrettyPrintVisitor.Indent;
|
||||
begin
|
||||
inc(FIndentLevel, 4);
|
||||
inc(FIndentLevel, 2);
|
||||
end;
|
||||
|
||||
procedure TPrettyPrintVisitor.Unindent;
|
||||
begin
|
||||
dec(FIndentLevel, 4);
|
||||
dec(FIndentLevel, 2);
|
||||
end;
|
||||
|
||||
procedure TPrettyPrintVisitor.AppendLine(const S: string);
|
||||
procedure TPrettyPrintVisitor.Append(const S: string);
|
||||
begin
|
||||
FBuilder.Append(S);
|
||||
end;
|
||||
|
||||
procedure TPrettyPrintVisitor.NewLine;
|
||||
begin
|
||||
FBuilder.AppendLine;
|
||||
FBuilder.Append(''.PadLeft(FIndentLevel));
|
||||
FBuilder.AppendLine(S);
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.Execute(const RootNode: IAstNode): TDataValue;
|
||||
begin
|
||||
Result := RootNode.Accept(Self);
|
||||
if Assigned(RootNode) then
|
||||
RootNode.Accept(Self);
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitConstant(const Node: IConstantNode): TDataValue;
|
||||
var
|
||||
val: TDataValue;
|
||||
begin
|
||||
AppendLine(Format('Constant (%s)', [Node.Value.ToString]));
|
||||
val := Node.Value;
|
||||
if val.Kind = vkText then
|
||||
Append('"' + val.AsText + '"')
|
||||
else
|
||||
Append(val.ToString);
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitIdentifier(const Node: IIdentifierNode): TDataValue;
|
||||
begin
|
||||
AppendLine(Format('Identifier (%s)', [Node.Name]));
|
||||
Append(Node.Name);
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitBinaryExpression(const Node: IBinaryExpressionNode): TDataValue;
|
||||
begin
|
||||
AppendLine(Format('BinaryExpr "%s"', [Node.Operator.ToString]));
|
||||
Indent;
|
||||
Append('(' + Node.Operator.ToString);
|
||||
Append(' ');
|
||||
Node.Left.Accept(Self);
|
||||
Append(' ');
|
||||
Node.Right.Accept(Self);
|
||||
Unindent;
|
||||
Append(')');
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitUnaryExpression(const Node: IUnaryExpressionNode): TDataValue;
|
||||
begin
|
||||
AppendLine(Format('UnaryExpr "%s"', [Node.Operator.ToString]));
|
||||
Indent;
|
||||
Append('(' + Node.Operator.ToString);
|
||||
Append(' ');
|
||||
Node.Right.Accept(Self);
|
||||
Unindent;
|
||||
Append(')');
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitIfExpression(const Node: IIfExpressionNode): TDataValue;
|
||||
begin
|
||||
AppendLine('IfExpr');
|
||||
Indent;
|
||||
AppendLine('Condition:');
|
||||
Indent;
|
||||
Append('(if ');
|
||||
Node.Condition.Accept(Self);
|
||||
Unindent;
|
||||
AppendLine('Then:');
|
||||
Indent;
|
||||
NewLine;
|
||||
Node.ThenBranch.Accept(Self);
|
||||
Unindent;
|
||||
if Node.ElseBranch <> nil then
|
||||
if Assigned(Node.ElseBranch) then
|
||||
begin
|
||||
AppendLine('Else:');
|
||||
Indent;
|
||||
NewLine;
|
||||
Node.ElseBranch.Accept(Self);
|
||||
Unindent;
|
||||
end;
|
||||
Unindent;
|
||||
NewLine;
|
||||
Append(')');
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitTernaryExpression(const Node: ITernaryExpressionNode): TDataValue;
|
||||
begin
|
||||
AppendLine('TernaryExpr');
|
||||
Indent;
|
||||
AppendLine('Condition:');
|
||||
Indent;
|
||||
Append('(if ');
|
||||
Node.Condition.Accept(Self);
|
||||
Unindent;
|
||||
AppendLine('Then:');
|
||||
Indent;
|
||||
NewLine;
|
||||
Node.ThenBranch.Accept(Self);
|
||||
Unindent;
|
||||
AppendLine('Else:');
|
||||
Indent;
|
||||
NewLine;
|
||||
Node.ElseBranch.Accept(Self);
|
||||
Unindent;
|
||||
Unindent;
|
||||
NewLine;
|
||||
Append(')');
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitLambdaExpression(const Node: ILambdaExpressionNode): TDataValue;
|
||||
var
|
||||
param: IIdentifierNode;
|
||||
paramNames: TStringList;
|
||||
sb: TStringBuilder;
|
||||
begin
|
||||
paramNames := TStringList.Create;
|
||||
sb := TStringBuilder.Create;
|
||||
try
|
||||
for param in Node.Parameters do
|
||||
paramNames.Add(param.Name);
|
||||
AppendLine(Format('Lambda (params: %s)', [paramNames.CommaText]));
|
||||
sb.Append(param.Name + ' ');
|
||||
if sb.Length > 0 then
|
||||
sb.Remove(sb.Length - 1, 1);
|
||||
|
||||
Append('(fn [' + sb.ToString + ']');
|
||||
finally
|
||||
paramNames.Free;
|
||||
sb.Free;
|
||||
end;
|
||||
|
||||
Indent;
|
||||
AppendLine('Body:');
|
||||
Indent;
|
||||
NewLine;
|
||||
Node.Body.Accept(Self);
|
||||
Unindent;
|
||||
Unindent;
|
||||
NewLine;
|
||||
Append(')');
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
@@ -192,18 +199,21 @@ function TPrettyPrintVisitor.VisitFunctionCall(const Node: IFunctionCallNode): T
|
||||
var
|
||||
arg: IAstNode;
|
||||
begin
|
||||
AppendLine('FunctionCall');
|
||||
Indent;
|
||||
AppendLine('Callee:');
|
||||
Indent;
|
||||
Append('(');
|
||||
Node.Callee.Accept(Self);
|
||||
Unindent;
|
||||
AppendLine('Arguments:');
|
||||
|
||||
Indent;
|
||||
for arg in Node.Arguments do
|
||||
begin
|
||||
NewLine;
|
||||
arg.Accept(Self);
|
||||
end;
|
||||
Unindent;
|
||||
Unindent;
|
||||
|
||||
if Length(Node.Arguments) > 0 then
|
||||
NewLine;
|
||||
|
||||
Append(')');
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
@@ -211,14 +221,17 @@ function TPrettyPrintVisitor.VisitRecurNode(const Node: IRecurNode): TDataValue;
|
||||
var
|
||||
arg: IAstNode;
|
||||
begin
|
||||
AppendLine('Recur');
|
||||
Indent;
|
||||
AppendLine('Arguments:');
|
||||
Append('(recur');
|
||||
Indent;
|
||||
for arg in Node.Arguments do
|
||||
begin
|
||||
NewLine;
|
||||
arg.Accept(Self);
|
||||
end;
|
||||
Unindent;
|
||||
Unindent;
|
||||
if Length(Node.Arguments) > 0 then
|
||||
NewLine;
|
||||
Append(')');
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
@@ -226,102 +239,88 @@ function TPrettyPrintVisitor.VisitBlockExpression(const Node: IBlockExpressionNo
|
||||
var
|
||||
expr: IAstNode;
|
||||
begin
|
||||
AppendLine('Block');
|
||||
Append('(do');
|
||||
Indent;
|
||||
for expr in Node.Expressions do
|
||||
begin
|
||||
NewLine;
|
||||
expr.Accept(Self);
|
||||
end;
|
||||
Unindent;
|
||||
NewLine;
|
||||
Append(')');
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitVariableDeclaration(const Node: IVariableDeclarationNode): TDataValue;
|
||||
begin
|
||||
AppendLine(Format('VarDecl (%s)', [Node.Identifier.Name]));
|
||||
Append('(def ');
|
||||
Node.Identifier.Accept(Self);
|
||||
if Assigned(Node.Initializer) then
|
||||
begin
|
||||
Indent;
|
||||
Append(' ');
|
||||
Node.Initializer.Accept(Self);
|
||||
Unindent;
|
||||
end;
|
||||
Append(')');
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitAssignment(const Node: IAssignmentNode): TDataValue;
|
||||
begin
|
||||
// Print the assignment node.
|
||||
AppendLine(Format('Assignment (%s)', [Node.Identifier.Name]));
|
||||
Indent;
|
||||
Append('(assign ');
|
||||
Node.Identifier.Accept(Self);
|
||||
Append(' ');
|
||||
Node.Value.Accept(Self);
|
||||
Unindent;
|
||||
Append(')');
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitIndexer(const Node: IIndexerNode): TDataValue;
|
||||
begin
|
||||
AppendLine('Indexer');
|
||||
Indent;
|
||||
AppendLine('Base:');
|
||||
Indent;
|
||||
Append('(get ');
|
||||
Node.Base.Accept(Self);
|
||||
Unindent;
|
||||
AppendLine('Index:');
|
||||
Indent;
|
||||
Append(' ');
|
||||
Node.Index.Accept(Self);
|
||||
Unindent;
|
||||
Unindent;
|
||||
Append(')');
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitMemberAccess(const Node: IMemberAccessNode): TDataValue;
|
||||
begin
|
||||
AppendLine(Format('MemberAccess (Member: %s)', [Node.Member.Name]));
|
||||
Indent;
|
||||
AppendLine('Base:');
|
||||
Indent;
|
||||
Append('(.');
|
||||
Node.Member.Accept(Self);
|
||||
Append(' ');
|
||||
Node.Base.Accept(Self);
|
||||
Unindent;
|
||||
Unindent;
|
||||
Append(')');
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitCreateSeries(const Node: ICreateSeriesNode): TDataValue;
|
||||
begin
|
||||
AppendLine('CreateSeries');
|
||||
Indent;
|
||||
AppendLine('Definition: ' + Node.Definition);
|
||||
Unindent;
|
||||
Append(Format('(new-series "%s")', [Node.Definition]));
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitAddSeriesItem(const Node: IAddSeriesItemNode): TDataValue;
|
||||
begin
|
||||
AppendLine('AddSeriesItem');
|
||||
Indent;
|
||||
AppendLine('Series:');
|
||||
Indent;
|
||||
Append('(add-item ');
|
||||
Node.Series.Accept(Self);
|
||||
Unindent;
|
||||
AppendLine('Value:');
|
||||
Indent;
|
||||
Append(' ');
|
||||
Node.Value.Accept(Self);
|
||||
Unindent;
|
||||
if Assigned(Node.Lookback) then
|
||||
begin
|
||||
AppendLine('Lookback:');
|
||||
Indent;
|
||||
Append(' ');
|
||||
Node.Lookback.Accept(Self);
|
||||
Unindent;
|
||||
end;
|
||||
Unindent;
|
||||
Append(')');
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitSeriesLength(const Node: ISeriesLengthNode): TDataValue;
|
||||
begin
|
||||
AppendLine('SeriesLength');
|
||||
Indent;
|
||||
Append('(count ');
|
||||
Node.Series.Accept(Self);
|
||||
Unindent;
|
||||
Append(')');
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user