2353 lines
64 KiB
ObjectPascal
2353 lines
64 KiB
ObjectPascal
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<TCompilerError>;
|
|
|
|
property Entries: TArray<TCompilerError> read GetEntries;
|
|
end;
|
|
|
|
TCompilerLog = class(TInterfacedObject, ICompilerLog)
|
|
private
|
|
FEntries: TList<TCompilerError>;
|
|
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<TCompilerError>;
|
|
end;
|
|
|
|
EAstException = class(Exception);
|
|
|
|
ECompilationFailed = class(EAstException)
|
|
private
|
|
FErrors: TArray<TCompilerError>;
|
|
public
|
|
constructor Create(const AErrors: TArray<TCompilerError>);
|
|
function ToString: string; override;
|
|
property Errors: TArray<TCompilerError> read FErrors;
|
|
end;
|
|
|
|
// Exception for the new visitor registry dispatch
|
|
ENoHandlerException = class(EAstException)
|
|
public
|
|
constructor Create(const KindName: string);
|
|
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<T: IAstNode> = interface(IAstNode)
|
|
{$region 'private'}
|
|
function GetCount: Integer;
|
|
function GetItem(Index: Integer): T;
|
|
{$endregion}
|
|
function GetEnumerator: TEnumerator<T>;
|
|
function ToArray: TArray<T>;
|
|
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<IRecordFieldNode>)
|
|
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<TCondPair>;
|
|
function GetElseBranch: IAstNode;
|
|
{$endregion}
|
|
property Pairs: TArray<TCondPair> read GetPairs;
|
|
property ElseBranch: IAstNode read GetElseBranch;
|
|
end;
|
|
|
|
ILambdaExpressionNode = interface(IFunctionDefinition)
|
|
{$region 'private'}
|
|
function GetLayout: IScopeLayout;
|
|
function GetDescriptor: IScopeDescriptor;
|
|
function GetUpvalues: TArray<TResolvedAddress>;
|
|
function GetHasNestedLambdas: Boolean;
|
|
{$endregion}
|
|
property Layout: IScopeLayout read GetLayout;
|
|
property Descriptor: IScopeDescriptor read GetDescriptor;
|
|
property Upvalues: TArray<TResolvedAddress> 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<IKeywordNode>)
|
|
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<IPipeInputNode>)
|
|
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<IIdentifierNode>)
|
|
end;
|
|
|
|
IArgumentList = interface(INodeList<IAstNode>)
|
|
end;
|
|
|
|
IExpressionList = interface(INodeList<IAstNode>)
|
|
end;
|
|
|
|
IAstVisitor = interface
|
|
// --- Central Dispatch Method (New) ---
|
|
function Visit(const Node: IAstNode): 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;
|
|
|
|
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<T: IAstNode> = class(TAstNode, INodeList<T>)
|
|
type
|
|
TEnumerator = class(TEnumerator<T>)
|
|
private
|
|
FArray: TArray<T>;
|
|
FIndex: NativeInt;
|
|
function GetCurrent: T; inline;
|
|
protected
|
|
function DoGetCurrent: T; override;
|
|
function DoMoveNext: Boolean; override;
|
|
public
|
|
constructor Create(const AArray: TArray<T>);
|
|
function MoveNext: Boolean; inline;
|
|
property Current: T read GetCurrent;
|
|
end;
|
|
private
|
|
FItems: TArray<T>;
|
|
function GetCount: Integer;
|
|
function GetItem(Index: Integer): T;
|
|
public
|
|
constructor Create(const AItems: TArray<T>; const AIdentity: IAstIdentity);
|
|
function GetEnumerator: TEnumerator<T>;
|
|
function ToArray: TArray<T>;
|
|
property Count: Integer read GetCount;
|
|
property Items[Index: Integer]: T read GetItem; default;
|
|
end;
|
|
|
|
TParameterList = class(TAstNodeList<IIdentifierNode>, IParameterList)
|
|
protected
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
function AsParameterList: IParameterList; override;
|
|
end;
|
|
|
|
TArgumentList = class(TAstNodeList<IAstNode>, IArgumentList)
|
|
protected
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
function AsArgumentList: IArgumentList; override;
|
|
end;
|
|
|
|
TExpressionList = class(TAstNodeList<IAstNode>, IExpressionList)
|
|
protected
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
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 AsRecordField: IRecordFieldNode; override;
|
|
end;
|
|
|
|
TRecordFieldList = class(TAstNodeList<IRecordFieldNode>, IRecordFieldList)
|
|
protected
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
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 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 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 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 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 AsIfExpression: IIfExpressionNode; override;
|
|
end;
|
|
|
|
TCondExpressionNode = class(TAstTypedNode, ICondExpressionNode)
|
|
private
|
|
FPairs: TArray<TCondPair>;
|
|
FElseBranch: IAstNode;
|
|
function GetPairs: TArray<TCondPair>;
|
|
function GetElseBranch: IAstNode;
|
|
protected
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(
|
|
const APairs: TArray<TCondPair>;
|
|
const AElseBranch: IAstNode;
|
|
const AStaticType: IStaticType;
|
|
const AIdentity: IAstIdentity
|
|
);
|
|
function AsCondExpression: ICondExpressionNode; override;
|
|
end;
|
|
|
|
TLambdaExpressionNode = class(TAstTypedNode, ILambdaExpressionNode, IFunctionDefinition)
|
|
private
|
|
FParameters: IParameterList;
|
|
FBody: IAstNode;
|
|
FLayout: IScopeLayout;
|
|
FDescriptor: IScopeDescriptor;
|
|
FUpvalues: TArray<TResolvedAddress>;
|
|
FHasNestedLambdas, FIsPure: Boolean;
|
|
function GetParameters: IParameterList;
|
|
function GetBody: IAstNode;
|
|
function GetLayout: IScopeLayout;
|
|
function GetDescriptor: IScopeDescriptor;
|
|
function GetUpvalues: TArray<TResolvedAddress>;
|
|
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<TResolvedAddress>;
|
|
const AHasNestedLambdas, AIsPure: Boolean;
|
|
const AIdentity: IAstIdentity
|
|
);
|
|
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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 AsSeriesLength: ISeriesLengthNode; override;
|
|
end;
|
|
|
|
TNopNode = class(TAstTypedNode, INopNode)
|
|
protected
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AStaticType: IStaticType; const AIdentity: IAstIdentity);
|
|
function AsNop: INopNode; override;
|
|
end;
|
|
|
|
TPipeSelectorList = class(TAstNodeList<IKeywordNode>, IPipeSelectorList)
|
|
protected
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
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 AsPipeInput: IPipeInputNode; override;
|
|
end;
|
|
|
|
TPipeInputList = class(TAstNodeList<IPipeInputNode>, IPipeInputList)
|
|
protected
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
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 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<TAstNodeKind>(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<TCompilerError>.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<TCompilerError>;
|
|
begin
|
|
Result := FEntries.ToArray;
|
|
end;
|
|
|
|
{ ECompilationFailed }
|
|
|
|
constructor ECompilationFailed.Create(const AErrors: TArray<TCompilerError>);
|
|
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;
|
|
|
|
{ ENoHandlerException }
|
|
|
|
constructor ENoHandlerException.Create(const KindName: string);
|
|
begin
|
|
inherited CreateFmt('No visitor handler registered for AST node kind: %s', [KindName]);
|
|
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;
|
|
|
|
function TAstNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
// Central Dispatch: Delegate to the generic Visit method of the visitor.
|
|
// The visitor uses Node.Kind to look up the correct handler.
|
|
Result := Visitor.Visit(Self);
|
|
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<T> }
|
|
|
|
constructor TAstNodeList<T>.Create(const AItems: TArray<T>; const AIdentity: IAstIdentity);
|
|
begin
|
|
inherited Create(AIdentity);
|
|
FItems := AItems;
|
|
end;
|
|
|
|
function TAstNodeList<T>.GetCount: Integer;
|
|
begin
|
|
Result := Length(FItems);
|
|
end;
|
|
|
|
function TAstNodeList<T>.GetEnumerator: TEnumerator<T>;
|
|
begin
|
|
Result := TEnumerator.Create(FItems);
|
|
end;
|
|
|
|
function TAstNodeList<T>.GetItem(Index: Integer): T;
|
|
begin
|
|
Result := FItems[Index];
|
|
end;
|
|
|
|
function TAstNodeList<T>.ToArray: TArray<T>;
|
|
begin
|
|
Result := FItems;
|
|
end;
|
|
|
|
{ TParameterList }
|
|
|
|
function TParameterList.AsParameterList: IParameterList;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TParameterList.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akParameterList;
|
|
end;
|
|
|
|
{ TArgumentList }
|
|
|
|
function TArgumentList.AsArgumentList: IArgumentList;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TArgumentList.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akArgumentList;
|
|
end;
|
|
|
|
{ TExpressionList }
|
|
|
|
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.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.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.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.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.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.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.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<TCondPair>;
|
|
const AElseBranch: IAstNode;
|
|
const AStaticType: IStaticType;
|
|
const AIdentity: IAstIdentity
|
|
);
|
|
begin
|
|
inherited Create(AStaticType, AIdentity);
|
|
FPairs := APairs;
|
|
FElseBranch := AElseBranch;
|
|
end;
|
|
|
|
function TCondExpressionNode.AsCondExpression: ICondExpressionNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TCondExpressionNode.GetPairs: TArray<TCondPair>;
|
|
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<TResolvedAddress>;
|
|
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.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<TResolvedAddress>;
|
|
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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.AsNop: INopNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TNopNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akNop;
|
|
end;
|
|
|
|
constructor TAstNodeList<T>.TEnumerator.Create(const AArray: TArray<T>);
|
|
begin
|
|
inherited Create;
|
|
FArray := AArray;
|
|
FIndex := -1;
|
|
end;
|
|
|
|
function TAstNodeList<T>.TEnumerator.DoGetCurrent: T;
|
|
begin
|
|
Result := Current;
|
|
end;
|
|
|
|
function TAstNodeList<T>.TEnumerator.DoMoveNext: Boolean;
|
|
begin
|
|
Result := MoveNext;
|
|
end;
|
|
|
|
function TAstNodeList<T>.TEnumerator.GetCurrent: T;
|
|
begin
|
|
Result := FArray[FIndex];
|
|
end;
|
|
|
|
function TAstNodeList<T>.TEnumerator.MoveNext: Boolean;
|
|
begin
|
|
Result := FIndex < High(FArray);
|
|
if Result then
|
|
Inc(FIndex);
|
|
end;
|
|
|
|
{ TPipeSelectorList }
|
|
|
|
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.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.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.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.
|