AST Types
This commit is contained in:
+21
-142
@@ -94,102 +94,52 @@ type
|
||||
): IAstNode; static;
|
||||
end;
|
||||
|
||||
// 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)
|
||||
TBoundIdentifierNode = class(TIdentifierNode)
|
||||
private
|
||||
FSource: IIdentifierNode; // The original Node.
|
||||
FAddress: TResolvedAddress;
|
||||
function GetName: string;
|
||||
public
|
||||
constructor Create(const ASource: IIdentifierNode; const AAddress: TResolvedAddress);
|
||||
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
||||
constructor Create(const AUnboundNode: IIdentifierNode; const AAddress: TResolvedAddress);
|
||||
property Address: TResolvedAddress read FAddress;
|
||||
property Name: string read GetName;
|
||||
property Source: IIdentifierNode read FSource;
|
||||
end;
|
||||
|
||||
// Bound variable declaration node
|
||||
TBoundVariableDeclarationNode = class(TBoundNode, IVariableDeclarationNode)
|
||||
TBoundVariableDeclarationNode = class(TVariableDeclarationNode)
|
||||
private
|
||||
FSource: IVariableDeclarationNode;
|
||||
FIdentifier: IIdentifierNode;
|
||||
FInitializer: IAstNode;
|
||||
FIsBoxed: Boolean;
|
||||
function GetIdentifier: IIdentifierNode;
|
||||
function GetInitializer: IAstNode;
|
||||
public
|
||||
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;
|
||||
constructor Create(const AIdentifier: IIdentifierNode; AInitializer: IAstNode; AIsBoxed: Boolean);
|
||||
property IsBoxed: Boolean read FIsBoxed;
|
||||
property Source: IVariableDeclarationNode read FSource;
|
||||
// IVariableDeclarationNode implementation
|
||||
property Identifier: IIdentifierNode read GetIdentifier;
|
||||
property Initializer: IAstNode read GetInitializer;
|
||||
end;
|
||||
|
||||
// Bound lambda expression node
|
||||
TBoundLambdaExpressionNode = class(TBoundNode, ILambdaExpressionNode)
|
||||
TBoundLambdaExpressionNode = class(TLambdaExpressionNode)
|
||||
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 ASource: ILambdaExpressionNode;
|
||||
const ABody: IAstNode; // Bound body
|
||||
const AParameters: TArray<IIdentifierNode>; // Bound parameters
|
||||
const AUnboundNode: ILambdaExpressionNode;
|
||||
const ABody: IAstNode;
|
||||
const AParameters: TArray<IIdentifierNode>;
|
||||
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;
|
||||
|
||||
// Bound function call node
|
||||
TBoundFunctionCallNode = class(TBoundNode, IFunctionCallNode)
|
||||
TBoundFunctionCallNode = class(TFunctionCallNode)
|
||||
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 ASource: IFunctionCallNode;
|
||||
const ACallee: IAstNode; // Bound callee
|
||||
const AArguments: TArray<IAstNode>; // Bound arguments
|
||||
const AUnboundNode: IFunctionCallNode;
|
||||
const ACallee: IAstNode;
|
||||
const AArguments: TArray<IAstNode>;
|
||||
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
|
||||
@@ -317,57 +267,22 @@ begin
|
||||
end;
|
||||
|
||||
{ TBoundIdentifierNode }
|
||||
|
||||
constructor TBoundIdentifierNode.Create(const ASource: IIdentifierNode; const AAddress: TResolvedAddress);
|
||||
constructor TBoundIdentifierNode.Create(const AUnboundNode: IIdentifierNode; const AAddress: TResolvedAddress);
|
||||
begin
|
||||
inherited Create;
|
||||
FSource := ASource;
|
||||
inherited Create(AUnboundNode.Name);
|
||||
FAddress := AAddress;
|
||||
end;
|
||||
|
||||
function TBoundIdentifierNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
||||
begin
|
||||
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
|
||||
);
|
||||
constructor TBoundVariableDeclarationNode.Create(const AIdentifier: IIdentifierNode; AInitializer: IAstNode; AIsBoxed: Boolean);
|
||||
begin
|
||||
inherited Create;
|
||||
FSource := ASource;
|
||||
FIdentifier := AIdentifier;
|
||||
FInitializer := AInitializer;
|
||||
inherited Create(AIdentifier, 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 ASource: ILambdaExpressionNode;
|
||||
const AUnboundNode: ILambdaExpressionNode;
|
||||
const ABody: IAstNode;
|
||||
const AParameters: TArray<IIdentifierNode>;
|
||||
const AScopeDescriptor: IScopeDescriptor;
|
||||
@@ -375,60 +290,24 @@ constructor TBoundLambdaExpressionNode.Create(
|
||||
AHasNestedLambdas: Boolean
|
||||
);
|
||||
begin
|
||||
inherited Create;
|
||||
FSource := ASource;
|
||||
FBody := ABody;
|
||||
FParameters := AParameters;
|
||||
inherited Create(AParameters, ABody);
|
||||
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 ASource: IFunctionCallNode;
|
||||
const AUnboundNode: IFunctionCallNode;
|
||||
const ACallee: IAstNode;
|
||||
const AArguments: TArray<IAstNode>;
|
||||
AIsTailCall: Boolean
|
||||
);
|
||||
begin
|
||||
inherited Create;
|
||||
FSource := ASource;
|
||||
FCallee := ACallee;
|
||||
FArguments := AArguments;
|
||||
inherited Create(ACallee, 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
|
||||
@@ -894,7 +773,7 @@ begin
|
||||
address := TResolvedAddress.Create(akLocalOrParent, 0, slotIndex);
|
||||
boundIdentifier := TBoundIdentifierNode.Create(Node.Identifier, address);
|
||||
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);
|
||||
end;
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ uses
|
||||
Myc.Data.Scalar,
|
||||
Myc.Data.Value,
|
||||
Myc.Ast.Nodes,
|
||||
Myc.Ast.Types,
|
||||
Myc.Ast.Scope;
|
||||
|
||||
type
|
||||
@@ -67,8 +68,12 @@ type
|
||||
|
||||
// Common base class for AST nodes to reduce boilerplate.
|
||||
TAstNode = class(TInterfacedObject, IAstNode)
|
||||
private
|
||||
FStaticType: IStaticType;
|
||||
public
|
||||
constructor Create;
|
||||
function Accept(const Visitor: IAstVisitor): TDataValue; virtual; abstract;
|
||||
property StaticType: IStaticType read FStaticType write FStaticType;
|
||||
end;
|
||||
|
||||
TConstantNode = class(TAstNode, IConstantNode)
|
||||
@@ -324,6 +329,14 @@ begin
|
||||
if not (AValue.Kind in [vkScalar, vkText, vkVoid]) then
|
||||
raise EArgumentException.Create('IConstantNode only supports Scalar, Text, and Void values.');
|
||||
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;
|
||||
|
||||
function TConstantNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
||||
@@ -988,4 +1001,10 @@ begin
|
||||
Result := TVariableDeclarationNode.Create(AIdentifier, AInitializer);
|
||||
end;
|
||||
|
||||
constructor TAstNode.Create;
|
||||
begin
|
||||
inherited;
|
||||
FStaticType := TTypes.Unknown;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
Reference in New Issue
Block a user