ITupleNode signature change

This commit is contained in:
Michael Schimmel
2026-01-06 11:37:18 +01:00
parent 264314cd93
commit 40ed51aef8
23 changed files with 340 additions and 270 deletions
+30 -18
View File
@@ -104,8 +104,8 @@ end;
function TTestAstBinder.Unwrap(const Node: IAstNode): IAstNode;
begin
if (Node.Kind = akBlockExpression) and (Node.AsBlockExpression.Expressions.Count = 1) then
Result := Node.AsBlockExpression.Expressions[0]
if (Node.Kind = akBlockExpression) and (Length(Node.AsBlockExpression.Expressions.Elements) = 1) then
Result := Node.AsBlockExpression.Expressions.Elements[0]
else
Result := Node;
end;
@@ -132,7 +132,7 @@ begin
block := bound.AsBlockExpression;
// Check definition of 'b'
decl := block.Expressions[1].AsVariableDeclaration;
decl := block.Expressions.Elements[1].AsVariableDeclaration;
initIdent := decl.Initializer.AsIdentifier;
// 'a' is Slot 0. 'b' is Slot 1.
@@ -177,7 +177,7 @@ begin
Assert.IsFalse(log.HasErrors);
block := bound.AsBlockExpression;
ident := block.Expressions[1].AsIdentifier;
ident := block.Expressions.Elements[1].AsIdentifier;
Assert.AreEqual<TAddressKind>(akLocalOrParent, ident.Address.Kind);
Assert.AreEqual<Integer>(0, ident.Address.ScopeDepth);
Assert.AreEqual<Integer>(0, ident.Address.SlotIndex);
@@ -192,14 +192,15 @@ var
innerUsage: IIdentifierNode;
log: ICompilerLog;
begin
root :=
TAst.Block([TAst.VarDecl(TAst.Identifier('x'), TAst.Constant(1)), TAst.LambdaExpr([TAst.Identifier('x')], TAst.Identifier('x'))]);
// Convert array to tuple for lambda params
var paramTuple := TAst.Tuple([TAst.Identifier('x')]);
root := TAst.Block([TAst.VarDecl(TAst.Identifier('x'), TAst.Constant(1)), TAst.LambdaExpr(nil, paramTuple, TAst.Identifier('x'))]);
bound := Bind(root, layout, log);
Assert.IsFalse(log.HasErrors);
block := bound.AsBlockExpression;
innerLambda := block.Expressions[1].AsLambdaExpression;
innerLambda := block.Expressions.Elements[1].AsLambdaExpression;
innerUsage := innerLambda.Body.AsIdentifier;
Assert.AreEqual<Integer>(1, innerUsage.Address.SlotIndex); // Parameter x (Slot 1 because <self> is Slot 0)
end;
@@ -211,7 +212,8 @@ var
log: ICompilerLog;
begin
// (do (fn [] (def a 1)) a) -> 'a' is inside lambda, not visible outside
root := TAst.Block([TAst.LambdaExpr([], TAst.VarDecl(TAst.Identifier('a'), TAst.Constant(1))), TAst.Identifier('a')]);
var emptyParams := TAst.Tuple([]);
root := TAst.Block([TAst.LambdaExpr(nil, emptyParams, TAst.VarDecl(TAst.Identifier('a'), TAst.Constant(1))), TAst.Identifier('a')]);
Bind(root, layout, log);
@@ -230,14 +232,16 @@ var
lambda: ILambdaExpressionNode;
log: ICompilerLog;
begin
root := TAst.LambdaExpr([TAst.Identifier('p1')], TAst.Nop);
// Use Tuple factory for params
var params := TAst.Tuple([TAst.Identifier('p1')]);
root := TAst.LambdaExpr(nil, params, TAst.Nop);
bound := Unwrap(Bind(root, layout, log));
Assert.IsFalse(log.HasErrors);
lambda := bound.AsLambdaExpression;
// FIX: Cast element to Identifier to access Address
Assert.AreEqual<Integer>(1, lambda.Parameters[0].AsIdentifier.Address.SlotIndex); // Slot 0 is reserved for <self>
Assert.AreEqual<Integer>(1, lambda.Parameters.Elements[0].AsIdentifier.Address.SlotIndex); // Slot 0 is reserved for <self>
end;
procedure TTestAstBinder.Test_MultipleParameters_AreBoundCorrectly;
@@ -247,15 +251,17 @@ var
lambda: ILambdaExpressionNode;
log: ICompilerLog;
begin
root := TAst.LambdaExpr([TAst.Identifier('a'), TAst.Identifier('b')], TAst.Nop);
// Use Tuple factory for params
var params := TAst.Tuple([TAst.Identifier('a'), TAst.Identifier('b')]);
root := TAst.LambdaExpr(nil, params, TAst.Nop);
bound := Unwrap(Bind(root, layout, log));
Assert.IsFalse(log.HasErrors);
lambda := bound.AsLambdaExpression;
// FIX: Cast elements to Identifier
Assert.AreEqual<Integer>(1, lambda.Parameters[0].AsIdentifier.Address.SlotIndex);
Assert.AreEqual<Integer>(2, lambda.Parameters[1].AsIdentifier.Address.SlotIndex);
Assert.AreEqual<Integer>(1, lambda.Parameters.Elements[0].AsIdentifier.Address.SlotIndex);
Assert.AreEqual<Integer>(2, lambda.Parameters.Elements[1].AsIdentifier.Address.SlotIndex);
end;
// ------------------------------------------------------------------------------------------------
@@ -271,13 +277,14 @@ var
bodyIdent: IIdentifierNode;
log: ICompilerLog;
begin
root := TAst.Block([TAst.VarDecl(TAst.Identifier('x'), TAst.Constant(99)), TAst.LambdaExpr([], TAst.Identifier('x'))]);
var emptyParams := TAst.Tuple([]);
root := TAst.Block([TAst.VarDecl(TAst.Identifier('x'), TAst.Constant(99)), TAst.LambdaExpr(nil, emptyParams, TAst.Identifier('x'))]);
bound := Bind(root, layout, log);
Assert.IsFalse(log.HasErrors);
block := bound.AsBlockExpression;
lambda := block.Expressions[1].AsLambdaExpression;
lambda := block.Expressions.Elements[1].AsLambdaExpression;
bodyIdent := lambda.Body.AsIdentifier;
// Inside the lambda, 'x' is accessed via an Upvalue
@@ -293,16 +300,20 @@ var
midLambda, innerLambda: ILambdaExpressionNode;
log: ICompilerLog;
begin
var emptyParams := TAst.Tuple([]);
root :=
TAst.Block(
[TAst.VarDecl(TAst.Identifier('top'), TAst.Constant(100)), TAst.LambdaExpr([], TAst.LambdaExpr([], TAst.Identifier('top')))]
[
TAst.VarDecl(TAst.Identifier('top'), TAst.Constant(100)),
TAst.LambdaExpr(nil, emptyParams, TAst.LambdaExpr(nil, emptyParams, TAst.Identifier('top')))
]
);
bound := Bind(root, layout, log);
Assert.IsFalse(log.HasErrors);
outerBlock := bound.AsBlockExpression;
midLambda := outerBlock.Expressions[1].AsLambdaExpression;
midLambda := outerBlock.Expressions.Elements[1].AsLambdaExpression;
innerLambda := midLambda.Body.AsLambdaExpression;
// Inner lambda accesses 'top' via upvalue
@@ -316,7 +327,8 @@ var
lambda: ILambdaExpressionNode;
log: ICompilerLog;
begin
root := TAst.LambdaExpr([], TAst.Identifier('<self>'));
var emptyParams := TAst.Tuple([]);
root := TAst.LambdaExpr(nil, emptyParams, TAst.Identifier('<self>'));
bound := Unwrap(Bind(root, layout, log));
Assert.IsFalse(log.HasErrors);