unit Myc.Ast; interface uses System.SysUtils, System.Classes, System.Generics.Collections, Myc.Data.Scalar, Myc.Data.Value, Myc.Data.Keyword, Myc.Ast.Nodes, Myc.Ast.Scope, Myc.Ast.Types; type // Record acting as a namespace for the factory functions. TAst = record public type TRegisterLibraryProc = reference to procedure(const Scope: IExecutionScope); private class var FLibraries: TList; class constructor Create; class destructor Destroy; public class procedure RegisterLibrary(const AProc: TRegisterLibraryProc); static; class function CreateScope( Parent: IExecutionScope; const Descriptor: IScopeDescriptor = nil; ARegisterLibraries: Boolean = False ): IExecutionScope; static; // A No-Operation node, used as a placeholder/stub. class function Nop(const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil): IAstNode; static; // --- Factory functions --- class function Constant( const AValue: TDataValue; const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil ): IConstantNode; overload; static; class function Constant(const AValue: String; const Identity: IAstIdentity = nil): IConstantNode; overload; static; class function Keyword(const AName: string; const Identity: IAstIdentity = nil): IKeywordNode; static; class function Identifier( AName: string; const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil ): IIdentifierNode; overload; static; class function Identifier( AName: string; const Address: TResolvedAddress; const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil ): IIdentifierNode; overload; static; class function IfExpr( const ACondition: IAstNode; const AThenBranch, AElseBranch: IAstNode; const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil ): IIfExpressionNode; static; class function TernaryExpr( const ACondition: IAstNode; const AThenBranch, AElseBranch: IAstNode; const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil ): ITernaryExpressionNode; static; class function LambdaExpr( const AParameters: TArray; const ABody: IAstNode; const ALayout: IScopeLayout = nil; const ADescriptor: IScopeDescriptor = nil; const AUpvalues: TArray = nil; const AHasNestedLambdas: Boolean = False; const AIsPure: Boolean = False; const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil ): ILambdaExpressionNode; static; class function MacroDef( const AName: IIdentifierNode; const AParameters: TArray; const ABody: IAstNode; const Identity: IAstIdentity = nil ): IMacroDefinitionNode; static; class function Quasiquote(const AExpression: IAstNode; const Identity: IAstIdentity = nil): IQuasiquoteNode; static; class function Unquote(const AExpression: IAstNode; const Identity: IAstIdentity = nil): IUnquoteNode; static; class function UnquoteSplicing( const AExpression: IQuasiquoteNode; const Identity: IAstIdentity = nil ): IUnquoteSplicingNode; static; class function FunctionCall( const ACallee: IAstNode; const AArguments: TArray; const AStaticType: IStaticType = nil; const AIsTailCall: Boolean = False; const AStaticTarget: TDataValue.TFunc = nil; const AIsTargetPure: Boolean = False; const Identity: IAstIdentity = nil ): IFunctionCallNode; static; class function MacroExpansionNode( const AOriginalCallNode: IFunctionCallNode; const AExpandedBody: IAstNode; const Identity: IAstIdentity = nil ): IMacroExpansionNode; static; class function Recur( const AArguments: array of IAstNode; const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil ): IRecurNode; static; class function Block( const AExpressions: array of IAstNode; const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil ): IBlockExpressionNode; static; class function VarDecl( const AIdentifier: IAstNode; AInitializer: IAstNode = nil; const AStaticType: IStaticType = nil; const AIsBoxed: Boolean = False; const Identity: IAstIdentity = nil ): IVariableDeclarationNode; static; class function Assign( const ATarget, AValue: IAstNode; const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil ): IAssignmentNode; static; class function AssignResult(const AValue: IAstNode; const Identity: IAstIdentity = nil): IAssignmentNode; static; deprecated; class function Indexer( const ABase: IAstNode; const AIndex: IAstNode; const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil ): IIndexerNode; static; class function MemberAccess( const ABase: IAstNode; const AMember: IKeywordNode; const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil ): IMemberAccessNode; static; class function RecordLiteral( const AFields: TArray; const AScalarDefinition: IScalarRecordDefinition = nil; const AGenericDefinition: IGenericRecordDefinition = nil; const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil ): IRecordLiteralNode; static; class function CreateSeries( const ADefinition: String; const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil ): ICreateSeriesNode; static; class function AddSeriesItem( const ASeries: IIdentifierNode; const AValue: IAstNode; const ALookback: IAstNode = nil; const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil ): IAddSeriesItemNode; static; class function SeriesLength( const ASeries: IIdentifierNode; const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil ): ISeriesLengthNode; static; end; implementation uses System.Generics.Defaults; type // --- Concrete Class Definitions --- TAstNode = class(TInterfacedObject, IAstNode) private FIdentity: IAstIdentity; function GetKind: TAstNodeKind; virtual; abstract; function GetIsTyped: Boolean; virtual; function GetIdentity: IAstIdentity; public constructor Create(const AIdentity: IAstIdentity); function Accept(const Visitor: IAstVisitor): TDataValue; virtual; abstract; // --- As... Accessors Implementation --- function AsConstant: IConstantNode; virtual; function AsIdentifier: IIdentifierNode; virtual; function AsKeyword: IKeywordNode; virtual; function AsIfExpression: IIfExpressionNode; virtual; function AsTernaryExpression: ITernaryExpressionNode; 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 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; function GetIsTyped: Boolean; override; public constructor Create(const AStaticType: IStaticType; const AIdentity: IAstIdentity); function AsTypedNode: IAstTypedNode; override; property StaticType: IStaticType read GetStaticType; end; // Updated TLambdaExpressionNode TLambdaExpressionNode = class(TAstTypedNode, ILambdaExpressionNode, IFunctionDefinition) private FParameters: TArray; FBody: IAstNode; FLayout: IScopeLayout; FDescriptor: IScopeDescriptor; FUpvalues: TArray; FHasNestedLambdas: Boolean; FIsPure: Boolean; function GetParameters: TArray; function GetBody: IAstNode; function GetLayout: IScopeLayout; function GetDescriptor: IScopeDescriptor; function GetUpvalues: TArray; function GetHasNestedLambdas: Boolean; function GetIsPure: Boolean; function GetKind: TAstNodeKind; override; public constructor Create( const AParameters: TArray; const ABody: IAstNode; const AStaticType: IStaticType; const ALayout: IScopeLayout; const ADescriptor: IScopeDescriptor; const AUpvalues: TArray; const AHasNestedLambdas: Boolean; const AIsPure: Boolean; const AIdentity: IAstIdentity ); destructor Destroy; override; function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsLambdaExpression: ILambdaExpressionNode; override; end; TFunctionCallNode = class(TAstTypedNode, IFunctionCallNode) private FCallee: IAstNode; FArguments: TArray; FIsTailCall: Boolean; FStaticTarget: TDataValue.TFunc; FIsTargetPure: Boolean; function GetCallee: IAstNode; function GetArguments: TArray; function GetIsTailCall: Boolean; function GetStaticTarget: TDataValue.TFunc; function GetIsTargetPure: Boolean; function GetKind: TAstNodeKind; override; public constructor Create( const ACallee: IAstNode; const AArguments: TArray; 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; TVariableDeclarationNode = class(TAstTypedNode, IVariableDeclarationNode) private FInitializer: IAstNode; FTarget: IAstNode; FIsBoxed: Boolean; function GetTarget: IAstNode; function GetInitializer: IAstNode; function GetIsBoxed: Boolean; 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; TConstantNode = class(TAstTypedNode, IConstantNode) private FValue: TDataValue; function GetValue: TDataValue; function GetKind: TAstNodeKind; override; public constructor Create(const AValue: TDataValue; const AStaticType: IStaticType; const AIdentity: IAstIdentity); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsConstant: IConstantNode; override; property Value: TDataValue read GetValue; end; TIdentifierNode = class(TAstTypedNode, IIdentifierNode) private FAddress: TResolvedAddress; FName: string; function GetAddress: TResolvedAddress; function GetName: string; function GetKind: TAstNodeKind; override; public constructor Create( const AName: string; const AAddress: TResolvedAddress; const AStaticType: IStaticType; const AIdentity: IAstIdentity ); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsIdentifier: IIdentifierNode; override; property Address: TResolvedAddress read GetAddress; property Name: string read FName; end; TKeywordNode = class(TAstTypedNode, IKeywordNode) private FValue: IKeyword; function GetValue: IKeyword; function GetKind: TAstNodeKind; override; public constructor Create(const AValue: IKeyword; const AIdentity: IAstIdentity); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsKeyword: IKeywordNode; override; property Value: IKeyword read FValue; end; TMacroDefinitionNode = class(TAstTypedNode, IMacroDefinitionNode) private FName: IIdentifierNode; FParameters: TArray; FBody: IAstNode; function GetName: IIdentifierNode; function GetParameters: TArray; function GetBody: IAstNode; function GetKind: TAstNodeKind; override; public constructor Create( const AName: IIdentifierNode; const AParameters: TArray; const ABody: IAstNode; const AIdentity: IAstIdentity ); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsMacroDefinition: IMacroDefinitionNode; override; property Name: IIdentifierNode read GetName; property Parameters: TArray read FParameters; property Body: IAstNode read FBody; end; TQuasiquoteNode = class(TAstNode, IQuasiquoteNode) private FExpression: IAstNode; function GetExpression: IAstNode; function GetKind: TAstNodeKind; override; public constructor Create(const AExpression: IAstNode; const AIdentity: IAstIdentity); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsQuasiquote: IQuasiquoteNode; override; property Expression: IAstNode read GetExpression; end; TUnquoteNode = class(TAstNode, IUnquoteNode) private FExpression: IAstNode; function GetExpression: IAstNode; function GetKind: TAstNodeKind; override; public constructor Create(const AExpression: IAstNode; const AIdentity: IAstIdentity); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsUnquote: IUnquoteNode; override; property Expression: IAstNode read GetExpression; end; TUnquoteSplicingNode = class(TAstNode, IUnquoteSplicingNode) private FExpression: IQuasiquoteNode; function GetExpression: IQuasiquoteNode; function GetKind: TAstNodeKind; override; public constructor Create(const AExpression: IQuasiquoteNode; const AIdentity: IAstIdentity); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsUnquoteSplicing: IUnquoteSplicingNode; override; property Expression: IQuasiquoteNode read GetExpression; end; TMacroExpansionNode = class(TAstTypedNode, IMacroExpansionNode) private FCallNode: IFunctionCallNode; FExpandedBody: IAstNode; function GetCallNode: IFunctionCallNode; function GetExpandedBody: IAstNode; 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; property CallNode: IFunctionCallNode read GetCallNode; property ExpandedBody: IAstNode read FExpandedBody; end; TRecurNode = class(TAstTypedNode, IRecurNode) private FArguments: TArray; function GetArguments: TArray; function GetKind: TAstNodeKind; override; public constructor Create(const AArguments: TArray; const AStaticType: IStaticType; const AIdentity: IAstIdentity); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsRecur: IRecurNode; override; property Arguments: TArray read FArguments; end; TBlockExpressionNode = class(TAstTypedNode, IBlockExpressionNode) private FExpressions: TArray; function GetExpressions: TArray; function GetKind: TAstNodeKind; override; public constructor Create(const AExpressions: array of IAstNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsBlockExpression: IBlockExpressionNode; override; property Expressions: TArray read FExpressions; end; TIfExpressionNode = class(TAstTypedNode, IIfExpressionNode) private FCondition: IAstNode; FThenBranch: IAstNode; FElseBranch: IAstNode; function GetCondition: IAstNode; function GetThenBranch: IAstNode; function GetElseBranch: IAstNode; 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; property Condition: IAstNode read FCondition; property ThenBranch: IAstNode read FThenBranch; property ElseBranch: IAstNode read FElseBranch; end; TTernaryExpressionNode = class(TAstTypedNode, ITernaryExpressionNode) private FCondition: IAstNode; FThenBranch: IAstNode; FElseBranch: IAstNode; function GetCondition: IAstNode; function GetThenBranch: IAstNode; function GetElseBranch: IAstNode; 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 AsTernaryExpression: ITernaryExpressionNode; override; property Condition: IAstNode read FCondition; property ThenBranch: IAstNode read FThenBranch; property ElseBranch: IAstNode read FElseBranch; end; TAssignmentNode = class(TAstTypedNode, IAssignmentNode) private FTarget: IAstNode; FValue: IAstNode; function GetTarget: IAstNode; function GetValue: IAstNode; function GetKind: TAstNodeKind; override; public constructor Create(const ATarget: IAstNode; const AValue: IAstNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsAssignment: IAssignmentNode; override; property Target: IAstNode read FTarget; property Value: IAstNode read FValue; end; TIndexerNode = class(TAstTypedNode, IIndexerNode) private FBase: IAstNode; FIndex: IAstNode; function GetBase: IAstNode; function GetIndex: IAstNode; function GetKind: TAstNodeKind; override; public constructor Create(const ABase: IAstNode; const AIndex: IAstNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsIndexer: IIndexerNode; override; property Base: IAstNode read FBase; property Index: IAstNode read FIndex; end; TMemberAccessNode = class(TAstTypedNode, IMemberAccessNode) private FBase: IAstNode; FMember: IKeywordNode; function GetBase: IAstNode; function GetMember: IKeywordNode; 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; property Base: IAstNode read FBase; property Member: IKeywordNode read FMember; end; TCreateSeriesNode = class(TAstTypedNode, ICreateSeriesNode) private FDefinition: String; function GetDefinition: String; function GetKind: TAstNodeKind; override; public constructor Create(const ADefinition: String; const AStaticType: IStaticType; const AIdentity: IAstIdentity); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsCreateSeries: ICreateSeriesNode; override; property Definition: String read FDefinition; end; TAddSeriesItemNode = class(TAstTypedNode, IAddSeriesItemNode) private FSeries: IIdentifierNode; FValue: IAstNode; FLookback: IAstNode; function GetSeries: IIdentifierNode; function GetValue: IAstNode; function GetLookback: IAstNode; function GetKind: TAstNodeKind; override; public constructor Create( const ASeries: IIdentifierNode; const AValue: IAstNode; const ALookback: IAstNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity ); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsAddSeriesItem: IAddSeriesItemNode; override; property Series: IIdentifierNode read FSeries; property Value: IAstNode read FValue; property Lookback: IAstNode read FLookback; end; TSeriesLengthNode = class(TAstTypedNode, ISeriesLengthNode) private FSeries: IIdentifierNode; function GetSeries: IIdentifierNode; 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; property Series: IIdentifierNode read FSeries; end; TRecordLiteralNode = class(TAstTypedNode, IRecordLiteralNode) private FFields: TArray; FScalarDefinition: IScalarRecordDefinition; FGenericDefinition: IGenericRecordDefinition; function GetFields: TArray; function GetGenericDefinition: IGenericRecordDefinition; function GetKind: TAstNodeKind; override; function GetScalarDefinition: IScalarRecordDefinition; public constructor Create( const AFields: TArray; const AScalarDefinition: IScalarRecordDefinition; const AGenericDefinition: IGenericRecordDefinition; const AStaticType: IStaticType; const AIdentity: IAstIdentity ); function Accept(const Visitor: IAstVisitor): TDataValue; override; function AsRecordLiteral: IRecordLiteralNode; override; property Fields: TArray read FFields; property ScalarDefinition: IScalarRecordDefinition read GetScalarDefinition; property GenericDefinition: IGenericRecordDefinition read GetGenericDefinition; end; TNopNode = class(TAstTypedNode, INopNode) private 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; { TAst } class function TAst.CreateScope( Parent: IExecutionScope; const Descriptor: IScopeDescriptor = nil; ARegisterLibraries: Boolean = False ): IExecutionScope; begin if Assigned(Descriptor) then Result := Descriptor.CreateScope(Parent) else Result := TScope.CreateScope(Parent, nil, nil); if ARegisterLibraries then begin for var libProc in FLibraries do libProc(Result); end; end; class function TAst.CreateSeries( const ADefinition: String; const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil ): ICreateSeriesNode; begin Result := TCreateSeriesNode.Create( ADefinition, if AStaticType <> nil then AStaticType else TTypes.Unknown, Identity ); end; class function TAst.AddSeriesItem( const ASeries: IIdentifierNode; const AValue: IAstNode; const ALookback: IAstNode = nil; const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil ): IAddSeriesItemNode; begin Result := TAddSeriesItemNode.Create( ASeries, AValue, ALookback, if AStaticType <> nil then AStaticType else TTypes.Void, Identity ); end; class function TAst.SeriesLength( const ASeries: IIdentifierNode; const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil ): ISeriesLengthNode; begin Result := TSeriesLengthNode.Create( ASeries, if AStaticType <> nil then AStaticType else TTypes.Ordinal, Identity ); end; class function TAst.Assign( const ATarget, AValue: IAstNode; const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil ): IAssignmentNode; begin Result := TAssignmentNode.Create( ATarget, AValue, if AStaticType <> nil then AStaticType else TTypes.Unknown, Identity ); end; class function TAst.AssignResult(const AValue: IAstNode; const Identity: IAstIdentity = nil): IAssignmentNode; begin Result := TAssignmentNode.Create(TAst.Identifier('Result', nil, Identity), AValue, TTypes.Unknown, Identity); end; class function TAst.Block( const AExpressions: array of IAstNode; const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil ): IBlockExpressionNode; begin Result := TBlockExpressionNode.Create( AExpressions, if AStaticType <> nil then AStaticType else TTypes.Unknown, Identity ); end; class function TAst.Constant( const AValue: TDataValue; const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil ): IConstantNode; begin var constType := AStaticType; if constType = nil then begin case AValue.Kind of TDataValueKind.vkScalar: constType := TTypes.FromScalarKind(AValue.AsScalar.Kind); TDataValueKind.vkText: constType := TTypes.Text; TDataValueKind.vkVoid: constType := TTypes.Void; else constType := TTypes.Unknown; end; end; Result := TConstantNode.Create(AValue, constType, Identity); end; class function TAst.Constant(const AValue: String; const Identity: IAstIdentity = nil): IConstantNode; begin Result := TConstantNode.Create(AValue, TTypes.Text, Identity); end; class constructor TAst.Create; begin FLibraries := TList.Create; end; class destructor TAst.Destroy; begin FLibraries.Free; end; class procedure TAst.RegisterLibrary(const AProc: TRegisterLibraryProc); begin FLibraries.Add(AProc); end; class function TAst.FunctionCall( const ACallee: IAstNode; const AArguments: TArray; const AStaticType: IStaticType = nil; const AIsTailCall: Boolean = False; const AStaticTarget: TDataValue.TFunc = nil; const AIsTargetPure: Boolean = False; const Identity: IAstIdentity = nil ): IFunctionCallNode; begin Result := TFunctionCallNode.Create( ACallee, AArguments, if AStaticType <> nil then AStaticType else TTypes.Unknown, AIsTailCall, AStaticTarget, AIsTargetPure, Identity ); end; class function TAst.Identifier(AName: string; const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil): IIdentifierNode; begin Result := TIdentifierNode.Create( AName, Default(TResolvedAddress), if AStaticType <> nil then AStaticType else TTypes.Unknown, Identity ); end; class function TAst.Identifier( AName: string; const Address: TResolvedAddress; const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil ): IIdentifierNode; begin Result := TIdentifierNode.Create( AName, Address, if AStaticType <> nil then AStaticType else TTypes.Unknown, Identity ); end; class function TAst.IfExpr( const ACondition: IAstNode; const AThenBranch, AElseBranch: IAstNode; const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil ): IIfExpressionNode; begin Result := TIfExpressionNode.Create( ACondition, AThenBranch, AElseBranch, if AStaticType <> nil then AStaticType else TTypes.Unknown, Identity ); end; class function TAst.Indexer( const ABase: IAstNode; const AIndex: IAstNode; const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil ): IIndexerNode; begin Result := TIndexerNode.Create( ABase, AIndex, if AStaticType <> nil then AStaticType else TTypes.Unknown, Identity ); end; class function TAst.Keyword(const AName: string; const Identity: IAstIdentity = nil): IKeywordNode; begin Result := TKeywordNode.Create(TKeywordRegistry.Intern(AName), Identity); end; class function TAst.LambdaExpr( const AParameters: TArray; const ABody: IAstNode; const ALayout: IScopeLayout = nil; const ADescriptor: IScopeDescriptor = nil; const AUpvalues: TArray = nil; const AHasNestedLambdas: Boolean = False; const AIsPure: Boolean = False; const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil ): ILambdaExpressionNode; begin Result := TLambdaExpressionNode.Create( AParameters, ABody, if AStaticType <> nil then AStaticType else TTypes.Unknown, ALayout, ADescriptor, AUpvalues, AHasNestedLambdas, AIsPure, Identity ); end; class function TAst.MacroDef( const AName: IIdentifierNode; const AParameters: TArray; const ABody: IAstNode; const Identity: IAstIdentity = nil ): IMacroDefinitionNode; begin Result := TMacroDefinitionNode.Create(AName, AParameters, ABody, Identity); end; class function TAst.MacroExpansionNode( const AOriginalCallNode: IFunctionCallNode; const AExpandedBody: IAstNode; const Identity: IAstIdentity = nil ): IMacroExpansionNode; begin Result := TMacroExpansionNode.Create(AOriginalCallNode, AExpandedBody, Identity); end; class function TAst.MemberAccess( const ABase: IAstNode; const AMember: IKeywordNode; const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil ): IMemberAccessNode; begin Result := TMemberAccessNode.Create( ABase, AMember, if AStaticType <> nil then AStaticType else TTypes.Unknown, Identity ); end; class function TAst.Nop(const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil): IAstNode; begin Result := TNopNode.Create(TTypes.Unknown, Identity); end; class function TAst.Quasiquote(const AExpression: IAstNode; const Identity: IAstIdentity = nil): IQuasiquoteNode; begin Result := TQuasiquoteNode.Create(AExpression, Identity); end; class function TAst.Recur( const AArguments: array of IAstNode; const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil ): IRecurNode; var args: TArray; i: Integer; begin SetLength(args, Length(AArguments)); for i := 0 to High(AArguments) do args[i] := AArguments[i]; Result := TRecurNode.Create( args, if AStaticType <> nil then AStaticType else TTypes.Void, Identity ); end; class function TAst.RecordLiteral( const AFields: TArray; const AScalarDefinition: IScalarRecordDefinition = nil; const AGenericDefinition: IGenericRecordDefinition = nil; const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil ): IRecordLiteralNode; begin Result := TRecordLiteralNode.Create( AFields, AScalarDefinition, AGenericDefinition, if AStaticType <> nil then AStaticType else TTypes.Unknown, Identity ); end; class function TAst.TernaryExpr( const ACondition: IAstNode; const AThenBranch, AElseBranch: IAstNode; const AStaticType: IStaticType = nil; const Identity: IAstIdentity = nil ): ITernaryExpressionNode; begin Result := TTernaryExpressionNode.Create( ACondition, AThenBranch, AElseBranch, if AStaticType <> nil then AStaticType else TTypes.Unknown, Identity ); end; class function TAst.Unquote(const AExpression: IAstNode; const Identity: IAstIdentity = nil): IUnquoteNode; begin Result := TUnquoteNode.Create(AExpression, Identity); end; class function TAst.UnquoteSplicing(const AExpression: IQuasiquoteNode; const Identity: IAstIdentity = nil): IUnquoteSplicingNode; begin Result := TUnquoteSplicingNode.Create(AExpression, Identity); end; class function TAst.VarDecl( const AIdentifier: IAstNode; AInitializer: IAstNode = nil; const AStaticType: IStaticType = nil; const AIsBoxed: Boolean = False; const Identity: IAstIdentity = nil ): IVariableDeclarationNode; begin Result := TVariableDeclarationNode.Create( AIdentifier, AInitializer, if AStaticType <> nil then AStaticType else TTypes.Unknown, AIsBoxed, Identity ); 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; { TAstNode } constructor TAstNode.Create(const AIdentity: IAstIdentity); begin inherited Create; FIdentity := AIdentity; end; function TAstNode.GetIdentity: IAstIdentity; begin Result := FIdentity; end; function TAstNode.AsAddSeriesItem: IAddSeriesItemNode; begin Assert(False, 'Node is not an AddSeriesItem'); Result := nil; end; function TAstNode.AsAssignment: IAssignmentNode; begin Assert(False, 'Node is not an Assignment'); Result := nil; end; function TAstNode.AsBlockExpression: IBlockExpressionNode; begin Assert(False, 'Node is not a BlockExpression'); Result := nil; end; function TAstNode.AsConstant: IConstantNode; begin Assert(False, 'Node is not a Constant'); Result := nil; end; function TAstNode.AsCreateSeries: ICreateSeriesNode; begin Assert(False, 'Node is not a CreateSeries'); Result := nil; end; function TAstNode.AsFunctionCall: IFunctionCallNode; begin Assert(False, 'Node is not a FunctionCall'); Result := nil; end; function TAstNode.AsIdentifier: IIdentifierNode; begin Assert(False, 'Node is not an Identifier'); Result := nil; end; function TAstNode.AsIfExpression: IIfExpressionNode; begin Assert(False, 'Node is not an IfExpression'); Result := nil; end; function TAstNode.AsIndexer: IIndexerNode; begin Assert(False, 'Node is not an Indexer'); Result := nil; end; function TAstNode.AsKeyword: IKeywordNode; begin Assert(False, 'Node is not a Keyword'); Result := nil; end; function TAstNode.AsLambdaExpression: ILambdaExpressionNode; begin Assert(False, 'Node is not a LambdaExpression'); Result := nil; end; function TAstNode.AsMacroDefinition: IMacroDefinitionNode; begin Assert(False, 'Node is not a MacroDefinition'); Result := nil; end; function TAstNode.AsMacroExpansion: IMacroExpansionNode; begin Assert(False, 'Node is not a MacroExpansion'); Result := nil; end; function TAstNode.AsMemberAccess: IMemberAccessNode; begin Assert(False, 'Node is not a MemberAccess'); Result := nil; end; function TAstNode.AsNop: INopNode; begin Assert(False, 'Node is not a Nop'); Result := nil; end; function TAstNode.AsQuasiquote: IQuasiquoteNode; begin Assert(False, 'Node is not a Quasiquote'); Result := nil; end; function TAstNode.AsRecordLiteral: IRecordLiteralNode; begin Assert(False, 'Node is not a RecordLiteral'); Result := nil; end; function TAstNode.AsRecur: IRecurNode; begin Assert(False, 'Node is not a Recur'); Result := nil; end; function TAstNode.AsSeriesLength: ISeriesLengthNode; begin Assert(False, 'Node is not a SeriesLength'); Result := nil; end; function TAstNode.AsTernaryExpression: ITernaryExpressionNode; begin Assert(False, 'Node is not a TernaryExpression'); Result := nil; end; function TAstNode.AsTypedNode: IAstTypedNode; begin Assert(False, 'Node has no type'); Result := nil; end; function TAstNode.AsUnquote: IUnquoteNode; begin Assert(False, 'Node is not an Unquote'); Result := nil; end; function TAstNode.AsUnquoteSplicing: IUnquoteSplicingNode; begin Assert(False, 'Node is not an UnquoteSplicing'); Result := nil; end; function TAstNode.AsVariableDeclaration: IVariableDeclarationNode; begin Assert(False, 'Node is not a VariableDeclaration'); Result := nil; end; function TAstNode.GetIsTyped: Boolean; begin Result := false; end; { TAstTypedNode } constructor TAstTypedNode.Create(const AStaticType: IStaticType; const AIdentity: IAstIdentity); begin inherited Create(AIdentity); FStaticType := AStaticType; Assert(FStaticType <> nil); end; function TAstTypedNode.AsTypedNode: IAstTypedNode; begin Result := Self; end; function TAstTypedNode.GetIsTyped: Boolean; begin Result := true; end; function TAstTypedNode.GetStaticType: IStaticType; begin Result := FStaticType; end; { TConstantNode } constructor TConstantNode.Create(const AValue: TDataValue; const AStaticType: IStaticType; const AIdentity: IAstIdentity); begin inherited Create(AStaticType, AIdentity); FValue := AValue; end; function TConstantNode.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitConstant(Self); end; function TConstantNode.AsConstant: IConstantNode; begin Result := Self; end; function TConstantNode.GetValue: TDataValue; begin Result := FValue; end; function TConstantNode.GetKind: TAstNodeKind; begin Result := akConstant; end; { TIdentifierNode } constructor TIdentifierNode.Create( const AName: string; const AAddress: TResolvedAddress; const AStaticType: IStaticType; const AIdentity: IAstIdentity ); begin inherited Create(AStaticType, AIdentity); FName := AName; 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.GetName: string; begin Result := FName; end; function TIdentifierNode.GetKind: TAstNodeKind; begin Result := akIdentifier; end; { TKeywordNode } constructor TKeywordNode.Create(const AValue: IKeyword; const AIdentity: IAstIdentity); begin inherited Create(TTypes.Keyword, AIdentity); FValue := AValue; end; function TKeywordNode.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitKeyword(Self); end; function TKeywordNode.AsKeyword: IKeywordNode; begin Result := Self; end; function TKeywordNode.GetValue: IKeyword; begin Result := FValue; end; function TKeywordNode.GetKind: TAstNodeKind; begin Result := akKeyword; 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.GetElseBranch: IAstNode; begin Result := FElseBranch; end; function TIfExpressionNode.GetThenBranch: IAstNode; begin Result := FThenBranch; end; function TIfExpressionNode.GetKind: TAstNodeKind; begin Result := akIfExpression; end; { TTernaryExpressionNode } constructor TTernaryExpressionNode.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 TTernaryExpressionNode.Accept(const Visitor: IAstVisitor): TDataValue; begin Result := Visitor.VisitTernaryExpression(Self); end; function TTernaryExpressionNode.AsTernaryExpression: ITernaryExpressionNode; begin Result := Self; end; function TTernaryExpressionNode.GetCondition: IAstNode; begin Result := FCondition; end; function TTernaryExpressionNode.GetElseBranch: IAstNode; begin Result := FElseBranch; end; function TTernaryExpressionNode.GetThenBranch: IAstNode; begin Result := FThenBranch; end; function TTernaryExpressionNode.GetKind: TAstNodeKind; begin Result := akTernaryExpression; end; { TLambdaExpressionNode } constructor TLambdaExpressionNode.Create( const AParameters: TArray; const ABody: IAstNode; const AStaticType: IStaticType; const ALayout: IScopeLayout; const ADescriptor: IScopeDescriptor; const AUpvalues: TArray; const AHasNestedLambdas: Boolean; const AIsPure: Boolean; const AIdentity: IAstIdentity ); begin inherited Create(AStaticType, AIdentity); FParameters := AParameters; FBody := ABody; FLayout := ALayout; FDescriptor := ADescriptor; FUpvalues := AUpvalues; FHasNestedLambdas := AHasNestedLambdas; FIsPure := AIsPure; // Consistency Check if Assigned(FDescriptor) and (FDescriptor.Layout <> FLayout) then raise Exception.Create('Consistency Error: Lambda Descriptor does not match Layout.'); end; destructor TLambdaExpressionNode.Destroy; begin inherited; 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: TArray; 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; { TMacroDefinitionNode } constructor TMacroDefinitionNode.Create( const AName: IIdentifierNode; const AParameters: TArray; 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.GetBody: IAstNode; begin Result := FBody; end; function TMacroDefinitionNode.GetName: IIdentifierNode; begin Result := FName; end; function TMacroDefinitionNode.GetParameters: TArray; begin Result := FParameters; end; function TMacroDefinitionNode.GetKind: TAstNodeKind; begin Result := akMacroDefinition; 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; { TFunctionCallNode } constructor TFunctionCallNode.Create( const ACallee: IAstNode; const AArguments: TArray; 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.GetArguments: TArray; begin Result := FArguments; end; function TFunctionCallNode.GetCallee: IAstNode; begin Result := FCallee; end; function TFunctionCallNode.GetIsTailCall: Boolean; begin Result := FIsTailCall; end; function TFunctionCallNode.GetKind: TAstNodeKind; begin Result := akFunctionCall; end; function TFunctionCallNode.GetStaticTarget: TDataValue.TFunc; begin Result := FStaticTarget; end; function TFunctionCallNode.GetIsTargetPure: Boolean; begin Result := FIsTargetPure; 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); FExpandedBody := AExpandedBody; FCallNode := ACallNode; 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; { TRecurNode } constructor TRecurNode.Create(const AArguments: TArray; 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: TArray; begin Result := FArguments; end; function TRecurNode.GetKind: TAstNodeKind; begin Result := akRecur; end; { TBlockExpressionNode } constructor TBlockExpressionNode.Create( const AExpressions: array of IAstNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity ); var i: Integer; begin inherited Create(AStaticType, AIdentity); SetLength(FExpressions, Length(AExpressions)); for i := 0 to High(AExpressions) do FExpressions[i] := AExpressions[i]; 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: TArray; 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: IAstNode; const 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: IAstNode; const 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: TArray; const AScalarDefinition: IScalarRecordDefinition; const AGenericDefinition: IGenericRecordDefinition; const AStaticType: IStaticType; const AIdentity: IAstIdentity ); begin inherited Create(AStaticType, AIdentity); FFields := AFields; FGenericDefinition := AGenericDefinition; FScalarDefinition := AScalarDefinition; 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: TArray; begin Result := FFields; end; function TRecordLiteralNode.GetGenericDefinition: IGenericRecordDefinition; begin Result := FGenericDefinition; end; function TRecordLiteralNode.GetKind: TAstNodeKind; begin Result := akRecordLiteral; end; function TRecordLiteralNode.GetScalarDefinition: IScalarRecordDefinition; begin Result := FScalarDefinition; end; { TCreateSeriesNode } constructor TCreateSeriesNode.Create(const ADefinition: String; const AStaticType: IStaticType; const AIdentity: IAstIdentity); begin inherited Create(AStaticType, AIdentity); FDefinition := ADefinition; 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 := FDefinition; end; function TCreateSeriesNode.GetKind: TAstNodeKind; begin Result := akCreateSeries; end; { TAddSeriesItemNode } constructor TAddSeriesItemNode.Create( const ASeries: IIdentifierNode; const AValue: IAstNode; const 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.GetLookback: IAstNode; begin Result := FLookback; end; function TAddSeriesItemNode.GetSeries: IIdentifierNode; begin Result := FSeries; end; function TAddSeriesItemNode.GetValue: IAstNode; begin Result := FValue; 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; end.