AST Types

This commit is contained in:
Michael Schimmel
2025-10-25 19:19:55 +02:00
parent 5a289492a3
commit 85f2e02893
2 changed files with 40 additions and 142 deletions
+21 -142
View File
@@ -94,102 +94,52 @@ type
): IAstNode; static; ): IAstNode; static;
end; end;
// New base class for all bound nodes TBoundIdentifierNode = class(TIdentifierNode)
TBoundNode = class abstract(TInterfacedObject, IAstNode)
public
function Accept(const Visitor: IAstVisitor): TDataValue; virtual; abstract;
end;
// Concrete bound identifier node
TBoundIdentifierNode = class(TBoundNode, IIdentifierNode)
private private
FSource: IIdentifierNode; // The original Node.
FAddress: TResolvedAddress; FAddress: TResolvedAddress;
function GetName: string;
public public
constructor Create(const ASource: IIdentifierNode; const AAddress: TResolvedAddress); constructor Create(const AUnboundNode: IIdentifierNode; const AAddress: TResolvedAddress);
function Accept(const Visitor: IAstVisitor): TDataValue; override;
property Address: TResolvedAddress read FAddress; property Address: TResolvedAddress read FAddress;
property Name: string read GetName;
property Source: IIdentifierNode read FSource;
end; end;
// Bound variable declaration node TBoundVariableDeclarationNode = class(TVariableDeclarationNode)
TBoundVariableDeclarationNode = class(TBoundNode, IVariableDeclarationNode)
private private
FSource: IVariableDeclarationNode;
FIdentifier: IIdentifierNode;
FInitializer: IAstNode;
FIsBoxed: Boolean; FIsBoxed: Boolean;
function GetIdentifier: IIdentifierNode;
function GetInitializer: IAstNode;
public public
constructor Create( constructor Create(const AIdentifier: IIdentifierNode; AInitializer: IAstNode; AIsBoxed: Boolean);
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 IsBoxed: Boolean read FIsBoxed;
property Source: IVariableDeclarationNode read FSource;
// IVariableDeclarationNode implementation
property Identifier: IIdentifierNode read GetIdentifier;
property Initializer: IAstNode read GetInitializer;
end; end;
// Bound lambda expression node TBoundLambdaExpressionNode = class(TLambdaExpressionNode)
TBoundLambdaExpressionNode = class(TBoundNode, ILambdaExpressionNode)
private private
FSource: ILambdaExpressionNode;
FParameters: TArray<IIdentifierNode>; // Bound parameters
FBody: IAstNode; // Bound body
FScopeDescriptor: IScopeDescriptor; FScopeDescriptor: IScopeDescriptor;
FUpvalues: TArray<TResolvedAddress>; FUpvalues: TArray<TResolvedAddress>;
FHasNestedLambdas: Boolean; FHasNestedLambdas: Boolean;
function GetBody: IAstNode;
function GetParameters: TArray<IIdentifierNode>;
public public
constructor Create( constructor Create(
const ASource: ILambdaExpressionNode; const AUnboundNode: ILambdaExpressionNode;
const ABody: IAstNode; // Bound body const ABody: IAstNode;
const AParameters: TArray<IIdentifierNode>; // Bound parameters const AParameters: TArray<IIdentifierNode>;
const AScopeDescriptor: IScopeDescriptor; const AScopeDescriptor: IScopeDescriptor;
const AUpvalues: TArray<TResolvedAddress>; const AUpvalues: TArray<TResolvedAddress>;
AHasNestedLambdas: Boolean AHasNestedLambdas: Boolean
); );
function Accept(const Visitor: IAstVisitor): TDataValue; override;
property ScopeDescriptor: IScopeDescriptor read FScopeDescriptor; property ScopeDescriptor: IScopeDescriptor read FScopeDescriptor;
property Upvalues: TArray<TResolvedAddress> read FUpvalues; property Upvalues: TArray<TResolvedAddress> read FUpvalues;
property HasNestedLambdas: Boolean read FHasNestedLambdas; property HasNestedLambdas: Boolean read FHasNestedLambdas;
property Source: ILambdaExpressionNode read FSource;
// ILambdaExpressionNode implementation
property Parameters: TArray<IIdentifierNode> read GetParameters;
property Body: IAstNode read GetBody;
end; end;
// Bound function call node TBoundFunctionCallNode = class(TFunctionCallNode)
TBoundFunctionCallNode = class(TBoundNode, IFunctionCallNode)
private private
FSource: IFunctionCallNode;
FCallee: IAstNode; // Bound callee
FArguments: TArray<IAstNode>; // Bound arguments
FIsTailCall: Boolean; FIsTailCall: Boolean;
function GetArguments: TArray<IAstNode>;
function GetCallee: IAstNode;
public public
constructor Create( constructor Create(
const ASource: IFunctionCallNode; const AUnboundNode: IFunctionCallNode;
const ACallee: IAstNode; // Bound callee const ACallee: IAstNode;
const AArguments: TArray<IAstNode>; // Bound arguments const AArguments: TArray<IAstNode>;
AIsTailCall: Boolean AIsTailCall: Boolean
); );
function Accept(const Visitor: IAstVisitor): TDataValue; override;
property IsTailCall: Boolean read FIsTailCall; property IsTailCall: Boolean read FIsTailCall;
property Source: IFunctionCallNode read FSource;
// IFunctionCallNode implementation
property Callee: IAstNode read GetCallee;
property Arguments: TArray<IAstNode> read GetArguments;
end; end;
implementation implementation
@@ -317,57 +267,22 @@ begin
end; end;
{ TBoundIdentifierNode } { TBoundIdentifierNode }
constructor TBoundIdentifierNode.Create(const AUnboundNode: IIdentifierNode; const AAddress: TResolvedAddress);
constructor TBoundIdentifierNode.Create(const ASource: IIdentifierNode; const AAddress: TResolvedAddress);
begin begin
inherited Create; inherited Create(AUnboundNode.Name);
FSource := ASource;
FAddress := AAddress; FAddress := AAddress;
end; end;
function TBoundIdentifierNode.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitIdentifier(Self);
end;
function TBoundIdentifierNode.GetName: string;
begin
Result := FSource.Name;
end;
{ TBoundVariableDeclarationNode } { TBoundVariableDeclarationNode }
constructor TBoundVariableDeclarationNode.Create( constructor TBoundVariableDeclarationNode.Create(const AIdentifier: IIdentifierNode; AInitializer: IAstNode; AIsBoxed: Boolean);
const ASource: IVariableDeclarationNode;
const AIdentifier: IIdentifierNode;
AInitializer: IAstNode;
AIsBoxed: Boolean
);
begin begin
inherited Create; inherited Create(AIdentifier, AInitializer);
FSource := ASource;
FIdentifier := AIdentifier;
FInitializer := AInitializer;
FIsBoxed := AIsBoxed; FIsBoxed := AIsBoxed;
end; 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 } { TBoundLambdaExpressionNode }
constructor TBoundLambdaExpressionNode.Create( constructor TBoundLambdaExpressionNode.Create(
const ASource: ILambdaExpressionNode; const AUnboundNode: ILambdaExpressionNode;
const ABody: IAstNode; const ABody: IAstNode;
const AParameters: TArray<IIdentifierNode>; const AParameters: TArray<IIdentifierNode>;
const AScopeDescriptor: IScopeDescriptor; const AScopeDescriptor: IScopeDescriptor;
@@ -375,60 +290,24 @@ constructor TBoundLambdaExpressionNode.Create(
AHasNestedLambdas: Boolean AHasNestedLambdas: Boolean
); );
begin begin
inherited Create; inherited Create(AParameters, ABody);
FSource := ASource;
FBody := ABody;
FParameters := AParameters;
FScopeDescriptor := AScopeDescriptor; FScopeDescriptor := AScopeDescriptor;
FUpvalues := AUpvalues; FUpvalues := AUpvalues;
FHasNestedLambdas := AHasNestedLambdas; FHasNestedLambdas := AHasNestedLambdas;
end; 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 } { TBoundFunctionCallNode }
constructor TBoundFunctionCallNode.Create( constructor TBoundFunctionCallNode.Create(
const ASource: IFunctionCallNode; const AUnboundNode: IFunctionCallNode;
const ACallee: IAstNode; const ACallee: IAstNode;
const AArguments: TArray<IAstNode>; const AArguments: TArray<IAstNode>;
AIsTailCall: Boolean AIsTailCall: Boolean
); );
begin begin
inherited Create; inherited Create(ACallee, AArguments);
FSource := ASource;
FCallee := ACallee;
FArguments := AArguments;
FIsTailCall := AIsTailCall; FIsTailCall := AIsTailCall;
end; 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 } { TResolvedAddressComparer }
function TResolvedAddressComparer.Equals(const Left, Right: TResolvedAddress): Boolean; function TResolvedAddressComparer.Equals(const Left, Right: TResolvedAddress): Boolean;
begin begin
@@ -894,7 +773,7 @@ begin
address := TResolvedAddress.Create(akLocalOrParent, 0, slotIndex); address := TResolvedAddress.Create(akLocalOrParent, 0, slotIndex);
boundIdentifier := TBoundIdentifierNode.Create(Node.Identifier, address); boundIdentifier := TBoundIdentifierNode.Create(Node.Identifier, address);
isBoxed := (FBoxedDeclarations <> nil) and FBoxedDeclarations.Contains(Node); isBoxed := (FBoxedDeclarations <> nil) and FBoxedDeclarations.Contains(Node);
boundDecl := TBoundVariableDeclarationNode.Create(Node, boundIdentifier, initializer, isBoxed); boundDecl := TBoundVariableDeclarationNode.Create(boundIdentifier, initializer, isBoxed);
Result := TDataValue.FromIntf<IVariableDeclarationNode>(boundDecl); Result := TDataValue.FromIntf<IVariableDeclarationNode>(boundDecl);
end; end;
+19
View File
@@ -10,6 +10,7 @@ uses
Myc.Data.Scalar, Myc.Data.Scalar,
Myc.Data.Value, Myc.Data.Value,
Myc.Ast.Nodes, Myc.Ast.Nodes,
Myc.Ast.Types,
Myc.Ast.Scope; Myc.Ast.Scope;
type type
@@ -67,8 +68,12 @@ type
// Common base class for AST nodes to reduce boilerplate. // Common base class for AST nodes to reduce boilerplate.
TAstNode = class(TInterfacedObject, IAstNode) TAstNode = class(TInterfacedObject, IAstNode)
private
FStaticType: IStaticType;
public public
constructor Create;
function Accept(const Visitor: IAstVisitor): TDataValue; virtual; abstract; function Accept(const Visitor: IAstVisitor): TDataValue; virtual; abstract;
property StaticType: IStaticType read FStaticType write FStaticType;
end; end;
TConstantNode = class(TAstNode, IConstantNode) TConstantNode = class(TAstNode, IConstantNode)
@@ -324,6 +329,14 @@ begin
if not (AValue.Kind in [vkScalar, vkText, vkVoid]) then if not (AValue.Kind in [vkScalar, vkText, vkVoid]) then
raise EArgumentException.Create('IConstantNode only supports Scalar, Text, and Void values.'); raise EArgumentException.Create('IConstantNode only supports Scalar, Text, and Void values.');
FValue := AValue; FValue := AValue;
case AValue.Kind of
vkScalar: StaticType := TTypes.FromScalarKind(AValue.AsScalar.Kind);
vkText: StaticType := TTypes.Text;
vkVoid: StaticType := TTypes.Void;
else
StaticType := TTypes.Unknown; // Should not happen due to validation above
end;
end; end;
function TConstantNode.Accept(const Visitor: IAstVisitor): TDataValue; function TConstantNode.Accept(const Visitor: IAstVisitor): TDataValue;
@@ -988,4 +1001,10 @@ begin
Result := TVariableDeclarationNode.Create(AIdentifier, AInitializer); Result := TVariableDeclarationNode.Create(AIdentifier, AInitializer);
end; end;
constructor TAstNode.Create;
begin
inherited;
FStaticType := TTypes.Unknown;
end;
end. end.