Binder refactoring, Monster refactoring
This commit is contained in:
+61
-84
@@ -29,7 +29,7 @@ var
|
||||
atom ::= number | string | identifier | keyword
|
||||
|
||||
(* ---------------------------------------------------------------------- *)
|
||||
(* ---- Reader-Macros (Syntactic Sugar) ---- *)
|
||||
(* ---- Reader-Macros (Syntactic Sugar) ---- *)
|
||||
(* ---------------------------------------------------------------------- *)
|
||||
|
||||
reader_macro ::= "'" expression (* (quote ...) *)
|
||||
@@ -38,7 +38,7 @@ var
|
||||
| "~@" expression (* (unquote-splicing ...) *)
|
||||
|
||||
(* ---------------------------------------------------------------------- *)
|
||||
(* ---- Lists (S-Expressions) ---- *)
|
||||
(* ---- Lists (S-Expressions) ---- *)
|
||||
(* ---------------------------------------------------------------------- *)
|
||||
|
||||
(* A list is the primary structure for code. Empty lists () are invalid. *)
|
||||
@@ -64,7 +64,7 @@ var
|
||||
function_call ::= expression expression*
|
||||
|
||||
(* ---------------------------------------------------------------------- *)
|
||||
(* ---- Parameter Lists and Records ---- *)
|
||||
(* ---- Parameter Lists and Records ---- *)
|
||||
(* ---------------------------------------------------------------------- *)
|
||||
|
||||
(* A parameter list is *only* valid inside 'fn' and 'defmacro' *)
|
||||
@@ -181,6 +181,7 @@ type
|
||||
|
||||
// --- Internal Printer Implementation ---
|
||||
|
||||
// Inherits from the new non-generic TAstVisitor
|
||||
TPrettyPrintVisitor = class(TAstVisitor)
|
||||
private
|
||||
FBuilder: TStringBuilder;
|
||||
@@ -193,32 +194,33 @@ type
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
function GetResult: string;
|
||||
// IAstVisitor
|
||||
// Helper
|
||||
function Execute(const RootNode: IAstNode): TDataValue;
|
||||
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 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 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 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;
|
||||
// Override abstract procedures from TAstVisitor
|
||||
procedure VisitConstant(const Node: IConstantNode); override;
|
||||
procedure VisitIdentifier(const Node: IIdentifierNode); override;
|
||||
procedure VisitKeyword(const Node: IKeywordNode); override;
|
||||
procedure VisitBinaryExpression(const Node: IBinaryExpressionNode); override;
|
||||
procedure VisitUnaryExpression(const Node: IUnaryExpressionNode); override;
|
||||
procedure VisitIfExpression(const Node: IIfExpressionNode); override;
|
||||
procedure VisitTernaryExpression(const Node: ITernaryExpressionNode); override;
|
||||
procedure VisitLambdaExpression(const Node: ILambdaExpressionNode); override;
|
||||
procedure VisitMacroDefinition(const Node: IMacroDefinitionNode); override;
|
||||
procedure VisitQuasiquote(const Node: IQuasiquoteNode); override;
|
||||
procedure VisitUnquote(const Node: IUnquoteNode); override;
|
||||
procedure VisitUnquoteSplicing(const Node: IUnquoteSplicingNode); override;
|
||||
procedure VisitFunctionCall(const Node: IFunctionCallNode); override;
|
||||
procedure VisitMacroExpansionNode(const Node: IMacroExpansionNode); override;
|
||||
procedure VisitBlockExpression(const Node: IBlockExpressionNode); override;
|
||||
procedure VisitVariableDeclaration(const Node: IVariableDeclarationNode); override;
|
||||
procedure VisitAssignment(const Node: IAssignmentNode); override;
|
||||
procedure VisitIndexer(const Node: IIndexerNode); override;
|
||||
procedure VisitMemberAccess(const Node: IMemberAccessNode); override;
|
||||
procedure VisitRecordLiteral(const Node: IRecordLiteralNode); override;
|
||||
procedure VisitCreateSeries(const Node: ICreateSeriesNode); override;
|
||||
procedure VisitAddSeriesItem(const Node: IAddSeriesItemNode); override;
|
||||
procedure VisitSeriesLength(const Node: ISeriesLengthNode); override;
|
||||
procedure VisitRecurNode(const Node: IRecurNode); override;
|
||||
end;
|
||||
|
||||
{ TLexer }
|
||||
@@ -592,7 +594,7 @@ begin
|
||||
if (Length(tailNodes) <> 3) or (tailTokens[0].Kind <> tkIdentifier) then
|
||||
raise Exception.Create('Syntax Error: ''defmacro'' requires a name, a parameter list, and a body.');
|
||||
|
||||
var macroName := IIdentifierNode(tailNodes[0]);
|
||||
var macroName := tailNodes[0].AsIdentifier;
|
||||
var macroParams := elements[2].Params;
|
||||
|
||||
if tailTokens[2].Kind <> tkBacktick then
|
||||
@@ -670,7 +672,7 @@ begin
|
||||
begin
|
||||
NextToken;
|
||||
expr := ParseExpression;
|
||||
Result.Node := TAst.UnquoteSplicing(expr.Node);
|
||||
Result.Node := TAst.UnquoteSplicing(expr.Node.AsQuasiquote);
|
||||
end
|
||||
else
|
||||
begin
|
||||
@@ -781,7 +783,7 @@ begin
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitConstant(const Node: IConstantNode): TDataValue;
|
||||
procedure TPrettyPrintVisitor.VisitConstant(const Node: IConstantNode);
|
||||
var
|
||||
val: TDataValue;
|
||||
begin
|
||||
@@ -790,22 +792,19 @@ begin
|
||||
Append('"' + val.AsText + '"')
|
||||
else
|
||||
Append(val.ToString);
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitIdentifier(const Node: IIdentifierNode): TDataValue;
|
||||
procedure TPrettyPrintVisitor.VisitIdentifier(const Node: IIdentifierNode);
|
||||
begin
|
||||
Append(Node.Name);
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitKeyword(const Node: IKeywordNode): TDataValue;
|
||||
procedure TPrettyPrintVisitor.VisitKeyword(const Node: IKeywordNode);
|
||||
begin
|
||||
Append(':' + Node.Value.Name);
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitBinaryExpression(const Node: IBinaryExpressionNode): TDataValue;
|
||||
procedure TPrettyPrintVisitor.VisitBinaryExpression(const Node: IBinaryExpressionNode);
|
||||
begin
|
||||
Append('(' + Node.Operator.ToString);
|
||||
Append(' ');
|
||||
@@ -813,19 +812,17 @@ begin
|
||||
Append(' ');
|
||||
Node.Right.Accept(Self);
|
||||
Append(')');
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitUnaryExpression(const Node: IUnaryExpressionNode): TDataValue;
|
||||
procedure TPrettyPrintVisitor.VisitUnaryExpression(const Node: IUnaryExpressionNode);
|
||||
begin
|
||||
Append('(' + Node.Operator.ToString);
|
||||
Append(' ');
|
||||
Node.Right.Accept(Self);
|
||||
Append(')');
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitIfExpression(const Node: IIfExpressionNode): TDataValue;
|
||||
procedure TPrettyPrintVisitor.VisitIfExpression(const Node: IIfExpressionNode);
|
||||
begin
|
||||
Append('(if ');
|
||||
Node.Condition.Accept(Self);
|
||||
@@ -840,10 +837,9 @@ begin
|
||||
Unindent;
|
||||
NewLine;
|
||||
Append(')');
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitTernaryExpression(const Node: ITernaryExpressionNode): TDataValue;
|
||||
procedure TPrettyPrintVisitor.VisitTernaryExpression(const Node: ITernaryExpressionNode);
|
||||
begin
|
||||
Append('(? ');
|
||||
Node.Condition.Accept(Self);
|
||||
@@ -855,17 +851,15 @@ begin
|
||||
Unindent;
|
||||
NewLine;
|
||||
Append(')');
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitLambdaExpression(const Node: ILambdaExpressionNode): TDataValue;
|
||||
procedure TPrettyPrintVisitor.VisitLambdaExpression(const Node: ILambdaExpressionNode);
|
||||
var
|
||||
param: IIdentifierNode;
|
||||
sb: TStringBuilder;
|
||||
begin
|
||||
sb := TStringBuilder.Create;
|
||||
try
|
||||
for param in Node.Parameters do
|
||||
for var param in Node.Parameters do
|
||||
sb.Append(param.Name + ' ');
|
||||
if sb.Length > 0 then
|
||||
sb.Remove(sb.Length - 1, 1); // remove trailing space
|
||||
@@ -881,17 +875,15 @@ begin
|
||||
Unindent;
|
||||
NewLine;
|
||||
Append(')');
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue;
|
||||
procedure TPrettyPrintVisitor.VisitMacroDefinition(const Node: IMacroDefinitionNode);
|
||||
var
|
||||
param: IIdentifierNode;
|
||||
sb: TStringBuilder;
|
||||
begin
|
||||
sb := TStringBuilder.Create;
|
||||
try
|
||||
for param in Node.Parameters do
|
||||
for var param in Node.Parameters do
|
||||
sb.Append(param.Name + ' ');
|
||||
if sb.Length > 0 then
|
||||
sb.Remove(sb.Length - 1, 1);
|
||||
@@ -907,33 +899,29 @@ begin
|
||||
Unindent;
|
||||
NewLine;
|
||||
Append(')');
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitQuasiquote(const Node: IQuasiquoteNode): TDataValue;
|
||||
procedure TPrettyPrintVisitor.VisitQuasiquote(const Node: IQuasiquoteNode);
|
||||
begin
|
||||
Append('`');
|
||||
Node.Expression.Accept(Self);
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitUnquote(const Node: IUnquoteNode): TDataValue;
|
||||
procedure TPrettyPrintVisitor.VisitUnquote(const Node: IUnquoteNode);
|
||||
begin
|
||||
Append('~');
|
||||
Node.Expression.Accept(Self);
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): TDataValue;
|
||||
procedure TPrettyPrintVisitor.VisitUnquoteSplicing(const Node: IUnquoteSplicingNode);
|
||||
begin
|
||||
// To handle '~@', we need to check if the expression is an identifier '@'.
|
||||
// However, the parser logic now handles this, so we just print '~@'.
|
||||
Append('~@');
|
||||
Node.Expression.Accept(Self);
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitFunctionCall(const Node: IFunctionCallNode): TDataValue;
|
||||
procedure TPrettyPrintVisitor.VisitFunctionCall(const Node: IFunctionCallNode);
|
||||
var
|
||||
arg: IAstNode;
|
||||
begin
|
||||
@@ -942,7 +930,7 @@ begin
|
||||
begin
|
||||
Append('''');
|
||||
Node.Arguments[0].Accept(Self);
|
||||
exit(TDataValue.Void);
|
||||
exit;
|
||||
end;
|
||||
|
||||
Append('(');
|
||||
@@ -957,17 +945,16 @@ begin
|
||||
Unindent;
|
||||
|
||||
Append(')');
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitMacroExpansionNode(const Node: IMacroExpansionNode): TDataValue;
|
||||
procedure TPrettyPrintVisitor.VisitMacroExpansionNode(const Node: IMacroExpansionNode);
|
||||
begin
|
||||
// For pretty-printing, show the original macro call, not the expanded body.
|
||||
// Delegate to the regular VisitFunctionCall to print it as such.
|
||||
Result := VisitFunctionCall(Node);
|
||||
VisitFunctionCall(Node);
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitRecurNode(const Node: IRecurNode): TDataValue;
|
||||
procedure TPrettyPrintVisitor.VisitRecurNode(const Node: IRecurNode);
|
||||
var
|
||||
arg: IAstNode;
|
||||
begin
|
||||
@@ -981,10 +968,9 @@ begin
|
||||
Unindent;
|
||||
|
||||
Append(')');
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitBlockExpression(const Node: IBlockExpressionNode): TDataValue;
|
||||
procedure TPrettyPrintVisitor.VisitBlockExpression(const Node: IBlockExpressionNode);
|
||||
var
|
||||
expr: IAstNode;
|
||||
begin
|
||||
@@ -998,10 +984,9 @@ begin
|
||||
Unindent;
|
||||
NewLine;
|
||||
Append(')');
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitVariableDeclaration(const Node: IVariableDeclarationNode): TDataValue;
|
||||
procedure TPrettyPrintVisitor.VisitVariableDeclaration(const Node: IVariableDeclarationNode);
|
||||
begin
|
||||
Append('(def ');
|
||||
Node.Identifier.Accept(Self);
|
||||
@@ -1011,47 +996,43 @@ begin
|
||||
Node.Initializer.Accept(Self);
|
||||
end;
|
||||
Append(')');
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitAssignment(const Node: IAssignmentNode): TDataValue;
|
||||
procedure TPrettyPrintVisitor.VisitAssignment(const Node: IAssignmentNode);
|
||||
begin
|
||||
Append('(assign ');
|
||||
Node.Identifier.Accept(Self);
|
||||
Append(' ');
|
||||
Node.Value.Accept(Self);
|
||||
Append(')');
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitIndexer(const Node: IIndexerNode): TDataValue;
|
||||
procedure TPrettyPrintVisitor.VisitIndexer(const Node: IIndexerNode);
|
||||
begin
|
||||
Append('(get ');
|
||||
Node.Base.Accept(Self);
|
||||
Append(' ');
|
||||
Node.Index.Accept(Self);
|
||||
Append(')');
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitMemberAccess(const Node: IMemberAccessNode): TDataValue;
|
||||
procedure TPrettyPrintVisitor.VisitMemberAccess(const Node: IMemberAccessNode);
|
||||
begin
|
||||
Append('(.');
|
||||
Node.Member.Accept(Self);
|
||||
Append(' ');
|
||||
Node.Base.Accept(Self);
|
||||
Append(')');
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitRecordLiteral(const Node: IRecordLiteralNode): TDataValue;
|
||||
procedure TPrettyPrintVisitor.VisitRecordLiteral(const Node: IRecordLiteralNode);
|
||||
var
|
||||
field: TRecordFieldLiteral;
|
||||
begin
|
||||
if Length(Node.Fields) = 0 then
|
||||
begin
|
||||
Append('{}');
|
||||
exit(TDataValue.Void);
|
||||
exit;
|
||||
end;
|
||||
|
||||
Append('{');
|
||||
@@ -1066,16 +1047,14 @@ begin
|
||||
Unindent;
|
||||
NewLine;
|
||||
Append('}');
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitCreateSeries(const Node: ICreateSeriesNode): TDataValue;
|
||||
procedure TPrettyPrintVisitor.VisitCreateSeries(const Node: ICreateSeriesNode);
|
||||
begin
|
||||
Append(Format('(new-series "%s")', [Node.Definition]));
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitAddSeriesItem(const Node: IAddSeriesItemNode): TDataValue;
|
||||
procedure TPrettyPrintVisitor.VisitAddSeriesItem(const Node: IAddSeriesItemNode);
|
||||
begin
|
||||
Append('(add-item ');
|
||||
Node.Series.Accept(Self);
|
||||
@@ -1087,15 +1066,13 @@ begin
|
||||
Node.Lookback.Accept(Self);
|
||||
end;
|
||||
Append(')');
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
function TPrettyPrintVisitor.VisitSeriesLength(const Node: ISeriesLengthNode): TDataValue;
|
||||
procedure TPrettyPrintVisitor.VisitSeriesLength(const Node: ISeriesLengthNode);
|
||||
begin
|
||||
Append('(count ');
|
||||
Node.Series.Accept(Self);
|
||||
Append(')');
|
||||
Result := TDataValue.Void;
|
||||
end;
|
||||
|
||||
{ TAstScript }
|
||||
|
||||
Reference in New Issue
Block a user