ITupleNode signature change
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user