Immutable infered types

This commit is contained in:
Michael Schimmel
2025-11-04 22:10:11 +01:00
parent f73c0c67b8
commit 980919525b
6 changed files with 395 additions and 271 deletions
+10 -20
View File
@@ -26,7 +26,6 @@ type
private
FBinaryOperators: TDictionary<string, TScalar.TBinaryOp>;
FUnaryOperators: TDictionary<string, TScalar.TUnaryOp>;
function SetType(const Node: IAstNode; const AType: IStaticType): IAstNode;
protected
// Override to find nodes to lower
function VisitFunctionCall(const Node: IFunctionCallNode): IAstNode; override;
@@ -82,16 +81,6 @@ begin
Result := Accept(RootNode); // Use IAstNode-returning Accept
if not Assigned(Result) then
Result := TAst.Block([]);
if Assigned(Result) then
(Result as TAstNode).StaticType := (Result as TAstNode).StaticType;
end;
function TAstLowerer.SetType(const Node: IAstNode; const AType: IStaticType): IAstNode;
begin
if Assigned(Node) then // Add nil check for safety
(Node as TAstNode).StaticType := AType;
Result := Node;
end;
function TAstLowerer.VisitFunctionCall(const Node: IFunctionCallNode): IAstNode;
@@ -100,11 +89,14 @@ var
binaryOp: TScalar.TBinaryOp;
unaryOp: TScalar.TUnaryOp;
left, right: IAstNode;
nodeType: IStaticType;
begin
// --- Optimization: Operator Folding ---
if (Node.Callee is TIdentifierNode) then
begin
calleeIdentifier := Node.Callee as TIdentifierNode;
// Get the type *before* replacing the node (it's an IAstTypedNode)
nodeType := Node.AsTypedNode.StaticType;
if (Length(Node.Arguments) = 2) then
begin
@@ -113,9 +105,9 @@ begin
// Note: We MUST visit children *before* creating the new node
left := Accept(Node.Arguments[0]);
right := Accept(Node.Arguments[1]);
var binExpr := TAst.BinaryExpr(left, binaryOp, right);
// Copy metadata (StaticType) from old node to new node
Result := SetType(binExpr, (Node as TAstNode).StaticType);
// Call constructor directly, passing the inferred type
Result := TBinaryExpressionNode.Create(left, binaryOp, right, nodeType);
exit;
end;
end;
@@ -125,18 +117,16 @@ begin
if FUnaryOperators.TryGetValue(calleeIdentifier.Name, unaryOp) then
begin
right := Accept(Node.Arguments[0]);
var unExpr := TAst.UnaryExpr(unaryOp, right);
// Copy metadata
Result := SetType(unExpr, (Node as TAstNode).StaticType);
// Call constructor directly, passing the inferred type
Result := TUnaryExpressionNode.Create(unaryOp, right, nodeType);
exit;
end;
if (calleeIdentifier.Name = '-') then
begin
right := Accept(Node.Arguments[0]);
var unExpr := TAst.UnaryExpr(TScalar.TUnaryOp.Negate, right);
// Copy metadata
Result := SetType(unExpr, (Node as TAstNode).StaticType);
// Call constructor directly, passing the inferred type
Result := TUnaryExpressionNode.Create(TScalar.TUnaryOp.Negate, right, nodeType);
exit;
end;
end;