AST Types

This commit is contained in:
Michael Schimmel
2025-10-25 18:33:38 +02:00
parent 28e4d94b97
commit 5a289492a3
+143 -25
View File
@@ -45,7 +45,6 @@ type
TUpvalueMapping = class
public
Map: TDictionary<TResolvedAddress, Integer>;
Nodes: TList<IIdentifierNode>;
constructor Create;
destructor Destroy; override;
end;
@@ -95,52 +94,102 @@ type
): IAstNode; static;
end;
TBoundIdentifierNode = class(TIdentifierNode)
// New base class for all bound nodes
TBoundNode = class abstract(TInterfacedObject, IAstNode)
public
function Accept(const Visitor: IAstVisitor): TDataValue; virtual; abstract;
end;
// Concrete bound identifier node
TBoundIdentifierNode = class(TBoundNode, IIdentifierNode)
private
FSource: IIdentifierNode; // The original Node.
FAddress: TResolvedAddress;
function GetName: string;
public
constructor Create(const AUnboundNode: IIdentifierNode; const AAddress: TResolvedAddress);
constructor Create(const ASource: IIdentifierNode; const AAddress: TResolvedAddress);
function Accept(const Visitor: IAstVisitor): TDataValue; override;
property Address: TResolvedAddress read FAddress;
property Name: string read GetName;
property Source: IIdentifierNode read FSource;
end;
TBoundVariableDeclarationNode = class(TVariableDeclarationNode)
// Bound variable declaration node
TBoundVariableDeclarationNode = class(TBoundNode, IVariableDeclarationNode)
private
FSource: IVariableDeclarationNode;
FIdentifier: IIdentifierNode;
FInitializer: IAstNode;
FIsBoxed: Boolean;
function GetIdentifier: IIdentifierNode;
function GetInitializer: IAstNode;
public
constructor Create(const AIdentifier: IIdentifierNode; AInitializer: IAstNode; AIsBoxed: Boolean);
constructor Create(
const ASource: IVariableDeclarationNode;
const AIdentifier: IIdentifierNode; // This is the bound identifier
AInitializer: IAstNode; // This is the bound initializer
AIsBoxed: Boolean
);
function Accept(const Visitor: IAstVisitor): TDataValue; override;
property IsBoxed: Boolean read FIsBoxed;
property Source: IVariableDeclarationNode read FSource;
// IVariableDeclarationNode implementation
property Identifier: IIdentifierNode read GetIdentifier;
property Initializer: IAstNode read GetInitializer;
end;
TBoundLambdaExpressionNode = class(TLambdaExpressionNode)
// Bound lambda expression node
TBoundLambdaExpressionNode = class(TBoundNode, ILambdaExpressionNode)
private
FSource: ILambdaExpressionNode;
FParameters: TArray<IIdentifierNode>; // Bound parameters
FBody: IAstNode; // Bound body
FScopeDescriptor: IScopeDescriptor;
FUpvalues: TArray<TResolvedAddress>;
FHasNestedLambdas: Boolean;
function GetBody: IAstNode;
function GetParameters: TArray<IIdentifierNode>;
public
constructor Create(
const AUnboundNode: ILambdaExpressionNode;
const ABody: IAstNode;
const AParameters: TArray<IIdentifierNode>;
const ASource: ILambdaExpressionNode;
const ABody: IAstNode; // Bound body
const AParameters: TArray<IIdentifierNode>; // Bound parameters
const AScopeDescriptor: IScopeDescriptor;
const AUpvalues: TArray<TResolvedAddress>;
AHasNestedLambdas: Boolean
);
function Accept(const Visitor: IAstVisitor): TDataValue; override;
property ScopeDescriptor: IScopeDescriptor read FScopeDescriptor;
property Upvalues: TArray<TResolvedAddress> read FUpvalues;
property HasNestedLambdas: Boolean read FHasNestedLambdas;
property Source: ILambdaExpressionNode read FSource;
// ILambdaExpressionNode implementation
property Parameters: TArray<IIdentifierNode> read GetParameters;
property Body: IAstNode read GetBody;
end;
TBoundFunctionCallNode = class(TFunctionCallNode)
// Bound function call node
TBoundFunctionCallNode = class(TBoundNode, IFunctionCallNode)
private
FSource: IFunctionCallNode;
FCallee: IAstNode; // Bound callee
FArguments: TArray<IAstNode>; // Bound arguments
FIsTailCall: Boolean;
function GetArguments: TArray<IAstNode>;
function GetCallee: IAstNode;
public
constructor Create(
const AUnboundNode: IFunctionCallNode;
const ACallee: IAstNode;
const AArguments: TArray<IAstNode>;
const ASource: IFunctionCallNode;
const ACallee: IAstNode; // Bound callee
const AArguments: TArray<IAstNode>; // Bound arguments
AIsTailCall: Boolean
);
function Accept(const Visitor: IAstVisitor): TDataValue; override;
property IsTailCall: Boolean read FIsTailCall;
property Source: IFunctionCallNode read FSource;
// IFunctionCallNode implementation
property Callee: IAstNode read GetCallee;
property Arguments: TArray<IAstNode> read GetArguments;
end;
implementation
@@ -268,22 +317,57 @@ begin
end;
{ TBoundIdentifierNode }
constructor TBoundIdentifierNode.Create(const AUnboundNode: IIdentifierNode; const AAddress: TResolvedAddress);
constructor TBoundIdentifierNode.Create(const ASource: IIdentifierNode; const AAddress: TResolvedAddress);
begin
inherited Create(AUnboundNode.Name);
inherited Create;
FSource := ASource;
FAddress := AAddress;
end;
{ TBoundVariableDeclarationNode }
constructor TBoundVariableDeclarationNode.Create(const AIdentifier: IIdentifierNode; AInitializer: IAstNode; AIsBoxed: Boolean);
function TBoundIdentifierNode.Accept(const Visitor: IAstVisitor): TDataValue;
begin
inherited Create(AIdentifier, AInitializer);
Result := Visitor.VisitIdentifier(Self);
end;
function TBoundIdentifierNode.GetName: string;
begin
Result := FSource.Name;
end;
{ TBoundVariableDeclarationNode }
constructor TBoundVariableDeclarationNode.Create(
const ASource: IVariableDeclarationNode;
const AIdentifier: IIdentifierNode;
AInitializer: IAstNode;
AIsBoxed: Boolean
);
begin
inherited Create;
FSource := ASource;
FIdentifier := AIdentifier;
FInitializer := AInitializer;
FIsBoxed := AIsBoxed;
end;
function TBoundVariableDeclarationNode.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitVariableDeclaration(Self);
end;
function TBoundVariableDeclarationNode.GetIdentifier: IIdentifierNode;
begin
Result := FIdentifier;
end;
function TBoundVariableDeclarationNode.GetInitializer: IAstNode;
begin
Result := FInitializer;
end;
{ TBoundLambdaExpressionNode }
constructor TBoundLambdaExpressionNode.Create(
const AUnboundNode: ILambdaExpressionNode;
const ASource: ILambdaExpressionNode;
const ABody: IAstNode;
const AParameters: TArray<IIdentifierNode>;
const AScopeDescriptor: IScopeDescriptor;
@@ -291,24 +375,60 @@ constructor TBoundLambdaExpressionNode.Create(
AHasNestedLambdas: Boolean
);
begin
inherited Create(AParameters, ABody);
inherited Create;
FSource := ASource;
FBody := ABody;
FParameters := AParameters;
FScopeDescriptor := AScopeDescriptor;
FUpvalues := AUpvalues;
FHasNestedLambdas := AHasNestedLambdas;
end;
function TBoundLambdaExpressionNode.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitLambdaExpression(Self);
end;
function TBoundLambdaExpressionNode.GetBody: IAstNode;
begin
Result := FBody;
end;
function TBoundLambdaExpressionNode.GetParameters: TArray<IIdentifierNode>;
begin
Result := FParameters;
end;
{ TBoundFunctionCallNode }
constructor TBoundFunctionCallNode.Create(
const AUnboundNode: IFunctionCallNode;
const ASource: IFunctionCallNode;
const ACallee: IAstNode;
const AArguments: TArray<IAstNode>;
AIsTailCall: Boolean
);
begin
inherited Create(ACallee, AArguments);
inherited Create;
FSource := ASource;
FCallee := ACallee;
FArguments := AArguments;
FIsTailCall := AIsTailCall;
end;
function TBoundFunctionCallNode.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitFunctionCall(Self);
end;
function TBoundFunctionCallNode.GetArguments: TArray<IAstNode>;
begin
Result := FArguments;
end;
function TBoundFunctionCallNode.GetCallee: IAstNode;
begin
Result := FCallee;
end;
{ TResolvedAddressComparer }
function TResolvedAddressComparer.Equals(const Left, Right: TResolvedAddress): Boolean;
begin
@@ -328,12 +448,10 @@ constructor TAstBinder.TUpvalueMapping.Create;
begin
inherited Create;
Map := TDictionary<TResolvedAddress, Integer>.Create(TResolvedAddressComparer.Create);
Nodes := TList<IIdentifierNode>.Create();
end;
destructor TAstBinder.TUpvalueMapping.Destroy;
begin
Nodes.Free;
Map.Free;
inherited Destroy;
end;
@@ -776,7 +894,7 @@ begin
address := TResolvedAddress.Create(akLocalOrParent, 0, slotIndex);
boundIdentifier := TBoundIdentifierNode.Create(Node.Identifier, address);
isBoxed := (FBoxedDeclarations <> nil) and FBoxedDeclarations.Contains(Node);
boundDecl := TBoundVariableDeclarationNode.Create(boundIdentifier, initializer, isBoxed);
boundDecl := TBoundVariableDeclarationNode.Create(Node, boundIdentifier, initializer, isBoxed);
Result := TDataValue.FromIntf<IVariableDeclarationNode>(boundDecl);
end;