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
+53 -46
View File
@@ -314,9 +314,11 @@ var
newDim: TArray<Integer>;
finalType: IStaticType;
elementsArray: TArray<IAstNode>;
begin
T := Node.AsTuple;
var count := T.Count;
elementsArray := T.Elements;
var count := Length(elementsArray);
SetLength(newElements, count);
SetLength(elementTypes, count);
@@ -325,7 +327,7 @@ begin
// Recursively type-check all elements first to determine their static types.
for i := 0 to count - 1 do
begin
newElements[i] := Accept(T.Items[i]);
newElements[i] := Accept(elementsArray[i]);
if newElements[i].IsTyped then
elementTypes[i] := newElements[i].AsTypedNode.StaticType
else
@@ -503,8 +505,7 @@ function TTypeChecker.VisitBlockExpression(const Node: IAstNode): IAstNode;
var
newBlock: IBlockExpressionNode;
blockType: IStaticType;
exprs: ITupleNode;
i: Integer;
exprs: TArray<IAstNode>;
begin
var transformedNode := inherited VisitBlockExpression(Node);
@@ -512,30 +513,25 @@ begin
raise ECompilationFailed.Create([TCompilerError.Create(elError, 'Internal Error: Block transformation returned nil.', Node)]);
newBlock := transformedNode.AsBlockExpression;
exprs := newBlock.Expressions;
exprs := newBlock.Expressions.Elements;
if exprs.Count > 0 then
if Length(exprs) > 0 then
begin
for i := 0 to exprs.Count - 1 do
begin
if exprs.Items[i] = nil then
raise ECompilationFailed.Create(
[TCompilerError.Create(elError, Format('Internal Error: Block expression #%d transformed to nil.', [i]), Node)]);
end;
blockType := exprs.Items[exprs.Count - 1].AsTypedNode.StaticType;
// The type of the block is the type of the last expression
blockType := exprs[High(exprs)].AsTypedNode.StaticType;
end
else
begin
blockType := TTypes.Void;
end;
Result := TAst.Block(Node.Identity, exprs, blockType);
Result := TAst.Block(Node.Identity, newBlock.Expressions, blockType);
end;
function TTypeChecker.VisitLambdaExpression(const Node: IAstNode): IAstNode;
var
L: ILambdaExpressionNode;
newParams: TArray<IIdentifierNode>;
newParams: TArray<IAstNode>;
newBody: IAstNode;
bodyType, methodType: IStaticType;
paramTypes: TArray<IStaticType>;
@@ -545,7 +541,7 @@ var
paramIdent: IIdentifierNode;
injectedType: IStaticType;
paramsTuple: ITupleNode;
paramsAsNodes: TArray<IAstNode>;
paramsElements: TArray<IAstNode>;
begin
L := Node.AsLambdaExpression;
@@ -566,12 +562,13 @@ begin
FCurrentContext := TTypeContext.Create(FCurrentContext, L.Layout, upvalueTypes, nil);
try
paramsTuple := L.Parameters;
SetLength(newParams, paramsTuple.Count);
SetLength(paramTypes, paramsTuple.Count);
paramsElements := paramsTuple.Elements;
SetLength(newParams, Length(paramsElements));
SetLength(paramTypes, Length(paramsElements));
for i := 0 to paramsTuple.Count - 1 do
for i := 0 to High(paramsElements) do
begin
paramIdent := paramsTuple.Items[i].AsIdentifier;
paramIdent := paramsElements[i].AsIdentifier;
injectedType := paramIdent.AsTypedNode.StaticType;
if injectedType.Kind = stUnknown then
@@ -597,11 +594,7 @@ begin
temp.Free;
end;
SetLength(paramsAsNodes, Length(newParams));
for i := 0 to High(newParams) do
paramsAsNodes[i] := newParams[i];
var paramList := TAst.Tuple(L.Parameters.Identity, paramsAsNodes);
var paramList := TAst.Tuple(L.Parameters.Identity, newParams);
Result :=
TAst.LambdaExpr(Node.Identity, paramList, newBody, L.Layout, finalDescriptor, L.Upvalues, L.HasNestedLambdas, L.IsPure, methodType);
@@ -617,17 +610,19 @@ var
bestSig: IMethodSignature;
match: Boolean;
newArgs: ITupleNode;
argsElements: TArray<IAstNode>;
begin
newCall := inherited VisitFunctionCall(Node).AsFunctionCall;
var newCallee := newCall.Callee;
newArgs := newCall.Arguments;
argsElements := newArgs.Elements;
SetLength(argTypes, newArgs.Count);
SetLength(argTypes, Length(argsElements));
hasUnknownArgs := False;
for i := 0 to newArgs.Count - 1 do
for i := 0 to High(argsElements) do
begin
argTypes[i] := newArgs.Items[i].AsTypedNode.StaticType;
argTypes[i] := argsElements[i].AsTypedNode.StaticType;
if argTypes[i].Kind = stUnknown then
hasUnknownArgs := True;
end;
@@ -761,18 +756,20 @@ var
valType: IStaticType;
key: IKeyword;
newFields: ITupleNode;
fieldsElements: TArray<IAstNode>;
begin
R := Node.AsRecordLiteral;
newFields := Visit(R.Fields).AsTuple;
fieldsElements := newFields.Elements;
var count := newFields.Count;
var count := Length(fieldsElements);
SetLength(fieldTypes, count);
SetLength(scalarFieldTypes, count);
isScalar := True;
for i := 0 to count - 1 do
begin
var field := newFields.Items[i].AsRecordField;
var field := fieldsElements[i].AsRecordField;
key := field.Key.Value;
valType := field.Value.AsTypedNode.StaticType;
@@ -865,17 +862,22 @@ var
selectorsNode: ITupleNode;
newSelectors: TList<IAstNode>;
streamType: IStaticType;
rawInputsElements: TArray<IAstNode>;
rawTupleElements: TArray<IAstNode>;
selectorsElements: TArray<IAstNode>;
lambdaParamsElements: TArray<IAstNode>;
begin
P := Node.AsPipe;
rawInputs := P.Inputs; // This is the Tuple of Tuples [[id [sel]] ...]
rawInputsElements := rawInputs.Elements;
newInputs := TList<IAstNode>.Create;
paramTypes := TList<IStaticType>.Create;
try
// 1. Iterate over input definitions
for i := 0 to rawInputs.Count - 1 do
for i := 0 to High(rawInputsElements) do
begin
inputPair := rawInputs.Items[i];
inputPair := rawInputsElements[i];
// Validate Structure: [StreamSource, [Selectors]]
if inputPair.Kind <> akTuple then
@@ -886,7 +888,9 @@ begin
end;
rawTuple := inputPair.AsTuple;
if rawTuple.Count <> 2 then
rawTupleElements := rawTuple.Elements;
if Length(rawTupleElements) <> 2 then
begin
if Assigned(FLog) then
FLog.AddError('Pipe input vector must have exactly 2 elements.', inputPair);
@@ -894,15 +898,15 @@ begin
end;
// Element 0: Stream Identifier
if rawTuple.Items[0].Kind <> akIdentifier then
if rawTupleElements[0].Kind <> akIdentifier then
begin
if Assigned(FLog) then
FLog.AddError('Pipe source must be an identifier.', rawTuple.Items[0]);
FLog.AddError('Pipe source must be an identifier.', rawTupleElements[0]);
continue;
end;
// Resolve Stream Identifier (Type Binding)
streamNode := Accept(rawTuple.Items[0]).AsIdentifier;
streamNode := Accept(rawTupleElements[0]).AsIdentifier;
streamType := streamNode.StaticType;
// Validate Stream Type
@@ -919,19 +923,21 @@ begin
end;
// Element 1: Selector Vector
if rawTuple.Items[1].Kind <> akTuple then
if rawTupleElements[1].Kind <> akTuple then
begin
if Assigned(FLog) then
FLog.AddError('Pipe selectors must be a vector of keywords.', rawTuple.Items[1]);
FLog.AddError('Pipe selectors must be a vector of keywords.', rawTupleElements[1]);
continue;
end;
selectorsNode := rawTuple.Items[1].AsTuple;
selectorsNode := rawTupleElements[1].AsTuple;
selectorsElements := selectorsNode.Elements;
newSelectors := TList<IAstNode>.Create;
try
// Iterate Selectors
for k := 0 to selectorsNode.Count - 1 do
for k := 0 to High(selectorsElements) do
begin
var selItem := selectorsNode.Items[k];
var selItem := selectorsElements[k];
if selItem.Kind <> akKeyword then
begin
if Assigned(FLog) then
@@ -974,23 +980,24 @@ begin
// 2. Process Transformation Lambda
lambda := P.Transformation;
lambdaParamsElements := lambda.Parameters.Elements;
if lambda.Parameters.Count <> paramTypes.Count then
if Length(lambdaParamsElements) <> paramTypes.Count then
begin
if Assigned(FLog) then
FLog.AddError(
Format(
'Pipe lambda expects %d parameters (one per selector), but got %d.',
[paramTypes.Count, lambda.Parameters.Count]
[paramTypes.Count, Length(lambdaParamsElements)]
),
lambda
);
end;
SetLength(newParams, lambda.Parameters.Count);
for k := 0 to lambda.Parameters.Count - 1 do
SetLength(newParams, Length(lambdaParamsElements));
for k := 0 to High(lambdaParamsElements) do
begin
var oldP := lambda.Parameters.Items[k].AsIdentifier;
var oldP := lambdaParamsElements[k].AsIdentifier;
var typeToInject :=
if k < paramTypes.Count then paramTypes[k]
else TTypes.Unknown;