AST list refactoring

This commit is contained in:
Michael Schimmel
2026-01-04 22:41:44 +01:00
parent 2a7e6626ad
commit 242ec9a56e
27 changed files with 815 additions and 1076 deletions
+66 -66
View File
@@ -26,10 +26,10 @@ type
function VisitIdentifier(const N: IAstNode): TVoid;
function VisitKeyword(const N: IAstNode): TVoid;
function VisitParameterList(const N: IAstNode): TVoid;
function VisitArgumentList(const N: IAstNode): TVoid;
function VisitExpressionList(const N: IAstNode): TVoid;
function VisitRecordFieldList(const N: IAstNode): TVoid;
// Tuple handles generic lists [ ... ]
function VisitTuple(const N: IAstNode): TVoid;
// Single Element
function VisitRecordField(const N: IAstNode): TVoid;
function VisitIfExpression(const N: IAstNode): TVoid;
@@ -91,10 +91,7 @@ begin
Register(akIdentifier, VisitIdentifier);
Register(akKeyword, VisitKeyword);
Register(akParameterList, VisitParameterList);
Register(akArgumentList, VisitArgumentList);
Register(akExpressionList, VisitExpressionList);
Register(akRecordFieldList, VisitRecordFieldList);
Register(akTuple, VisitTuple);
Register(akRecordField, VisitRecordField);
Register(akIfExpression, VisitIfExpression);
@@ -156,7 +153,7 @@ begin
FBuilder.Append(''.PadLeft(FIndentLevel));
end;
// --- Implementations (Clean & Typed) ---
// --- Implementations ---
function TPrettyPrintVisitor.VisitPipeInput(const N: IAstNode): TVoid;
var
@@ -241,67 +238,22 @@ begin
Append('...');
end;
function TPrettyPrintVisitor.VisitParameterList(const N: IAstNode): TVoid;
function TPrettyPrintVisitor.VisitTuple(const N: IAstNode): TVoid;
var
L: IParameterList;
T: ITupleNode;
i: Integer;
begin
L := N.AsParameterList;
T := N.AsTuple;
Append('[');
for i := 0 to L.Count - 1 do
for i := 0 to T.Count - 1 do
begin
if i > 0 then
Append(' ');
Visit(L[i]);
Visit(T.Items[i]);
end;
Append(']');
end;
function TPrettyPrintVisitor.VisitArgumentList(const N: IAstNode): TVoid;
var
L: IArgumentList;
i: Integer;
begin
L := N.AsArgumentList;
for i := 0 to L.Count - 1 do
begin
Append(' ');
Visit(L[i]);
end;
end;
function TPrettyPrintVisitor.VisitExpressionList(const N: IAstNode): TVoid;
var
L: IExpressionList;
item: IAstNode;
begin
L := N.AsExpressionList;
Indent;
for item in L do
begin
NewLine;
Visit(item);
end;
Unindent;
NewLine;
end;
function TPrettyPrintVisitor.VisitRecordFieldList(const N: IAstNode): TVoid;
var
L: IRecordFieldList;
item: IRecordFieldNode;
begin
L := N.AsRecordFieldList;
Indent;
for item in L do
begin
NewLine;
Visit(item);
end;
Unindent;
NewLine;
end;
function TPrettyPrintVisitor.VisitRecordField(const N: IAstNode): TVoid;
var
F: IRecordFieldNode;
@@ -359,6 +311,7 @@ var
begin
E := N.AsLambdaExpression;
Append('(fn ');
// Parameters is ITupleNode -> prints [ ... ] automatically
Visit(E.Parameters);
Indent;
NewLine;
@@ -376,6 +329,7 @@ begin
Append('(defmacro ');
Visit(M.Name);
Append(' ');
// Parameters is ITupleNode -> prints [ ... ] automatically
Visit(M.Parameters);
Indent;
NewLine;
@@ -406,17 +360,28 @@ end;
function TPrettyPrintVisitor.VisitFunctionCall(const N: IAstNode): TVoid;
var
C: IFunctionCallNode;
i: Integer;
args: ITupleNode;
begin
C := N.AsFunctionCall;
if (C.Callee.Kind = akIdentifier) and (C.Callee.AsIdentifier.Name = 'quote') and (C.Arguments.Count = 1) then
args := C.Arguments;
// Special case for 'quote'
if (C.Callee.Kind = akIdentifier) and (C.Callee.AsIdentifier.Name = 'quote') and (args.Count = 1) then
begin
Append('''');
Visit(C.Arguments[0]);
Visit(args.Items[0]);
exit;
end;
Append('(');
Visit(C.Callee);
Visit(C.Arguments);
// Manually iterate arguments tuple to avoid printing [...] inside ()
for i := 0 to args.Count - 1 do
begin
Append(' ');
Visit(args.Items[i]);
end;
Append(')');
end;
@@ -426,16 +391,41 @@ begin
end;
function TPrettyPrintVisitor.VisitRecurNode(const N: IAstNode): TVoid;
var
R: IRecurNode;
i: Integer;
args: ITupleNode;
begin
R := N.AsRecur;
args := R.Arguments;
Append('(recur');
Visit(N.AsRecur.Arguments);
// Manually iterate arguments
for i := 0 to args.Count - 1 do
begin
Append(' ');
Visit(args.Items[i]);
end;
Append(')');
end;
function TPrettyPrintVisitor.VisitBlockExpression(const N: IAstNode): TVoid;
var
B: IBlockExpressionNode;
exprs: ITupleNode;
i: Integer;
begin
B := N.AsBlockExpression;
exprs := B.Expressions;
Append('(do');
Visit(N.AsBlockExpression.Expressions);
Indent;
// Manually iterate expressions tuple for newlines
for i := 0 to exprs.Count - 1 do
begin
NewLine;
Visit(exprs.Items[i]);
end;
Unindent;
NewLine;
Append(')');
end;
@@ -493,15 +483,25 @@ end;
function TPrettyPrintVisitor.VisitRecordLiteral(const N: IAstNode): TVoid;
var
R: IRecordLiteralNode;
fields: ITupleNode;
i: Integer;
begin
R := N.AsRecordLiteral;
if R.Fields.Count = 0 then
fields := R.Fields;
if fields.Count = 0 then
begin
Append('{}');
exit;
end;
Append('{');
Visit(R.Fields);
Indent;
for i := 0 to fields.Count - 1 do
begin
NewLine;
Visit(fields.Items[i]);
end;
Unindent;
NewLine;
Append('}');
end;