unit Myc.Ast.Nodes; interface uses System.SysUtils, System.Generics.Collections, Myc.Data.Scalar, Myc.Data.Value, Myc.Data.Keyword, Myc.Ast.Scope, Myc.Ast.Types, Myc.Ast.Identities; type // --- Forward Declarations --- IAstNode = interface; // --- Error Handling --- TCompilerErrorLevel = (elHint, elWarning, elError); TCompilerError = record Level: TCompilerErrorLevel; Message: string; Node: IAstNode; constructor Create(ALevel: TCompilerErrorLevel; const AMessage: string; const ANode: IAstNode = nil); function ToString: string; end; ICompilerLog = interface procedure Add(ALevel: TCompilerErrorLevel; const AMessage: string; const ANode: IAstNode = nil); procedure AddError(const AMessage: string; const ANode: IAstNode = nil); procedure AddWarning(const AMessage: string; const ANode: IAstNode = nil); function HasErrors: Boolean; function GetEntryCount: Integer; function GetEntries: TArray; property Entries: TArray read GetEntries; end; TCompilerLog = class(TInterfacedObject, ICompilerLog) private FEntries: TList; public constructor Create; destructor Destroy; override; procedure Add(ALevel: TCompilerErrorLevel; const AMessage: string; const ANode: IAstNode = nil); procedure AddError(const AMessage: string; const ANode: IAstNode = nil); procedure AddWarning(const AMessage: string; const ANode: IAstNode = nil); function HasErrors: Boolean; function GetEntryCount: Integer; function GetEntries: TArray; end; EAstException = class(Exception); ECompilationFailed = class(EAstException) private FErrors: TArray; public constructor Create(const AErrors: TArray); function ToString: string; override; property Errors: TArray read FErrors; end; TCompiledFunction = record public Func: TDataValue.TFunc; StaticType: IStaticType; IsPure: Boolean; constructor Create(const AFunc: TDataValue.TFunc; const AStaticType: IStaticType; AIsPure: Boolean); end; // --- AST Interfaces --- IAstVisitor = interface; IAstTypedNode = interface; // Core Nodes IConstantNode = interface; IIdentifierNode = interface; IKeywordNode = interface; // Lists & Containers IParameterList = interface; IArgumentList = interface; IExpressionList = interface; IRecordFieldList = interface; IRecordFieldNode = interface; // Control Flow & Structure IIfExpressionNode = interface; ICondExpressionNode = interface; ILambdaExpressionNode = interface; IFunctionCallNode = interface; IMacroExpansionNode = interface; IBlockExpressionNode = interface; IVariableDeclarationNode = interface; IAssignmentNode = interface; IMacroDefinitionNode = interface; IQuasiquoteNode = interface; IUnquoteNode = interface; IUnquoteSplicingNode = interface; IIndexerNode = interface; IMemberAccessNode = interface; IRecordLiteralNode = interface; ICreateSeriesNode = interface; IAddSeriesItemNode = interface; ISeriesLengthNode = interface; IRecurNode = interface; INopNode = interface; // Pipes IPipeSelectorList = interface; IPipeInputNode = interface; IPipeInputList = interface; IPipeNode = interface; // Node Kinds & Helpers TAstNodeKind = ( akConstant, akIdentifier, akKeyword, // Lists akParameterList, akArgumentList, akExpressionList, akRecordFieldList, akRecordField, akIfExpression, akCondExpression, akLambdaExpression, akFunctionCall, akMacroExpansion, akBlockExpression, akVariableDeclaration, akAssignment, akMacroDefinition, akQuasiquote, akUnquote, akUnquoteSplicing, akIndexer, akMemberAccess, akRecordLiteral, akCreateSeries, akAddSeriesItem, akSeriesLength, akRecur, akNop, // Pipes akPipe, akPipeInput, akPipeSelectorList, akPipeInputList ); TAstNodeKindHelper = record helper for TAstNodeKind public function ToString: string; end; // Represents a single branch in a Cond expression (Condition -> Branch) TCondPair = record Condition: IAstNode; Branch: IAstNode; constructor Create(const ACondition, ABranch: IAstNode); end; // --- Base Interfaces --- IAstNode = interface {$region 'private'} function GetKind: TAstNodeKind; function GetIsTyped: Boolean; function GetIdentity: IAstIdentity; {$endregion} function Accept(const Visitor: IAstVisitor): TDataValue; // Fluent Casts / Accessors (Interface based) function AsTypedNode: IAstTypedNode; function AsConstant: IConstantNode; function AsIdentifier: IIdentifierNode; function AsKeyword: IKeywordNode; function AsParameterList: IParameterList; function AsArgumentList: IArgumentList; function AsExpressionList: IExpressionList; function AsRecordFieldList: IRecordFieldList; function AsRecordField: IRecordFieldNode; function AsIfExpression: IIfExpressionNode; function AsCondExpression: ICondExpressionNode; function AsLambdaExpression: ILambdaExpressionNode; function AsFunctionCall: IFunctionCallNode; function AsMacroExpansion: IMacroExpansionNode; function AsBlockExpression: IBlockExpressionNode; function AsVariableDeclaration: IVariableDeclarationNode; function AsAssignment: IAssignmentNode; function AsMacroDefinition: IMacroDefinitionNode; function AsQuasiquote: IQuasiquoteNode; function AsUnquote: IUnquoteNode; function AsUnquoteSplicing: IUnquoteSplicingNode; function AsIndexer: IIndexerNode; function AsMemberAccess: IMemberAccessNode; function AsRecordLiteral: IRecordLiteralNode; function AsCreateSeries: ICreateSeriesNode; function AsAddSeriesItem: IAddSeriesItemNode; function AsSeriesLength: ISeriesLengthNode; function AsRecur: IRecurNode; function AsNop: INopNode; // Pipes function AsPipeInput: IPipeInputNode; function AsPipeSelectorList: IPipeSelectorList; function AsPipeInputList: IPipeInputList; function AsPipe: IPipeNode; property IsTyped: Boolean read GetIsTyped; property Kind: TAstNodeKind read GetKind; property Identity: IAstIdentity read GetIdentity; end; INodeList = interface(IAstNode) {$region 'private'} function GetCount: Integer; function GetItem(Index: Integer): T; {$endregion} function GetEnumerator: TEnumerator; function ToArray: TArray; property Count: Integer read GetCount; property Items[Index: Integer]: T read GetItem; default; end; IAstTypedNode = interface(IAstNode) {$region 'private'} function GetStaticType: IStaticType; {$endregion} property StaticType: IStaticType read GetStaticType; end; IRecordFieldNode = interface(IAstNode) {$region 'private'} function GetKey: IKeywordNode; function GetValue: IAstNode; {$endregion} property Key: IKeywordNode read GetKey; property Value: IAstNode read GetValue; end; IRecordFieldList = interface(INodeList) end; // --- Node Interfaces (Definitions) --- // Function Definition (Lambda) IFunctionDefinition = interface(IAstTypedNode) {$region 'private'} function GetBody: IAstNode; function GetParameters: IParameterList; function GetIsPure: Boolean; {$endregion} property Body: IAstNode read GetBody; property Parameters: IParameterList read GetParameters; property IsPure: Boolean read GetIsPure; end; INopNode = interface(IAstTypedNode) end; IConstantNode = interface(IAstTypedNode) {$region 'private'} function GetValue: TDataValue; {$endregion} property Value: TDataValue read GetValue; end; IIdentifierNode = interface(IAstTypedNode) {$region 'private'} function GetAddress: TResolvedAddress; function GetName: string; {$endregion} property Address: TResolvedAddress read GetAddress; property Name: string read GetName; end; IKeywordNode = interface(IAstTypedNode) {$region 'private'} function GetValue: IKeyword; {$endregion} property Value: IKeyword read GetValue; end; IIfExpressionNode = interface(IAstTypedNode) {$region 'private'} function GetCondition: IAstNode; function GetThenBranch: IAstNode; function GetElseBranch: IAstNode; {$endregion} property Condition: IAstNode read GetCondition; property ThenBranch: IAstNode read GetThenBranch; property ElseBranch: IAstNode read GetElseBranch; end; ICondExpressionNode = interface(IAstTypedNode) {$region 'private'} function GetPairs: TArray; function GetElseBranch: IAstNode; {$endregion} property Pairs: TArray read GetPairs; property ElseBranch: IAstNode read GetElseBranch; end; ILambdaExpressionNode = interface(IFunctionDefinition) {$region 'private'} function GetLayout: IScopeLayout; function GetDescriptor: IScopeDescriptor; function GetUpvalues: TArray; function GetHasNestedLambdas: Boolean; {$endregion} property Layout: IScopeLayout read GetLayout; property Descriptor: IScopeDescriptor read GetDescriptor; property Upvalues: TArray read GetUpvalues; property HasNestedLambdas: Boolean read GetHasNestedLambdas; end; IFunctionCallNode = interface(IAstTypedNode) {$region 'private'} function GetCallee: IAstNode; function GetArguments: IArgumentList; function GetIsTailCall: Boolean; function GetStaticTarget: TDataValue.TFunc; function GetIsTargetPure: Boolean; {$endregion} property Callee: IAstNode read GetCallee; property Arguments: IArgumentList read GetArguments; property IsTailCall: Boolean read GetIsTailCall; property StaticTarget: TDataValue.TFunc read GetStaticTarget; property IsTargetPure: Boolean read GetIsTargetPure; end; IMacroExpansionNode = interface(IAstTypedNode) {$region 'private'} function GetCallNode: IFunctionCallNode; function GetExpandedBody: IAstNode; {$endregion} property CallNode: IFunctionCallNode read GetCallNode; property ExpandedBody: IAstNode read GetExpandedBody; end; IRecurNode = interface(IAstTypedNode) {$region 'private'} function GetArguments: IArgumentList; {$endregion} property Arguments: IArgumentList read GetArguments; end; IBlockExpressionNode = interface(IAstTypedNode) {$region 'private'} function GetExpressions: IExpressionList; {$endregion} property Expressions: IExpressionList read GetExpressions; end; IVariableDeclarationNode = interface(IAstTypedNode) {$region 'private'} function GetTarget: IAstNode; function GetInitializer: IAstNode; function GetIsBoxed: Boolean; {$endregion} property Target: IAstNode read GetTarget; property Initializer: IAstNode read GetInitializer; property IsBoxed: Boolean read GetIsBoxed; end; IAssignmentNode = interface(IAstTypedNode) {$region 'private'} function GetTarget: IAstNode; function GetValue: IAstNode; {$endregion} property Target: IAstNode read GetTarget; property Value: IAstNode read GetValue; end; IMacroDefinitionNode = interface(IAstTypedNode) {$region 'private'} function GetName: IIdentifierNode; function GetParameters: IParameterList; function GetBody: IAstNode; {$endregion} property Name: IIdentifierNode read GetName; property Parameters: IParameterList read GetParameters; property Body: IAstNode read GetBody; end; IQuasiquoteNode = interface(IAstNode) {$region 'private'} function GetExpression: IAstNode; {$endregion} property Expression: IAstNode read GetExpression; end; IUnquoteNode = interface(IAstNode) {$region 'private'} function GetExpression: IAstNode; {$endregion} property Expression: IAstNode read GetExpression; end; IUnquoteSplicingNode = interface(IAstNode) {$region 'private'} function GetExpression: IQuasiquoteNode; {$endregion} property Expression: IQuasiquoteNode read GetExpression; end; IIndexerNode = interface(IAstTypedNode) {$region 'private'} function GetBase: IAstNode; function GetIndex: IAstNode; {$endregion} property Base: IAstNode read GetBase; property Index: IAstNode read GetIndex; end; IMemberAccessNode = interface(IAstTypedNode) {$region 'private'} function GetBase: IAstNode; function GetMember: IKeywordNode; {$endregion} property Base: IAstNode read GetBase; property Member: IKeywordNode read GetMember; end; IRecordLiteralNode = interface(IAstTypedNode) {$region 'private'} function GetFields: IRecordFieldList; function GetGenericDefinition: IGenericRecordDefinition; function GetScalarDefinition: IScalarRecordDefinition; {$endregion} property Fields: IRecordFieldList read GetFields; property GenericDefinition: IGenericRecordDefinition read GetGenericDefinition; property ScalarDefinition: IScalarRecordDefinition read GetScalarDefinition; end; ICreateSeriesNode = interface(IAstTypedNode) {$region 'private'} function GetDefinition: String; {$endregion} property Definition: String read GetDefinition; end; IAddSeriesItemNode = interface(IAstTypedNode) {$region 'private'} function GetSeries: IIdentifierNode; function GetValue: IAstNode; function GetLookback: IAstNode; {$endregion} property Series: IIdentifierNode read GetSeries; property Value: IAstNode read GetValue; property Lookback: IAstNode read GetLookback; end; ISeriesLengthNode = interface(IAstTypedNode) {$region 'private'} function GetSeries: IIdentifierNode; {$endregion} property Series: IIdentifierNode read GetSeries; end; // A list of selector keywords [ :A :B ] IPipeSelectorList = interface(INodeList) end; // Represents a single input definition within a pipe: "btc [:Close :Open]" IPipeInputNode = interface(IAstTypedNode) {$region 'private'} function GetStreamSource: IIdentifierNode; function GetSelectors: IPipeSelectorList; {$endregion} property StreamSource: IIdentifierNode read GetStreamSource; property Selectors: IPipeSelectorList read GetSelectors; end; // A list of pipe inputs IPipeInputList = interface(INodeList) end; // The main pipe definition: (pipe [inputs...] (fn ...)) IPipeNode = interface(IAstTypedNode) {$region 'private'} function GetInputs: IPipeInputList; function GetTransformation: ILambdaExpressionNode; {$endregion} property Inputs: IPipeInputList read GetInputs; property Transformation: ILambdaExpressionNode read GetTransformation; end; IParameterList = interface(INodeList) end; IArgumentList = interface(INodeList) end; IExpressionList = interface(INodeList) end; IAstVisitor = interface function VisitConstant(const Node: IConstantNode): TDataValue; function VisitIdentifier(const Node: IIdentifierNode): TDataValue; function VisitKeyword(const Node: IKeywordNode): TDataValue; // List Visits function VisitParameterList(const Node: IParameterList): TDataValue; function VisitArgumentList(const Node: IArgumentList): TDataValue; function VisitExpressionList(const Node: IExpressionList): TDataValue; function VisitRecordFieldList(const Node: IRecordFieldList): TDataValue; function VisitRecordField(const Node: IRecordFieldNode): TDataValue; function VisitIfExpression(const Node: IIfExpressionNode): TDataValue; function VisitCondExpression(const Node: ICondExpressionNode): TDataValue; function VisitLambdaExpression(const Node: ILambdaExpressionNode): TDataValue; function VisitFunctionCall(const Node: IFunctionCallNode): TDataValue; function VisitMacroExpansionNode(const Node: IMacroExpansionNode): TDataValue; function VisitBlockExpression(const Node: IBlockExpressionNode): TDataValue; function VisitVariableDeclaration(const Node: IVariableDeclarationNode): TDataValue; function VisitAssignment(const Node: IAssignmentNode): TDataValue; function VisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue; function VisitQuasiquote(const Node: IQuasiquoteNode): TDataValue; function VisitUnquote(const Node: IUnquoteNode): TDataValue; function VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): TDataValue; function VisitIndexer(const Node: IIndexerNode): TDataValue; function VisitMemberAccess(const Node: IMemberAccessNode): TDataValue; function VisitRecordLiteral(const Node: IRecordLiteralNode): TDataValue; function VisitCreateSeries(const Node: ICreateSeriesNode): TDataValue; function VisitAddSeriesItem(const Node: IAddSeriesItemNode): TDataValue; function VisitSeriesLength(const Node: ISeriesLengthNode): TDataValue; function VisitRecurNode(const Node: IRecurNode): TDataValue; function VisitNop(const Node: INopNode): TDataValue; // Pipes function VisitPipeInput(const Node: IPipeInputNode): TDataValue; function VisitPipeSelectorList(const Node: IPipeSelectorList): TDataValue; function VisitPipeInputList(const Node: IPipeInputList): TDataValue; function VisitPipe(const Node: IPipeNode): TDataValue; end; IEvaluatorVisitor = interface(IAstVisitor) function Execute(const RootNode: IAstNode): TDataValue; end; TEvaluatorFactory = reference to function(const Scope: IExecutionScope): IEvaluatorVisitor; TAstNode = class(TInterfacedObject, IAstNode) private FIdentity: IAstIdentity; function GetIdentity: IAstIdentity; protected function GetKind: TAstNodeKind; virtual; abstract; function GetIsTyped: Boolean; virtual; public constructor Create(const AIdentity: IAstIdentity); function Accept(const Visitor: IAstVisitor): TDataValue; virtual; abstract; function AsConstant: IConstantNode; virtual; function AsIdentifier: IIdentifierNode; virtual; function AsKeyword: IKeywordNode; virtual; function AsParameterList: IParameterList; virtual; function AsArgumentList: IArgumentList; virtual; function AsExpressionList: IExpressionList; virtual; function AsRecordFieldList: IRecordFieldList; virtual; function AsRecordField: IRecordFieldNode; virtual; function AsIfExpression: IIfExpressionNode; virtual; function AsCondExpression: ICondExpressionNode; virtual; function AsLambdaExpression: ILambdaExpressionNode; virtual; function AsFunctionCall: IFunctionCallNode; virtual; function AsMacroExpansion: IMacroExpansionNode; virtual; function AsBlockExpression: IBlockExpressionNode; virtual; function AsVariableDeclaration: IVariableDeclarationNode; virtual; function AsAssignment: IAssignmentNode; virtual; function AsMacroDefinition: IMacroDefinitionNode; virtual; function AsQuasiquote: IQuasiquoteNode; virtual; function AsUnquote: IUnquoteNode; virtual; function AsUnquoteSplicing: IUnquoteSplicingNode; virtual; function AsIndexer: IIndexerNode; virtual; function AsMemberAccess: IMemberAccessNode; virtual; function AsRecordLiteral: IRecordLiteralNode; virtual; function AsCreateSeries: ICreateSeriesNode; virtual; function AsAddSeriesItem: IAddSeriesItemNode; virtual; function AsSeriesLength: ISeriesLengthNode; virtual; function AsRecur: IRecurNode; virtual; function AsNop: INopNode; virtual; function AsPipeInput: IPipeInputNode; virtual; function AsPipeSelectorList: IPipeSelectorList; virtual; function AsPipeInputList: IPipeInputList; virtual; function AsPipe: IPipeNode; virtual; function AsTypedNode: IAstTypedNode; virtual; property IsTyped: Boolean read GetIsTyped; property Kind: TAstNodeKind read GetKind; property Identity: IAstIdentity read GetIdentity; end; TAstTypedNode = class(TAstNode, IAstTypedNode) private FStaticType: IStaticType; function GetStaticType: IStaticType; protected function GetIsTyped: Boolean; override; public constructor Create(const AStaticType: IStaticType; const AIdentity: IAstIdentity); function AsTypedNode: IAstTypedNode; override; property StaticType: IStaticType read GetStaticType; end; // --- List Implementation Bases --- TAstNodeList = class(TAstNode, INodeList) type TEnumerator = class(TEnumerator) private FArray: TArray; FIndex: NativeInt; function GetCurrent: T; inline; protected function DoGetCurrent: T; override; function DoMoveNext: Boolean; override; public constructor Create(const AArray: TArray); function MoveNext: Boolean; inline; property Current: T read GetCurrent; end; private FItems: TArray; function GetCount: Integer; function GetItem(Index: Integer): T; public constructor Create(const AItems: TArray; const AIdentity: IAstIdentity); function GetEnumerator: TEnumerator; function ToArray: TArray; property Count: Integer read GetCount; property Items[Index: Integer]: T read GetItem; default; end; TParameterList = class(TAstNodeList, IParameterList) protected function GetKind: TAstNodeKind; override; public function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsParameterList: IParameterList; override; end; TArgumentList = class(TAstNodeList, IArgumentList) protected function GetKind: TAstNodeKind; override; public function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsArgumentList: IArgumentList; override; end; TExpressionList = class(TAstNodeList, IExpressionList) protected function GetKind: TAstNodeKind; override; public function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsExpressionList: IExpressionList; override; end; TRecordFieldNode = class(TAstNode, IRecordFieldNode) private FKey: IKeywordNode; FValue: IAstNode; function GetKey: IKeywordNode; function GetValue: IAstNode; protected function GetKind: TAstNodeKind; override; public constructor Create(const AKey: IKeywordNode; const AValue: IAstNode; const AIdentity: IAstIdentity); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsRecordField: IRecordFieldNode; override; end; TRecordFieldList = class(TAstNodeList, IRecordFieldList) protected function GetKind: TAstNodeKind; override; public function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsRecordFieldList: IRecordFieldList; override; end; // --- Core Nodes Implementations --- TConstantNode = class(TAstTypedNode, IConstantNode) private FConstIdentity: IConstantIdentity; // Typed reference for fast access function GetValue: TDataValue; protected function GetKind: TAstNodeKind; override; public constructor Create(const AIdentity: IConstantIdentity; const AStaticType: IStaticType); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsConstant: IConstantNode; override; end; TIdentifierNode = class(TAstTypedNode, IIdentifierNode) private FNamedIdentity: INamedIdentity; // Typed reference for fast access FAddress: TResolvedAddress; function GetAddress: TResolvedAddress; function GetName: string; protected function GetKind: TAstNodeKind; override; public constructor Create(const AIdentity: INamedIdentity; const AAddress: TResolvedAddress; const AStaticType: IStaticType); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsIdentifier: IIdentifierNode; override; end; TKeywordNode = class(TAstTypedNode, IKeywordNode) private FKeywordIdentity: IKeywordIdentity; function GetValue: IKeyword; protected function GetKind: TAstNodeKind; override; public constructor Create(const AIdentity: IKeywordIdentity); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsKeyword: IKeywordNode; override; end; TCreateSeriesNode = class(TAstTypedNode, ICreateSeriesNode) private FDefIdentity: IDefinitionIdentity; function GetDefinition: String; protected function GetKind: TAstNodeKind; override; public constructor Create(const AIdentity: IDefinitionIdentity; const AStaticType: IStaticType); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsCreateSeries: ICreateSeriesNode; override; end; // --- Structural Nodes (Identity only for location) --- TIfExpressionNode = class(TAstTypedNode, IIfExpressionNode) private FCondition, FThenBranch, FElseBranch: IAstNode; function GetCondition: IAstNode; function GetThenBranch: IAstNode; function GetElseBranch: IAstNode; protected function GetKind: TAstNodeKind; override; public constructor Create( const ACondition, AThenBranch, AElseBranch: IAstNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity ); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsIfExpression: IIfExpressionNode; override; end; TCondExpressionNode = class(TAstTypedNode, ICondExpressionNode) private FPairs: TArray; FElseBranch: IAstNode; function GetPairs: TArray; function GetElseBranch: IAstNode; protected function GetKind: TAstNodeKind; override; public constructor Create( const APairs: TArray; const AElseBranch: IAstNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity ); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsCondExpression: ICondExpressionNode; override; end; TLambdaExpressionNode = class(TAstTypedNode, ILambdaExpressionNode, IFunctionDefinition) private FParameters: IParameterList; FBody: IAstNode; FLayout: IScopeLayout; FDescriptor: IScopeDescriptor; FUpvalues: TArray; FHasNestedLambdas, FIsPure: Boolean; function GetParameters: IParameterList; function GetBody: IAstNode; function GetLayout: IScopeLayout; function GetDescriptor: IScopeDescriptor; function GetUpvalues: TArray; function GetHasNestedLambdas: Boolean; function GetIsPure: Boolean; protected function GetKind: TAstNodeKind; override; public constructor Create( const AParameters: IParameterList; const ABody: IAstNode; const AStaticType: IStaticType; const ALayout: IScopeLayout; const ADescriptor: IScopeDescriptor; const AUpvalues: TArray; const AHasNestedLambdas, AIsPure: Boolean; const AIdentity: IAstIdentity ); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsLambdaExpression: ILambdaExpressionNode; override; end; TFunctionCallNode = class(TAstTypedNode, IFunctionCallNode) private FCallee: IAstNode; FArguments: IArgumentList; FIsTailCall: Boolean; FStaticTarget: TDataValue.TFunc; FIsTargetPure: Boolean; function GetCallee: IAstNode; function GetArguments: IArgumentList; function GetIsTailCall: Boolean; function GetStaticTarget: TDataValue.TFunc; function GetIsTargetPure: Boolean; protected function GetKind: TAstNodeKind; override; public constructor Create( const ACallee: IAstNode; const AArguments: IArgumentList; const AStaticType: IStaticType; const AIsTailCall: Boolean; const AStaticTarget: TDataValue.TFunc; const AIsTargetPure: Boolean; const AIdentity: IAstIdentity ); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsFunctionCall: IFunctionCallNode; override; end; TMacroDefinitionNode = class(TAstTypedNode, IMacroDefinitionNode) private FName: IIdentifierNode; FParameters: IParameterList; FBody: IAstNode; function GetName: IIdentifierNode; function GetParameters: IParameterList; function GetBody: IAstNode; protected function GetKind: TAstNodeKind; override; public constructor Create( const AName: IIdentifierNode; const AParameters: IParameterList; const ABody: IAstNode; const AIdentity: IAstIdentity ); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsMacroDefinition: IMacroDefinitionNode; override; end; TMacroExpansionNode = class(TAstTypedNode, IMacroExpansionNode) private FCallNode: IFunctionCallNode; FExpandedBody: IAstNode; function GetCallNode: IFunctionCallNode; function GetExpandedBody: IAstNode; protected function GetKind: TAstNodeKind; override; public constructor Create(const ACallNode: IFunctionCallNode; const AExpandedBody: IAstNode; const AIdentity: IAstIdentity); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsMacroExpansion: IMacroExpansionNode; override; end; TQuasiquoteNode = class(TAstNode, IQuasiquoteNode) private FExpression: IAstNode; function GetExpression: IAstNode; protected function GetKind: TAstNodeKind; override; public constructor Create(const AExpression: IAstNode; const AIdentity: IAstIdentity); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsQuasiquote: IQuasiquoteNode; override; end; TUnquoteNode = class(TAstNode, IUnquoteNode) private FExpression: IAstNode; function GetExpression: IAstNode; protected function GetKind: TAstNodeKind; override; public constructor Create(const AExpression: IAstNode; const AIdentity: IAstIdentity); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsUnquote: IUnquoteNode; override; end; TUnquoteSplicingNode = class(TAstNode, IUnquoteSplicingNode) private FExpression: IQuasiquoteNode; function GetExpression: IQuasiquoteNode; protected function GetKind: TAstNodeKind; override; public constructor Create(const AExpression: IQuasiquoteNode; const AIdentity: IAstIdentity); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsUnquoteSplicing: IUnquoteSplicingNode; override; end; TRecurNode = class(TAstTypedNode, IRecurNode) private FArguments: IArgumentList; function GetArguments: IArgumentList; protected function GetKind: TAstNodeKind; override; public constructor Create(const AArguments: IArgumentList; const AStaticType: IStaticType; const AIdentity: IAstIdentity); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsRecur: IRecurNode; override; end; TBlockExpressionNode = class(TAstTypedNode, IBlockExpressionNode) private FExpressions: IExpressionList; function GetExpressions: IExpressionList; protected function GetKind: TAstNodeKind; override; public constructor Create(const AExpressions: IExpressionList; const AStaticType: IStaticType; const AIdentity: IAstIdentity); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsBlockExpression: IBlockExpressionNode; override; end; TVariableDeclarationNode = class(TAstTypedNode, IVariableDeclarationNode) private FTarget, FInitializer: IAstNode; FIsBoxed: Boolean; function GetTarget: IAstNode; function GetInitializer: IAstNode; function GetIsBoxed: Boolean; protected function GetKind: TAstNodeKind; override; public constructor Create( const ATarget: IAstNode; AInitializer: IAstNode; const AStaticType: IStaticType; const AIsBoxed: Boolean; const AIdentity: IAstIdentity ); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsVariableDeclaration: IVariableDeclarationNode; override; end; TAssignmentNode = class(TAstTypedNode, IAssignmentNode) private FTarget, FValue: IAstNode; function GetTarget: IAstNode; function GetValue: IAstNode; protected function GetKind: TAstNodeKind; override; public constructor Create(const ATarget, AValue: IAstNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsAssignment: IAssignmentNode; override; end; TIndexerNode = class(TAstTypedNode, IIndexerNode) private FBase, FIndex: IAstNode; function GetBase: IAstNode; function GetIndex: IAstNode; protected function GetKind: TAstNodeKind; override; public constructor Create(const ABase, AIndex: IAstNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsIndexer: IIndexerNode; override; end; TMemberAccessNode = class(TAstTypedNode, IMemberAccessNode) private FBase: IAstNode; FMember: IKeywordNode; function GetBase: IAstNode; function GetMember: IKeywordNode; protected function GetKind: TAstNodeKind; override; public constructor Create( const ABase: IAstNode; const AMember: IKeywordNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity ); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsMemberAccess: IMemberAccessNode; override; end; TRecordLiteralNode = class(TAstTypedNode, IRecordLiteralNode) private FFields: IRecordFieldList; FScalarDef: IScalarRecordDefinition; FGenericDef: IGenericRecordDefinition; function GetFields: IRecordFieldList; function GetGenericDefinition: IGenericRecordDefinition; function GetScalarDefinition: IScalarRecordDefinition; protected function GetKind: TAstNodeKind; override; public constructor Create( const AFields: IRecordFieldList; const AScalarDef: IScalarRecordDefinition; const AGenericDef: IGenericRecordDefinition; const AStaticType: IStaticType; const AIdentity: IAstIdentity ); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsRecordLiteral: IRecordLiteralNode; override; end; TAddSeriesItemNode = class(TAstTypedNode, IAddSeriesItemNode) private FSeries: IIdentifierNode; FValue, FLookback: IAstNode; function GetSeries: IIdentifierNode; function GetValue: IAstNode; function GetLookback: IAstNode; protected function GetKind: TAstNodeKind; override; public constructor Create( const ASeries: IIdentifierNode; const AValue, ALookback: IAstNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity ); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsAddSeriesItem: IAddSeriesItemNode; override; end; TSeriesLengthNode = class(TAstTypedNode, ISeriesLengthNode) private FSeries: IIdentifierNode; function GetSeries: IIdentifierNode; protected function GetKind: TAstNodeKind; override; public constructor Create(const ASeries: IIdentifierNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsSeriesLength: ISeriesLengthNode; override; end; TNopNode = class(TAstTypedNode, INopNode) protected function GetKind: TAstNodeKind; override; public constructor Create(const AStaticType: IStaticType; const AIdentity: IAstIdentity); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsNop: INopNode; override; end; TPipeSelectorList = class(TAstNodeList, IPipeSelectorList) protected function GetKind: TAstNodeKind; override; public function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsPipeSelectorList: IPipeSelectorList; override; end; TPipeInputNode = class(TAstTypedNode, IPipeInputNode) private FStreamSource: IIdentifierNode; FSelectors: IPipeSelectorList; function GetStreamSource: IIdentifierNode; function GetSelectors: IPipeSelectorList; protected function GetKind: TAstNodeKind; override; public constructor Create( const AStreamSource: IIdentifierNode; const ASelectors: IPipeSelectorList; const AIdentity: IAstIdentity; const AStaticType: IStaticType ); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsPipeInput: IPipeInputNode; override; end; TPipeInputList = class(TAstNodeList, IPipeInputList) protected function GetKind: TAstNodeKind; override; public function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsPipeInputList: IPipeInputList; override; end; TPipeNode = class(TAstTypedNode, IPipeNode) private FInputs: IPipeInputList; FTransformation: ILambdaExpressionNode; function GetInputs: IPipeInputList; function GetTransformation: ILambdaExpressionNode; protected function GetKind: TAstNodeKind; override; public constructor Create( const AInputs: IPipeInputList; const ATransformation: ILambdaExpressionNode; const AIdentity: IAstIdentity; const AStaticType: IStaticType ); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsPipe: IPipeNode; override; end; implementation uses System.Classes, System.Rtti, System.StrUtils; { TCompiledFunction } constructor TCompiledFunction.Create(const AFunc: TDataValue.TFunc; const AStaticType: IStaticType; AIsPure: Boolean); begin Func := AFunc; StaticType := AStaticType; IsPure := AIsPure; end; { TAstNodeKindHelper } function TAstNodeKindHelper.ToString: string; begin Result := TRttiEnumerationType.GetName(Self); Assert(StartsText('ak', Result)); Result := Result.Substring(2); end; { TCondPair } constructor TCondPair.Create(const ACondition, ABranch: IAstNode); begin Condition := ACondition; Branch := ABranch; end; { TCompilerError } constructor TCompilerError.Create(ALevel: TCompilerErrorLevel; const AMessage: string; const ANode: IAstNode); begin Level := ALevel; Message := AMessage; Node := ANode; end; function TCompilerError.ToString: string; var location: string; begin location := ''; if Assigned(Node) and Assigned(Node.Identity) and Assigned(Node.Identity.Location) then begin location := Node.Identity.Location.ToString + ' '; end else if Assigned(Node) and Assigned(Node.Identity) then begin location := '[' + Node.Identity.ToString + '] '; end; case Level of elHint: Result := '[Hint] '; elWarning: Result := '[Warning] '; elError: Result := '[Error] '; end; Result := Result + location + Message; end; { TCompilerLog } constructor TCompilerLog.Create; begin inherited Create; FEntries := TList.Create; end; destructor TCompilerLog.Destroy; begin FEntries.Free; inherited; end; procedure TCompilerLog.Add(ALevel: TCompilerErrorLevel; const AMessage: string; const ANode: IAstNode); begin FEntries.Add(TCompilerError.Create(ALevel, AMessage, ANode)); end; procedure TCompilerLog.AddError(const AMessage: string; const ANode: IAstNode); begin Add(elError, AMessage, ANode); end; procedure TCompilerLog.AddWarning(const AMessage: string; const ANode: IAstNode); begin Add(elWarning, AMessage, ANode); end; function TCompilerLog.HasErrors: Boolean; var entry: TCompilerError; begin Result := False; for entry in FEntries do if entry.Level = elError then Exit(True); end; function TCompilerLog.GetEntryCount: Integer; begin Result := FEntries.Count; end; function TCompilerLog.GetEntries: TArray; begin Result := FEntries.ToArray; end; { ECompilationFailed } constructor ECompilationFailed.Create(const AErrors: TArray); var msg: string; begin if Length(AErrors) > 0 then msg := Format('Compilation failed with %d error(s). First: %s', [Length(AErrors), AErrors[0].Message]) else msg := 'Compilation failed with unspecified errors.'; inherited Create(msg); FErrors := AErrors; end; function ECompilationFailed.ToString: string; var sb: TStringBuilder; err: TCompilerError; begin sb := TStringBuilder.Create; try sb.AppendLine(Message); for err in FErrors do begin sb.Append(' - '); sb.AppendLine(err.ToString); end; Result := sb.ToString; finally sb.Free; end; end; { TAstNode } constructor TAstNode.Create(const AIdentity: IAstIdentity); begin inherited Create; FIdentity := AIdentity; end; function TAstNode.GetIdentity: IAstIdentity; begin Result := FIdentity; end; function TAstNode.GetIsTyped: Boolean; begin Result := False; end; // Default implementations for As... casting methods (Return nil) function TAstNode.AsConstant: IConstantNode; begin Result := nil; end; function TAstNode.AsIdentifier: IIdentifierNode; begin Result := nil; end; function TAstNode.AsKeyword: IKeywordNode; begin Result := nil; end; function TAstNode.AsParameterList: IParameterList; begin Result := nil; end; function TAstNode.AsArgumentList: IArgumentList; begin Result := nil; end; function TAstNode.AsExpressionList: IExpressionList; begin Result := nil; end; function TAstNode.AsRecordFieldList: IRecordFieldList; begin Result := nil; end; function TAstNode.AsRecordField: IRecordFieldNode; begin Result := nil; end; function TAstNode.AsIfExpression: IIfExpressionNode; begin Result := nil; end; function TAstNode.AsCondExpression: ICondExpressionNode; begin Result := nil; end; function TAstNode.AsLambdaExpression: ILambdaExpressionNode; begin Result := nil; end; function TAstNode.AsFunctionCall: IFunctionCallNode; begin Result := nil; end; function TAstNode.AsMacroExpansion: IMacroExpansionNode; begin Result := nil; end; function TAstNode.AsBlockExpression: IBlockExpressionNode; begin Result := nil; end; function TAstNode.AsVariableDeclaration: IVariableDeclarationNode; begin Result := nil; end; function TAstNode.AsAssignment: IAssignmentNode; begin Result := nil; end; function TAstNode.AsMacroDefinition: IMacroDefinitionNode; begin Result := nil; end; function TAstNode.AsQuasiquote: IQuasiquoteNode; begin Result := nil; end; function TAstNode.AsUnquote: IUnquoteNode; begin Result := nil; end; function TAstNode.AsUnquoteSplicing: IUnquoteSplicingNode; begin Result := nil; end; function TAstNode.AsIndexer: IIndexerNode; begin Result := nil; end; function TAstNode.AsMemberAccess: IMemberAccessNode; begin Result := nil; end; function TAstNode.AsRecordLiteral: IRecordLiteralNode; begin Result := nil; end; function TAstNode.AsCreateSeries: ICreateSeriesNode; begin Result := nil; end; function TAstNode.AsAddSeriesItem: IAddSeriesItemNode; begin Result := nil; end; function TAstNode.AsSeriesLength: ISeriesLengthNode; begin Result := nil; end; function TAstNode.AsRecur: IRecurNode; begin Result := nil; end; function TAstNode.AsNop: INopNode; begin Result := nil; end; function TAstNode.AsTypedNode: IAstTypedNode; begin Result := nil; end; function TAstNode.AsPipeInput: IPipeInputNode; begin Result := nil; end; function TAstNode.AsPipeSelectorList: IPipeSelectorList; begin Result := nil; end; function TAstNode.AsPipeInputList: IPipeInputList; begin Result := nil; end; function TAstNode.AsPipe: IPipeNode; begin Result := nil; end; { TAstTypedNode } constructor TAstTypedNode.Create(const AStaticType: IStaticType; const AIdentity: IAstIdentity); begin inherited Create(AIdentity); FStaticType := AStaticType; end; function TAstTypedNode.GetStaticType: IStaticType; begin Result := FStaticType; end; function TAstTypedNode.GetIsTyped: Boolean; begin Result := True; end; function TAstTypedNode.AsTypedNode: IAstTypedNode; begin Result := Self; end; { TAstNodeList } constructor TAstNodeList.Create(const AItems: TArray; const AIdentity: IAstIdentity); begin inherited Create(AIdentity); FItems := AItems; end; function TAstNodeList.GetCount: Integer; begin Result := Length(FItems); end; function TAstNodeList.GetEnumerator: TEnumerator; begin Result := TEnumerator.Create(FItems); end; function TAstNodeList.GetItem(Index: Integer): T; begin Result := FItems[Index]; end; function TAstNodeList.ToArray: TArray; begin Result := FItems; end; { TParameterList } function TParameterList.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitParameterList(Self); end; function TParameterList.AsParameterList: IParameterList; begin Result := Self; end; function TParameterList.GetKind: TAstNodeKind; begin Result := akParameterList; end; { TArgumentList } function TArgumentList.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitArgumentList(Self); end; function TArgumentList.AsArgumentList: IArgumentList; begin Result := Self; end; function TArgumentList.GetKind: TAstNodeKind; begin Result := akArgumentList; end; { TExpressionList } function TExpressionList.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitExpressionList(Self); end; function TExpressionList.AsExpressionList: IExpressionList; begin Result := Self; end; function TExpressionList.GetKind: TAstNodeKind; begin Result := akExpressionList; end; { TRecordFieldNode } constructor TRecordFieldNode.Create(const AKey: IKeywordNode; const AValue: IAstNode; const AIdentity: IAstIdentity); begin inherited Create(AIdentity); FKey := AKey; FValue := AValue; end; function TRecordFieldNode.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitRecordField(Self); end; function TRecordFieldNode.AsRecordField: IRecordFieldNode; begin Result := Self; end; function TRecordFieldNode.GetKey: IKeywordNode; begin Result := FKey; end; function TRecordFieldNode.GetKind: TAstNodeKind; begin Result := akRecordField; end; function TRecordFieldNode.GetValue: IAstNode; begin Result := FValue; end; { TRecordFieldList } function TRecordFieldList.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitRecordFieldList(Self); end; function TRecordFieldList.AsRecordFieldList: IRecordFieldList; begin Result := Self; end; function TRecordFieldList.GetKind: TAstNodeKind; begin Result := akRecordFieldList; end; { TConstantNode } constructor TConstantNode.Create(const AIdentity: IConstantIdentity; const AStaticType: IStaticType); begin inherited Create(AStaticType, AIdentity); FConstIdentity := AIdentity; end; function TConstantNode.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitConstant(Self); end; function TConstantNode.AsConstant: IConstantNode; begin Result := Self; end; function TConstantNode.GetKind: TAstNodeKind; begin Result := akConstant; end; function TConstantNode.GetValue: TDataValue; begin Result := FConstIdentity.Value; end; { TIdentifierNode } constructor TIdentifierNode.Create(const AIdentity: INamedIdentity; const AAddress: TResolvedAddress; const AStaticType: IStaticType); begin inherited Create(AStaticType, AIdentity); FNamedIdentity := AIdentity; FAddress := AAddress; end; function TIdentifierNode.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitIdentifier(Self); end; function TIdentifierNode.AsIdentifier: IIdentifierNode; begin Result := Self; end; function TIdentifierNode.GetAddress: TResolvedAddress; begin Result := FAddress; end; function TIdentifierNode.GetKind: TAstNodeKind; begin Result := akIdentifier; end; function TIdentifierNode.GetName: string; begin Result := FNamedIdentity.Name; end; { TKeywordNode } constructor TKeywordNode.Create(const AIdentity: IKeywordIdentity); begin inherited Create(TTypes.Keyword, AIdentity); FKeywordIdentity := AIdentity; end; function TKeywordNode.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitKeyword(Self); end; function TKeywordNode.AsKeyword: IKeywordNode; begin Result := Self; end; function TKeywordNode.GetKind: TAstNodeKind; begin Result := akKeyword; end; function TKeywordNode.GetValue: IKeyword; begin Result := FKeywordIdentity.Value; end; { TCreateSeriesNode } constructor TCreateSeriesNode.Create(const AIdentity: IDefinitionIdentity; const AStaticType: IStaticType); begin inherited Create(AStaticType, AIdentity); FDefIdentity := AIdentity; end; function TCreateSeriesNode.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitCreateSeries(Self); end; function TCreateSeriesNode.AsCreateSeries: ICreateSeriesNode; begin Result := Self; end; function TCreateSeriesNode.GetDefinition: String; begin Result := FDefIdentity.Definition; end; function TCreateSeriesNode.GetKind: TAstNodeKind; begin Result := akCreateSeries; end; { TIfExpressionNode } constructor TIfExpressionNode.Create( const ACondition, AThenBranch, AElseBranch: IAstNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity ); begin inherited Create(AStaticType, AIdentity); FCondition := ACondition; FThenBranch := AThenBranch; FElseBranch := AElseBranch; end; function TIfExpressionNode.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitIfExpression(Self); end; function TIfExpressionNode.AsIfExpression: IIfExpressionNode; begin Result := Self; end; function TIfExpressionNode.GetCondition: IAstNode; begin Result := FCondition; end; function TIfExpressionNode.GetThenBranch: IAstNode; begin Result := FThenBranch; end; function TIfExpressionNode.GetElseBranch: IAstNode; begin Result := FElseBranch; end; function TIfExpressionNode.GetKind: TAstNodeKind; begin Result := akIfExpression; end; { TCondExpressionNode } constructor TCondExpressionNode.Create( const APairs: TArray; const AElseBranch: IAstNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity ); begin inherited Create(AStaticType, AIdentity); FPairs := APairs; FElseBranch := AElseBranch; end; function TCondExpressionNode.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitCondExpression(Self); end; function TCondExpressionNode.AsCondExpression: ICondExpressionNode; begin Result := Self; end; function TCondExpressionNode.GetPairs: TArray; begin Result := FPairs; end; function TCondExpressionNode.GetElseBranch: IAstNode; begin Result := FElseBranch; end; function TCondExpressionNode.GetKind: TAstNodeKind; begin Result := akCondExpression; end; { TLambdaExpressionNode } constructor TLambdaExpressionNode.Create( const AParameters: IParameterList; const ABody: IAstNode; const AStaticType: IStaticType; const ALayout: IScopeLayout; const ADescriptor: IScopeDescriptor; const AUpvalues: TArray; const AHasNestedLambdas, AIsPure: Boolean; const AIdentity: IAstIdentity ); begin inherited Create(AStaticType, AIdentity); FParameters := AParameters; FBody := ABody; FLayout := ALayout; FDescriptor := ADescriptor; FUpvalues := AUpvalues; FHasNestedLambdas := AHasNestedLambdas; FIsPure := AIsPure; end; function TLambdaExpressionNode.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitLambdaExpression(Self); end; function TLambdaExpressionNode.AsLambdaExpression: ILambdaExpressionNode; begin Result := Self; end; function TLambdaExpressionNode.GetBody: IAstNode; begin Result := FBody; end; function TLambdaExpressionNode.GetParameters: IParameterList; begin Result := FParameters; end; function TLambdaExpressionNode.GetLayout: IScopeLayout; begin Result := FLayout; end; function TLambdaExpressionNode.GetDescriptor: IScopeDescriptor; begin Result := FDescriptor; end; function TLambdaExpressionNode.GetUpvalues: TArray; begin Result := FUpvalues; end; function TLambdaExpressionNode.GetHasNestedLambdas: Boolean; begin Result := FHasNestedLambdas; end; function TLambdaExpressionNode.GetIsPure: Boolean; begin Result := FIsPure; end; function TLambdaExpressionNode.GetKind: TAstNodeKind; begin Result := akLambdaExpression; end; { TFunctionCallNode } constructor TFunctionCallNode.Create( const ACallee: IAstNode; const AArguments: IArgumentList; const AStaticType: IStaticType; const AIsTailCall: Boolean; const AStaticTarget: TDataValue.TFunc; const AIsTargetPure: Boolean; const AIdentity: IAstIdentity ); begin inherited Create(AStaticType, AIdentity); FCallee := ACallee; FArguments := AArguments; FIsTailCall := AIsTailCall; FStaticTarget := AStaticTarget; FIsTargetPure := AIsTargetPure; end; function TFunctionCallNode.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitFunctionCall(Self); end; function TFunctionCallNode.AsFunctionCall: IFunctionCallNode; begin Result := Self; end; function TFunctionCallNode.GetCallee: IAstNode; begin Result := FCallee; end; function TFunctionCallNode.GetArguments: IArgumentList; begin Result := FArguments; end; function TFunctionCallNode.GetIsTailCall: Boolean; begin Result := FIsTailCall; end; function TFunctionCallNode.GetStaticTarget: TDataValue.TFunc; begin Result := FStaticTarget; end; function TFunctionCallNode.GetIsTargetPure: Boolean; begin Result := FIsTargetPure; end; function TFunctionCallNode.GetKind: TAstNodeKind; begin Result := akFunctionCall; end; { TMacroDefinitionNode } constructor TMacroDefinitionNode.Create( const AName: IIdentifierNode; const AParameters: IParameterList; const ABody: IAstNode; const AIdentity: IAstIdentity ); begin inherited Create(TTypes.Void, AIdentity); FName := AName; FParameters := AParameters; FBody := ABody; end; function TMacroDefinitionNode.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitMacroDefinition(Self); end; function TMacroDefinitionNode.AsMacroDefinition: IMacroDefinitionNode; begin Result := Self; end; function TMacroDefinitionNode.GetName: IIdentifierNode; begin Result := FName; end; function TMacroDefinitionNode.GetParameters: IParameterList; begin Result := FParameters; end; function TMacroDefinitionNode.GetBody: IAstNode; begin Result := FBody; end; function TMacroDefinitionNode.GetKind: TAstNodeKind; begin Result := akMacroDefinition; end; { TMacroExpansionNode } constructor TMacroExpansionNode.Create(const ACallNode: IFunctionCallNode; const AExpandedBody: IAstNode; const AIdentity: IAstIdentity); begin if AExpandedBody.IsTyped then inherited Create(AExpandedBody.AsTypedNode.StaticType, AIdentity) else inherited Create(TTypes.Unknown, AIdentity); FCallNode := ACallNode; FExpandedBody := AExpandedBody; end; function TMacroExpansionNode.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitMacroExpansionNode(Self); end; function TMacroExpansionNode.AsMacroExpansion: IMacroExpansionNode; begin Result := Self; end; function TMacroExpansionNode.GetCallNode: IFunctionCallNode; begin Result := FCallNode; end; function TMacroExpansionNode.GetExpandedBody: IAstNode; begin Result := FExpandedBody; end; function TMacroExpansionNode.GetKind: TAstNodeKind; begin Result := akMacroExpansion; end; { TQuasiquoteNode } constructor TQuasiquoteNode.Create(const AExpression: IAstNode; const AIdentity: IAstIdentity); begin inherited Create(AIdentity); FExpression := AExpression; end; function TQuasiquoteNode.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitQuasiquote(Self); end; function TQuasiquoteNode.AsQuasiquote: IQuasiquoteNode; begin Result := Self; end; function TQuasiquoteNode.GetExpression: IAstNode; begin Result := FExpression; end; function TQuasiquoteNode.GetKind: TAstNodeKind; begin Result := akQuasiquote; end; { TUnquoteNode } constructor TUnquoteNode.Create(const AExpression: IAstNode; const AIdentity: IAstIdentity); begin inherited Create(AIdentity); FExpression := AExpression; end; function TUnquoteNode.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitUnquote(Self); end; function TUnquoteNode.AsUnquote: IUnquoteNode; begin Result := Self; end; function TUnquoteNode.GetExpression: IAstNode; begin Result := FExpression; end; function TUnquoteNode.GetKind: TAstNodeKind; begin Result := akUnquote; end; { TUnquoteSplicingNode } constructor TUnquoteSplicingNode.Create(const AExpression: IQuasiquoteNode; const AIdentity: IAstIdentity); begin inherited Create(AIdentity); FExpression := AExpression; end; function TUnquoteSplicingNode.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitUnquoteSplicing(Self); end; function TUnquoteSplicingNode.AsUnquoteSplicing: IUnquoteSplicingNode; begin Result := Self; end; function TUnquoteSplicingNode.GetExpression: IQuasiquoteNode; begin Result := FExpression; end; function TUnquoteSplicingNode.GetKind: TAstNodeKind; begin Result := akUnquoteSplicing; end; { TRecurNode } constructor TRecurNode.Create(const AArguments: IArgumentList; const AStaticType: IStaticType; const AIdentity: IAstIdentity); begin inherited Create(AStaticType, AIdentity); FArguments := AArguments; end; function TRecurNode.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitRecurNode(Self); end; function TRecurNode.AsRecur: IRecurNode; begin Result := Self; end; function TRecurNode.GetArguments: IArgumentList; begin Result := FArguments; end; function TRecurNode.GetKind: TAstNodeKind; begin Result := akRecur; end; { TBlockExpressionNode } constructor TBlockExpressionNode.Create(const AExpressions: IExpressionList; const AStaticType: IStaticType; const AIdentity: IAstIdentity); begin inherited Create(AStaticType, AIdentity); FExpressions := AExpressions; end; function TBlockExpressionNode.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitBlockExpression(Self); end; function TBlockExpressionNode.AsBlockExpression: IBlockExpressionNode; begin Result := Self; end; function TBlockExpressionNode.GetExpressions: IExpressionList; begin Result := FExpressions; end; function TBlockExpressionNode.GetKind: TAstNodeKind; begin Result := akBlockExpression; end; { TVariableDeclarationNode } constructor TVariableDeclarationNode.Create( const ATarget: IAstNode; AInitializer: IAstNode; const AStaticType: IStaticType; const AIsBoxed: Boolean; const AIdentity: IAstIdentity ); begin inherited Create(AStaticType, AIdentity); FTarget := ATarget; FInitializer := AInitializer; FIsBoxed := AIsBoxed; end; function TVariableDeclarationNode.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitVariableDeclaration(Self); end; function TVariableDeclarationNode.AsVariableDeclaration: IVariableDeclarationNode; begin Result := Self; end; function TVariableDeclarationNode.GetTarget: IAstNode; begin Result := FTarget; end; function TVariableDeclarationNode.GetInitializer: IAstNode; begin Result := FInitializer; end; function TVariableDeclarationNode.GetIsBoxed: Boolean; begin Result := FIsBoxed; end; function TVariableDeclarationNode.GetKind: TAstNodeKind; begin Result := akVariableDeclaration; end; { TAssignmentNode } constructor TAssignmentNode.Create(const ATarget, AValue: IAstNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity); begin inherited Create(AStaticType, AIdentity); FTarget := ATarget; FValue := AValue; end; function TAssignmentNode.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitAssignment(Self); end; function TAssignmentNode.AsAssignment: IAssignmentNode; begin Result := Self; end; function TAssignmentNode.GetTarget: IAstNode; begin Result := FTarget; end; function TAssignmentNode.GetValue: IAstNode; begin Result := FValue; end; function TAssignmentNode.GetKind: TAstNodeKind; begin Result := akAssignment; end; { TIndexerNode } constructor TIndexerNode.Create(const ABase, AIndex: IAstNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity); begin inherited Create(AStaticType, AIdentity); FBase := ABase; FIndex := AIndex; end; function TIndexerNode.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitIndexer(Self); end; function TIndexerNode.AsIndexer: IIndexerNode; begin Result := Self; end; function TIndexerNode.GetBase: IAstNode; begin Result := FBase; end; function TIndexerNode.GetIndex: IAstNode; begin Result := FIndex; end; function TIndexerNode.GetKind: TAstNodeKind; begin Result := akIndexer; end; { TMemberAccessNode } constructor TMemberAccessNode.Create( const ABase: IAstNode; const AMember: IKeywordNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity ); begin inherited Create(AStaticType, AIdentity); FBase := ABase; FMember := AMember; end; function TMemberAccessNode.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitMemberAccess(Self); end; function TMemberAccessNode.AsMemberAccess: IMemberAccessNode; begin Result := Self; end; function TMemberAccessNode.GetBase: IAstNode; begin Result := FBase; end; function TMemberAccessNode.GetMember: IKeywordNode; begin Result := FMember; end; function TMemberAccessNode.GetKind: TAstNodeKind; begin Result := akMemberAccess; end; { TRecordLiteralNode } constructor TRecordLiteralNode.Create( const AFields: IRecordFieldList; const AScalarDef: IScalarRecordDefinition; const AGenericDef: IGenericRecordDefinition; const AStaticType: IStaticType; const AIdentity: IAstIdentity ); begin inherited Create(AStaticType, AIdentity); FFields := AFields; FScalarDef := AScalarDef; FGenericDef := AGenericDef; end; function TRecordLiteralNode.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitRecordLiteral(Self); end; function TRecordLiteralNode.AsRecordLiteral: IRecordLiteralNode; begin Result := Self; end; function TRecordLiteralNode.GetFields: IRecordFieldList; begin Result := FFields; end; function TRecordLiteralNode.GetGenericDefinition: IGenericRecordDefinition; begin Result := FGenericDef; end; function TRecordLiteralNode.GetScalarDefinition: IScalarRecordDefinition; begin Result := FScalarDef; end; function TRecordLiteralNode.GetKind: TAstNodeKind; begin Result := akRecordLiteral; end; { TAddSeriesItemNode } constructor TAddSeriesItemNode.Create( const ASeries: IIdentifierNode; const AValue, ALookback: IAstNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity ); begin inherited Create(AStaticType, AIdentity); FSeries := ASeries; FValue := AValue; FLookback := ALookback; end; function TAddSeriesItemNode.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitAddSeriesItem(Self); end; function TAddSeriesItemNode.AsAddSeriesItem: IAddSeriesItemNode; begin Result := Self; end; function TAddSeriesItemNode.GetSeries: IIdentifierNode; begin Result := FSeries; end; function TAddSeriesItemNode.GetValue: IAstNode; begin Result := FValue; end; function TAddSeriesItemNode.GetLookback: IAstNode; begin Result := FLookback; end; function TAddSeriesItemNode.GetKind: TAstNodeKind; begin Result := akAddSeriesItem; end; { TSeriesLengthNode } constructor TSeriesLengthNode.Create(const ASeries: IIdentifierNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity); begin inherited Create(AStaticType, AIdentity); FSeries := ASeries; end; function TSeriesLengthNode.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitSeriesLength(Self); end; function TSeriesLengthNode.AsSeriesLength: ISeriesLengthNode; begin Result := Self; end; function TSeriesLengthNode.GetSeries: IIdentifierNode; begin Result := FSeries; end; function TSeriesLengthNode.GetKind: TAstNodeKind; begin Result := akSeriesLength; end; { TNopNode } constructor TNopNode.Create(const AStaticType: IStaticType; const AIdentity: IAstIdentity); begin inherited Create(AStaticType, AIdentity); end; function TNopNode.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitNop(Self); end; function TNopNode.AsNop: INopNode; begin Result := Self; end; function TNopNode.GetKind: TAstNodeKind; begin Result := akNop; end; constructor TAstNodeList.TEnumerator.Create(const AArray: TArray); begin inherited Create; FArray := AArray; FIndex := -1; end; function TAstNodeList.TEnumerator.DoGetCurrent: T; begin Result := Current; end; function TAstNodeList.TEnumerator.DoMoveNext: Boolean; begin Result := MoveNext; end; function TAstNodeList.TEnumerator.GetCurrent: T; begin Result := FArray[FIndex]; end; function TAstNodeList.TEnumerator.MoveNext: Boolean; begin Result := FIndex < High(FArray); if Result then Inc(FIndex); end; { TPipeSelectorList } function TPipeSelectorList.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitPipeSelectorList(Self); end; function TPipeSelectorList.AsPipeSelectorList: IPipeSelectorList; begin Result := Self; end; function TPipeSelectorList.GetKind: TAstNodeKind; begin Result := akPipeSelectorList; end; { TPipeInputNode } constructor TPipeInputNode.Create( const AStreamSource: IIdentifierNode; const ASelectors: IPipeSelectorList; const AIdentity: IAstIdentity; const AStaticType: IStaticType ); begin inherited Create(AStaticType, AIdentity); FStreamSource := AStreamSource; FSelectors := ASelectors; end; function TPipeInputNode.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitPipeInput(Self); end; function TPipeInputNode.AsPipeInput: IPipeInputNode; begin Result := Self; end; function TPipeInputNode.GetKind: TAstNodeKind; begin Result := akPipeInput; end; function TPipeInputNode.GetSelectors: IPipeSelectorList; begin Result := FSelectors; end; function TPipeInputNode.GetStreamSource: IIdentifierNode; begin Result := FStreamSource; end; { TPipeInputList } function TPipeInputList.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitPipeInputList(Self); end; function TPipeInputList.AsPipeInputList: IPipeInputList; begin Result := Self; end; function TPipeInputList.GetKind: TAstNodeKind; begin Result := akPipeInputList; end; { TPipeNode } constructor TPipeNode.Create( const AInputs: IPipeInputList; const ATransformation: ILambdaExpressionNode; const AIdentity: IAstIdentity; const AStaticType: IStaticType ); begin inherited Create(AStaticType, AIdentity); FInputs := AInputs; FTransformation := ATransformation; end; function TPipeNode.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitPipe(Self); end; function TPipeNode.AsPipe: IPipeNode; begin Result := Self; end; function TPipeNode.GetInputs: IPipeInputList; begin Result := FInputs; end; function TPipeNode.GetKind: TAstNodeKind; begin Result := akPipe; end; function TPipeNode.GetTransformation: ILambdaExpressionNode; begin Result := FTransformation; end; end.