diff --git a/Src/AST/Myc.Ast.Binding.pas b/Src/AST/Myc.Ast.Binding.pas index 353ce37..0f30f49 100644 --- a/Src/AST/Myc.Ast.Binding.pas +++ b/Src/AST/Myc.Ast.Binding.pas @@ -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; // Bound parameters - FBody: IAstNode; // Bound body FScopeDescriptor: IScopeDescriptor; FUpvalues: TArray; FHasNestedLambdas: Boolean; - function GetBody: IAstNode; - function GetParameters: TArray; public constructor Create( - const ASource: ILambdaExpressionNode; - const ABody: IAstNode; // Bound body - const AParameters: TArray; // Bound parameters + const AUnboundNode: ILambdaExpressionNode; + const ABody: IAstNode; + const AParameters: TArray; const AScopeDescriptor: IScopeDescriptor; const AUpvalues: TArray; AHasNestedLambdas: Boolean ); - function Accept(const Visitor: IAstVisitor): TDataValue; override; property ScopeDescriptor: IScopeDescriptor read FScopeDescriptor; property Upvalues: TArray read FUpvalues; property HasNestedLambdas: Boolean read FHasNestedLambdas; - property Source: ILambdaExpressionNode read FSource; - // ILambdaExpressionNode implementation - property Parameters: TArray 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; // Bound arguments FIsTailCall: Boolean; - function GetArguments: TArray; - function GetCallee: IAstNode; public constructor Create( - const ASource: IFunctionCallNode; - const ACallee: IAstNode; // Bound callee - const AArguments: TArray; // Bound arguments + const AUnboundNode: IFunctionCallNode; + const ACallee: IAstNode; + const AArguments: TArray; 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 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; 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; -begin - Result := FParameters; -end; - { TBoundFunctionCallNode } constructor TBoundFunctionCallNode.Create( - const ASource: IFunctionCallNode; + const AUnboundNode: IFunctionCallNode; const ACallee: IAstNode; const AArguments: TArray; 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; -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(boundDecl); end; diff --git a/Src/AST/Myc.Ast.pas b/Src/AST/Myc.Ast.pas index a18b4f4..658ebe7 100644 --- a/Src/AST/Myc.Ast.pas +++ b/Src/AST/Myc.Ast.pas @@ -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.