Ast ternary expr replaced by cond expr

This commit is contained in:
Michael Schimmel
2025-12-07 12:06:29 +01:00
parent 91c4d57aaf
commit 1d13d0cdaa
15 changed files with 449 additions and 180 deletions
+25 -10
View File
@@ -50,7 +50,7 @@ var
list_content ::= special_form | function_call
special_form ::= "if" expression expression expression?
| "?" expression expression expression
| "?" (expression expression)* expression (* cond1 branch1 ... else *)
| "def" identifier expression?
| "defmacro" identifier parameter_list expression
| "assign" identifier expression
@@ -206,7 +206,7 @@ type
function VisitRecordField(const Node: IRecordFieldNode): TVoid; override;
function VisitIfExpression(const Node: IIfExpressionNode): TVoid; override;
function VisitTernaryExpression(const Node: ITernaryExpressionNode): 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;
@@ -642,9 +642,19 @@ begin
end
else if SameText(head.Token.Text, '?') then
begin
if Length(tailNodes) <> 3 then
Error('Syntax Error in ternary statement.');
Result := TAst.TernaryExpr(tailNodes[0], tailNodes[1], tailNodes[2], startLoc);
// (? test1 branch1 test2 branch2 ... else)
// Requires odd number of tailNodes (pairs + 1 else)
var count := Length(tailNodes);
if (count < 1) or ((count mod 2) = 0) then
Error('Syntax Error: ''?'' (cond) requires an odd number of arguments (pairs of condition/branch and one final else).');
var pairs: TArray<TCondPair>;
SetLength(pairs, count div 2);
for var i := 0 to High(pairs) do
pairs[i] := TCondPair.Create(tailNodes[i * 2], tailNodes[i * 2 + 1]);
var elseNode := tailNodes[High(tailNodes)];
Result := TAst.CondExpr(pairs, elseNode, startLoc);
end
else if SameText(head.Token.Text, 'def') then
begin
@@ -946,13 +956,18 @@ begin
Append(')');
end;
function TPrettyPrintVisitor.VisitTernaryExpression(const Node: ITernaryExpressionNode): TVoid;
function TPrettyPrintVisitor.VisitCondExpression(const Node: ICondExpressionNode): TVoid;
begin
Append('(? ');
Node.Condition.Accept(Self);
Append('(?');
Indent;
NewLine;
Node.ThenBranch.Accept(Self);
for var pair in Node.Pairs do
begin
NewLine;
pair.Condition.Accept(Self);
Append(' ');
pair.Branch.Accept(Self);
end;
// Else
NewLine;
Node.ElseBranch.Accept(Self);
Unindent;