Files
MycLib/Src/AST/Myc.Ast.Nodes.pas
T
2025-12-07 12:06:29 +01:00

2264 lines
66 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;
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;
// 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
);
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;
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;
IParameterList = interface(INodeList<IIdentifierNode>)
end;
IArgumentList = interface(INodeList<IAstNode>)
end;
IExpressionList = interface(INodeList<IAstNode>)
end;
IAstVisitor = interface
function VisitConstant(const Node: IConstantNode): TDataValue;
function VisitIdentifier(const Node: IIdentifierNode): TDataValue;
function VisitKeyword(const Node: IKeywordNode): TDataValue;
// List Visits
function VisitParameterList(const Node: IParameterList): TDataValue;
function VisitArgumentList(const Node: IArgumentList): TDataValue;
function VisitExpressionList(const Node: IExpressionList): TDataValue;
function VisitRecordFieldList(const Node: IRecordFieldList): TDataValue;
function VisitRecordField(const Node: IRecordFieldNode): TDataValue;
function VisitIfExpression(const Node: IIfExpressionNode): TDataValue;
function VisitCondExpression(const Node: ICondExpressionNode): TDataValue;
function VisitLambdaExpression(const Node: ILambdaExpressionNode): TDataValue;
function VisitFunctionCall(const Node: IFunctionCallNode): TDataValue;
function VisitMacroExpansionNode(const Node: IMacroExpansionNode): TDataValue;
function VisitBlockExpression(const Node: IBlockExpressionNode): TDataValue;
function VisitVariableDeclaration(const Node: IVariableDeclarationNode): TDataValue;
function VisitAssignment(const Node: IAssignmentNode): TDataValue;
function VisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue;
function VisitQuasiquote(const Node: IQuasiquoteNode): TDataValue;
function VisitUnquote(const Node: IUnquoteNode): TDataValue;
function VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): TDataValue;
function VisitIndexer(const Node: IIndexerNode): TDataValue;
function VisitMemberAccess(const Node: IMemberAccessNode): TDataValue;
function VisitRecordLiteral(const Node: IRecordLiteralNode): TDataValue;
function VisitCreateSeries(const Node: ICreateSeriesNode): TDataValue;
function VisitAddSeriesItem(const Node: IAddSeriesItemNode): TDataValue;
function VisitSeriesLength(const Node: ISeriesLengthNode): TDataValue;
function VisitRecurNode(const Node: IRecurNode): TDataValue;
function VisitNop(const Node: INopNode): TDataValue;
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 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;
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 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;
// --- 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 Accept(const Visitor: IAstVisitor): TDataValue; override;
function AsParameterList: IParameterList; override;
end;
TArgumentList = class(TAstNodeList<IAstNode>, IArgumentList)
protected
function GetKind: TAstNodeKind; override;
public
function Accept(const Visitor: IAstVisitor): TDataValue; override;
function AsArgumentList: IArgumentList; override;
end;
TExpressionList = class(TAstNodeList<IAstNode>, IExpressionList)
protected
function GetKind: TAstNodeKind; override;
public
function Accept(const Visitor: IAstVisitor): TDataValue; override;
function AsExpressionList: IExpressionList; override;
end;
TRecordFieldNode = class(TAstNode, IRecordFieldNode)
private
FKey: IKeywordNode;
FValue: IAstNode;
function GetKey: IKeywordNode;
function GetValue: IAstNode;
function GetKind: TAstNodeKind; override;
public
constructor Create(const AKey: IKeywordNode; const AValue: IAstNode; const AIdentity: IAstIdentity);
function Accept(const Visitor: IAstVisitor): TDataValue; override;
function AsRecordField: IRecordFieldNode; override;
end;
TRecordFieldList = class(TAstNodeList<IRecordFieldNode>, IRecordFieldList)
protected
function GetKind: TAstNodeKind; override;
public
function Accept(const Visitor: IAstVisitor): TDataValue; override;
function AsRecordFieldList: IRecordFieldList; override;
end;
// --- Core Nodes Implementations ---
TConstantNode = class(TAstTypedNode, IConstantNode)
private
FConstIdentity: IConstantIdentity; // Typed reference for fast access
function GetValue: TDataValue;
function GetKind: TAstNodeKind; override;
public
constructor Create(const AIdentity: IConstantIdentity; const AStaticType: IStaticType);
function Accept(const Visitor: IAstVisitor): TDataValue; override;
function AsConstant: IConstantNode; override;
end;
TIdentifierNode = class(TAstTypedNode, IIdentifierNode)
private
FNamedIdentity: INamedIdentity; // Typed reference for fast access
FAddress: TResolvedAddress;
function GetAddress: TResolvedAddress;
function GetName: string;
function GetKind: TAstNodeKind; override;
public
constructor Create(const AIdentity: INamedIdentity; const AAddress: TResolvedAddress; const AStaticType: IStaticType);
function Accept(const Visitor: IAstVisitor): TDataValue; override;
function AsIdentifier: IIdentifierNode; override;
end;
TKeywordNode = class(TAstTypedNode, IKeywordNode)
private
FKeywordIdentity: IKeywordIdentity;
function GetValue: IKeyword;
function GetKind: TAstNodeKind; override;
public
constructor Create(const AIdentity: IKeywordIdentity);
function Accept(const Visitor: IAstVisitor): TDataValue; override;
function AsKeyword: IKeywordNode; override;
end;
TCreateSeriesNode = class(TAstTypedNode, ICreateSeriesNode)
private
FDefIdentity: IDefinitionIdentity;
function GetDefinition: String;
function GetKind: TAstNodeKind; override;
public
constructor Create(const AIdentity: IDefinitionIdentity; const AStaticType: IStaticType);
function Accept(const Visitor: IAstVisitor): TDataValue; override;
function AsCreateSeries: ICreateSeriesNode; override;
end;
// --- Structural Nodes (Identity only for location) ---
TIfExpressionNode = class(TAstTypedNode, IIfExpressionNode)
private
FCondition, FThenBranch, FElseBranch: IAstNode;
function GetCondition: IAstNode;
function GetThenBranch: IAstNode;
function GetElseBranch: IAstNode;
function GetKind: TAstNodeKind; override;
public
constructor Create(
const ACondition, AThenBranch, AElseBranch: IAstNode;
const AStaticType: IStaticType;
const AIdentity: IAstIdentity
);
function Accept(const Visitor: IAstVisitor): TDataValue; override;
function AsIfExpression: IIfExpressionNode; override;
end;
TCondExpressionNode = class(TAstTypedNode, ICondExpressionNode)
private
FPairs: TArray<TCondPair>;
FElseBranch: IAstNode;
function GetPairs: TArray<TCondPair>;
function GetElseBranch: IAstNode;
function GetKind: TAstNodeKind; override;
public
constructor Create(
const APairs: TArray<TCondPair>;
const AElseBranch: IAstNode;
const AStaticType: IStaticType;
const AIdentity: IAstIdentity
);
function Accept(const Visitor: IAstVisitor): TDataValue; override;
function AsCondExpression: ICondExpressionNode; override;
end;
TLambdaExpressionNode = class(TAstTypedNode, ILambdaExpressionNode, IFunctionDefinition)
private
FParameters: IParameterList;
FBody: IAstNode;
FLayout: IScopeLayout;
FDescriptor: IScopeDescriptor;
FUpvalues: TArray<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;
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 Accept(const Visitor: IAstVisitor): TDataValue; override;
function AsLambdaExpression: ILambdaExpressionNode; override;
end;
TFunctionCallNode = class(TAstTypedNode, IFunctionCallNode)
private
FCallee: IAstNode;
FArguments: IArgumentList;
FIsTailCall: Boolean;
FStaticTarget: TDataValue.TFunc;
FIsTargetPure: Boolean;
function GetCallee: IAstNode;
function GetArguments: IArgumentList;
function GetIsTailCall: Boolean;
function GetStaticTarget: TDataValue.TFunc;
function GetIsTargetPure: Boolean;
function GetKind: TAstNodeKind; override;
public
constructor Create(
const ACallee: IAstNode;
const AArguments: IArgumentList;
const AStaticType: IStaticType;
const AIsTailCall: Boolean;
const AStaticTarget: TDataValue.TFunc;
const AIsTargetPure: Boolean;
const AIdentity: IAstIdentity
);
function Accept(const Visitor: IAstVisitor): TDataValue; override;
function AsFunctionCall: IFunctionCallNode; override;
end;
TMacroDefinitionNode = class(TAstTypedNode, IMacroDefinitionNode)
private
FName: IIdentifierNode;
FParameters: IParameterList;
FBody: IAstNode;
function GetName: IIdentifierNode;
function GetParameters: IParameterList;
function GetBody: IAstNode;
function GetKind: TAstNodeKind; override;
public
constructor Create(
const AName: IIdentifierNode;
const AParameters: IParameterList;
const ABody: IAstNode;
const AIdentity: IAstIdentity
);
function Accept(const Visitor: IAstVisitor): TDataValue; override;
function AsMacroDefinition: IMacroDefinitionNode; override;
end;
TMacroExpansionNode = class(TAstTypedNode, IMacroExpansionNode)
private
FCallNode: IFunctionCallNode;
FExpandedBody: IAstNode;
function GetCallNode: IFunctionCallNode;
function GetExpandedBody: IAstNode;
function GetKind: TAstNodeKind; override;
public
constructor Create(const ACallNode: IFunctionCallNode; const AExpandedBody: IAstNode; const AIdentity: IAstIdentity);
function Accept(const Visitor: IAstVisitor): TDataValue; override;
function AsMacroExpansion: IMacroExpansionNode; override;
end;
TQuasiquoteNode = class(TAstNode, IQuasiquoteNode)
private
FExpression: IAstNode;
function GetExpression: IAstNode;
function GetKind: TAstNodeKind; override;
public
constructor Create(const AExpression: IAstNode; const AIdentity: IAstIdentity);
function Accept(const Visitor: IAstVisitor): TDataValue; override;
function AsQuasiquote: IQuasiquoteNode; override;
end;
TUnquoteNode = class(TAstNode, IUnquoteNode)
private
FExpression: IAstNode;
function GetExpression: IAstNode;
function GetKind: TAstNodeKind; override;
public
constructor Create(const AExpression: IAstNode; const AIdentity: IAstIdentity);
function Accept(const Visitor: IAstVisitor): TDataValue; override;
function AsUnquote: IUnquoteNode; override;
end;
TUnquoteSplicingNode = class(TAstNode, IUnquoteSplicingNode)
private
FExpression: IQuasiquoteNode;
function GetExpression: IQuasiquoteNode;
function GetKind: TAstNodeKind; override;
public
constructor Create(const AExpression: IQuasiquoteNode; const AIdentity: IAstIdentity);
function Accept(const Visitor: IAstVisitor): TDataValue; override;
function AsUnquoteSplicing: IUnquoteSplicingNode; override;
end;
TRecurNode = class(TAstTypedNode, IRecurNode)
private
FArguments: IArgumentList;
function GetArguments: IArgumentList;
function GetKind: TAstNodeKind; override;
public
constructor Create(const AArguments: IArgumentList; const AStaticType: IStaticType; const AIdentity: IAstIdentity);
function Accept(const Visitor: IAstVisitor): TDataValue; override;
function AsRecur: IRecurNode; override;
end;
TBlockExpressionNode = class(TAstTypedNode, IBlockExpressionNode)
private
FExpressions: IExpressionList;
function GetExpressions: IExpressionList;
function GetKind: TAstNodeKind; override;
public
constructor Create(const AExpressions: IExpressionList; const AStaticType: IStaticType; const AIdentity: IAstIdentity);
function Accept(const Visitor: IAstVisitor): TDataValue; override;
function AsBlockExpression: IBlockExpressionNode; override;
end;
TVariableDeclarationNode = class(TAstTypedNode, IVariableDeclarationNode)
private
FTarget, FInitializer: IAstNode;
FIsBoxed: Boolean;
function GetTarget: IAstNode;
function GetInitializer: IAstNode;
function GetIsBoxed: Boolean;
function GetKind: TAstNodeKind; override;
public
constructor Create(
const ATarget: IAstNode;
AInitializer: IAstNode;
const AStaticType: IStaticType;
const AIsBoxed: Boolean;
const AIdentity: IAstIdentity
);
function Accept(const Visitor: IAstVisitor): TDataValue; override;
function AsVariableDeclaration: IVariableDeclarationNode; override;
end;
TAssignmentNode = class(TAstTypedNode, IAssignmentNode)
private
FTarget, FValue: IAstNode;
function GetTarget: IAstNode;
function GetValue: IAstNode;
function GetKind: TAstNodeKind; override;
public
constructor Create(const ATarget, AValue: IAstNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity);
function Accept(const Visitor: IAstVisitor): TDataValue; override;
function AsAssignment: IAssignmentNode; override;
end;
TIndexerNode = class(TAstTypedNode, IIndexerNode)
private
FBase, FIndex: IAstNode;
function GetBase: IAstNode;
function GetIndex: IAstNode;
function GetKind: TAstNodeKind; override;
public
constructor Create(const ABase, AIndex: IAstNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity);
function Accept(const Visitor: IAstVisitor): TDataValue; override;
function AsIndexer: IIndexerNode; override;
end;
TMemberAccessNode = class(TAstTypedNode, IMemberAccessNode)
private
FBase: IAstNode;
FMember: IKeywordNode;
function GetBase: IAstNode;
function GetMember: IKeywordNode;
function GetKind: TAstNodeKind; override;
public
constructor Create(
const ABase: IAstNode;
const AMember: IKeywordNode;
const AStaticType: IStaticType;
const AIdentity: IAstIdentity
);
function Accept(const Visitor: IAstVisitor): TDataValue; override;
function AsMemberAccess: IMemberAccessNode; override;
end;
TRecordLiteralNode = class(TAstTypedNode, IRecordLiteralNode)
private
FFields: IRecordFieldList;
FScalarDef: IScalarRecordDefinition;
FGenericDef: IGenericRecordDefinition;
function GetFields: IRecordFieldList;
function GetGenericDefinition: IGenericRecordDefinition;
function GetScalarDefinition: IScalarRecordDefinition;
function GetKind: TAstNodeKind; override;
public
constructor Create(
const AFields: IRecordFieldList;
const AScalarDef: IScalarRecordDefinition;
const AGenericDef: IGenericRecordDefinition;
const AStaticType: IStaticType;
const AIdentity: IAstIdentity
);
function Accept(const Visitor: IAstVisitor): TDataValue; override;
function AsRecordLiteral: IRecordLiteralNode; override;
end;
TAddSeriesItemNode = class(TAstTypedNode, IAddSeriesItemNode)
private
FSeries: IIdentifierNode;
FValue, FLookback: IAstNode;
function GetSeries: IIdentifierNode;
function GetValue: IAstNode;
function GetLookback: IAstNode;
function GetKind: TAstNodeKind; override;
public
constructor Create(
const ASeries: IIdentifierNode;
const AValue, ALookback: IAstNode;
const AStaticType: IStaticType;
const AIdentity: IAstIdentity
);
function Accept(const Visitor: IAstVisitor): TDataValue; override;
function AsAddSeriesItem: IAddSeriesItemNode; override;
end;
TSeriesLengthNode = class(TAstTypedNode, ISeriesLengthNode)
private
FSeries: IIdentifierNode;
function GetSeries: IIdentifierNode;
function GetKind: TAstNodeKind; override;
public
constructor Create(const ASeries: IIdentifierNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity);
function Accept(const Visitor: IAstVisitor): TDataValue; override;
function AsSeriesLength: ISeriesLengthNode; override;
end;
TNopNode = class(TAstTypedNode, INopNode)
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;
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;
{ TAstNode }
constructor TAstNode.Create(const AIdentity: IAstIdentity);
begin
inherited Create;
FIdentity := AIdentity;
end;
function TAstNode.GetIdentity: IAstIdentity;
begin
Result := FIdentity;
end;
function TAstNode.GetIsTyped: Boolean;
begin
Result := False;
end;
// Default implementations for As... casting methods (Return nil)
function TAstNode.AsConstant: IConstantNode;
begin
Result := nil;
end;
function TAstNode.AsIdentifier: IIdentifierNode;
begin
Result := nil;
end;
function TAstNode.AsKeyword: IKeywordNode;
begin
Result := nil;
end;
function TAstNode.AsParameterList: IParameterList;
begin
Result := nil;
end;
function TAstNode.AsArgumentList: IArgumentList;
begin
Result := nil;
end;
function TAstNode.AsExpressionList: IExpressionList;
begin
Result := nil;
end;
function TAstNode.AsRecordFieldList: IRecordFieldList;
begin
Result := nil;
end;
function TAstNode.AsRecordField: IRecordFieldNode;
begin
Result := nil;
end;
function TAstNode.AsIfExpression: IIfExpressionNode;
begin
Result := nil;
end;
function TAstNode.AsCondExpression: ICondExpressionNode;
begin
Result := nil;
end;
function TAstNode.AsLambdaExpression: ILambdaExpressionNode;
begin
Result := nil;
end;
function TAstNode.AsFunctionCall: IFunctionCallNode;
begin
Result := nil;
end;
function TAstNode.AsMacroExpansion: IMacroExpansionNode;
begin
Result := nil;
end;
function TAstNode.AsBlockExpression: IBlockExpressionNode;
begin
Result := nil;
end;
function TAstNode.AsVariableDeclaration: IVariableDeclarationNode;
begin
Result := nil;
end;
function TAstNode.AsAssignment: IAssignmentNode;
begin
Result := nil;
end;
function TAstNode.AsMacroDefinition: IMacroDefinitionNode;
begin
Result := nil;
end;
function TAstNode.AsQuasiquote: IQuasiquoteNode;
begin
Result := nil;
end;
function TAstNode.AsUnquote: IUnquoteNode;
begin
Result := nil;
end;
function TAstNode.AsUnquoteSplicing: IUnquoteSplicingNode;
begin
Result := nil;
end;
function TAstNode.AsIndexer: IIndexerNode;
begin
Result := nil;
end;
function TAstNode.AsMemberAccess: IMemberAccessNode;
begin
Result := nil;
end;
function TAstNode.AsRecordLiteral: IRecordLiteralNode;
begin
Result := nil;
end;
function TAstNode.AsCreateSeries: ICreateSeriesNode;
begin
Result := nil;
end;
function TAstNode.AsAddSeriesItem: IAddSeriesItemNode;
begin
Result := nil;
end;
function TAstNode.AsSeriesLength: ISeriesLengthNode;
begin
Result := nil;
end;
function TAstNode.AsRecur: IRecurNode;
begin
Result := nil;
end;
function TAstNode.AsNop: INopNode;
begin
Result := nil;
end;
function TAstNode.AsTypedNode: IAstTypedNode;
begin
Result := nil;
end;
{ 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.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitParameterList(Self);
end;
function TParameterList.AsParameterList: IParameterList;
begin
Result := Self;
end;
function TParameterList.GetKind: TAstNodeKind;
begin
Result := akParameterList;
end;
{ TArgumentList }
function TArgumentList.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitArgumentList(Self);
end;
function TArgumentList.AsArgumentList: IArgumentList;
begin
Result := Self;
end;
function TArgumentList.GetKind: TAstNodeKind;
begin
Result := akArgumentList;
end;
{ TExpressionList }
function TExpressionList.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitExpressionList(Self);
end;
function TExpressionList.AsExpressionList: IExpressionList;
begin
Result := Self;
end;
function TExpressionList.GetKind: TAstNodeKind;
begin
Result := akExpressionList;
end;
{ TRecordFieldNode }
constructor TRecordFieldNode.Create(const AKey: IKeywordNode; const AValue: IAstNode; const AIdentity: IAstIdentity);
begin
inherited Create(AIdentity);
FKey := AKey;
FValue := AValue;
end;
function TRecordFieldNode.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitRecordField(Self);
end;
function TRecordFieldNode.AsRecordField: IRecordFieldNode;
begin
Result := Self;
end;
function TRecordFieldNode.GetKey: IKeywordNode;
begin
Result := FKey;
end;
function TRecordFieldNode.GetKind: TAstNodeKind;
begin
Result := akRecordField;
end;
function TRecordFieldNode.GetValue: IAstNode;
begin
Result := FValue;
end;
{ TRecordFieldList }
function TRecordFieldList.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitRecordFieldList(Self);
end;
function TRecordFieldList.AsRecordFieldList: IRecordFieldList;
begin
Result := Self;
end;
function TRecordFieldList.GetKind: TAstNodeKind;
begin
Result := akRecordFieldList;
end;
{ TConstantNode }
constructor TConstantNode.Create(const AIdentity: IConstantIdentity; const AStaticType: IStaticType);
begin
inherited Create(AStaticType, AIdentity);
FConstIdentity := AIdentity;
end;
function TConstantNode.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitConstant(Self);
end;
function TConstantNode.AsConstant: IConstantNode;
begin
Result := Self;
end;
function TConstantNode.GetKind: TAstNodeKind;
begin
Result := akConstant;
end;
function TConstantNode.GetValue: TDataValue;
begin
Result := FConstIdentity.Value;
end;
{ TIdentifierNode }
constructor TIdentifierNode.Create(const AIdentity: INamedIdentity; const AAddress: TResolvedAddress; const AStaticType: IStaticType);
begin
inherited Create(AStaticType, AIdentity);
FNamedIdentity := AIdentity;
FAddress := AAddress;
end;
function TIdentifierNode.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitIdentifier(Self);
end;
function TIdentifierNode.AsIdentifier: IIdentifierNode;
begin
Result := Self;
end;
function TIdentifierNode.GetAddress: TResolvedAddress;
begin
Result := FAddress;
end;
function TIdentifierNode.GetKind: TAstNodeKind;
begin
Result := akIdentifier;
end;
function TIdentifierNode.GetName: string;
begin
Result := FNamedIdentity.Name;
end;
{ TKeywordNode }
constructor TKeywordNode.Create(const AIdentity: IKeywordIdentity);
begin
inherited Create(TTypes.Keyword, AIdentity);
FKeywordIdentity := AIdentity;
end;
function TKeywordNode.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitKeyword(Self);
end;
function TKeywordNode.AsKeyword: IKeywordNode;
begin
Result := Self;
end;
function TKeywordNode.GetKind: TAstNodeKind;
begin
Result := akKeyword;
end;
function TKeywordNode.GetValue: IKeyword;
begin
Result := FKeywordIdentity.Value;
end;
{ TCreateSeriesNode }
constructor TCreateSeriesNode.Create(const AIdentity: IDefinitionIdentity; const AStaticType: IStaticType);
begin
inherited Create(AStaticType, AIdentity);
FDefIdentity := AIdentity;
end;
function TCreateSeriesNode.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitCreateSeries(Self);
end;
function TCreateSeriesNode.AsCreateSeries: ICreateSeriesNode;
begin
Result := Self;
end;
function TCreateSeriesNode.GetDefinition: String;
begin
Result := FDefIdentity.Definition;
end;
function TCreateSeriesNode.GetKind: TAstNodeKind;
begin
Result := akCreateSeries;
end;
{ TIfExpressionNode }
constructor TIfExpressionNode.Create(
const ACondition, AThenBranch, AElseBranch: IAstNode;
const AStaticType: IStaticType;
const AIdentity: IAstIdentity
);
begin
inherited Create(AStaticType, AIdentity);
FCondition := ACondition;
FThenBranch := AThenBranch;
FElseBranch := AElseBranch;
end;
function TIfExpressionNode.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitIfExpression(Self);
end;
function TIfExpressionNode.AsIfExpression: IIfExpressionNode;
begin
Result := Self;
end;
function TIfExpressionNode.GetCondition: IAstNode;
begin
Result := FCondition;
end;
function TIfExpressionNode.GetThenBranch: IAstNode;
begin
Result := FThenBranch;
end;
function TIfExpressionNode.GetElseBranch: IAstNode;
begin
Result := FElseBranch;
end;
function TIfExpressionNode.GetKind: TAstNodeKind;
begin
Result := akIfExpression;
end;
{ TCondExpressionNode }
constructor TCondExpressionNode.Create(
const APairs: TArray<TCondPair>;
const AElseBranch: IAstNode;
const AStaticType: IStaticType;
const AIdentity: IAstIdentity
);
begin
inherited Create(AStaticType, AIdentity);
FPairs := APairs;
FElseBranch := AElseBranch;
end;
function TCondExpressionNode.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitCondExpression(Self);
end;
function TCondExpressionNode.AsCondExpression: ICondExpressionNode;
begin
Result := Self;
end;
function TCondExpressionNode.GetPairs: TArray<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.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitLambdaExpression(Self);
end;
function TLambdaExpressionNode.AsLambdaExpression: ILambdaExpressionNode;
begin
Result := Self;
end;
function TLambdaExpressionNode.GetBody: IAstNode;
begin
Result := FBody;
end;
function TLambdaExpressionNode.GetParameters: IParameterList;
begin
Result := FParameters;
end;
function TLambdaExpressionNode.GetLayout: IScopeLayout;
begin
Result := FLayout;
end;
function TLambdaExpressionNode.GetDescriptor: IScopeDescriptor;
begin
Result := FDescriptor;
end;
function TLambdaExpressionNode.GetUpvalues: TArray<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.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitFunctionCall(Self);
end;
function TFunctionCallNode.AsFunctionCall: IFunctionCallNode;
begin
Result := Self;
end;
function TFunctionCallNode.GetCallee: IAstNode;
begin
Result := FCallee;
end;
function TFunctionCallNode.GetArguments: IArgumentList;
begin
Result := FArguments;
end;
function TFunctionCallNode.GetIsTailCall: Boolean;
begin
Result := FIsTailCall;
end;
function TFunctionCallNode.GetStaticTarget: TDataValue.TFunc;
begin
Result := FStaticTarget;
end;
function TFunctionCallNode.GetIsTargetPure: Boolean;
begin
Result := FIsTargetPure;
end;
function TFunctionCallNode.GetKind: TAstNodeKind;
begin
Result := akFunctionCall;
end;
{ TMacroDefinitionNode }
constructor TMacroDefinitionNode.Create(
const AName: IIdentifierNode;
const AParameters: IParameterList;
const ABody: IAstNode;
const AIdentity: IAstIdentity
);
begin
inherited Create(TTypes.Void, AIdentity);
FName := AName;
FParameters := AParameters;
FBody := ABody;
end;
function TMacroDefinitionNode.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitMacroDefinition(Self);
end;
function TMacroDefinitionNode.AsMacroDefinition: IMacroDefinitionNode;
begin
Result := Self;
end;
function TMacroDefinitionNode.GetName: IIdentifierNode;
begin
Result := FName;
end;
function TMacroDefinitionNode.GetParameters: IParameterList;
begin
Result := FParameters;
end;
function TMacroDefinitionNode.GetBody: IAstNode;
begin
Result := FBody;
end;
function TMacroDefinitionNode.GetKind: TAstNodeKind;
begin
Result := akMacroDefinition;
end;
{ TMacroExpansionNode }
constructor TMacroExpansionNode.Create(const ACallNode: IFunctionCallNode; const AExpandedBody: IAstNode; const AIdentity: IAstIdentity);
begin
if AExpandedBody.IsTyped then
inherited Create(AExpandedBody.AsTypedNode.StaticType, AIdentity)
else
inherited Create(TTypes.Unknown, AIdentity);
FCallNode := ACallNode;
FExpandedBody := AExpandedBody;
end;
function TMacroExpansionNode.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitMacroExpansionNode(Self);
end;
function TMacroExpansionNode.AsMacroExpansion: IMacroExpansionNode;
begin
Result := Self;
end;
function TMacroExpansionNode.GetCallNode: IFunctionCallNode;
begin
Result := FCallNode;
end;
function TMacroExpansionNode.GetExpandedBody: IAstNode;
begin
Result := FExpandedBody;
end;
function TMacroExpansionNode.GetKind: TAstNodeKind;
begin
Result := akMacroExpansion;
end;
{ TQuasiquoteNode }
constructor TQuasiquoteNode.Create(const AExpression: IAstNode; const AIdentity: IAstIdentity);
begin
inherited Create(AIdentity);
FExpression := AExpression;
end;
function TQuasiquoteNode.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitQuasiquote(Self);
end;
function TQuasiquoteNode.AsQuasiquote: IQuasiquoteNode;
begin
Result := Self;
end;
function TQuasiquoteNode.GetExpression: IAstNode;
begin
Result := FExpression;
end;
function TQuasiquoteNode.GetKind: TAstNodeKind;
begin
Result := akQuasiquote;
end;
{ TUnquoteNode }
constructor TUnquoteNode.Create(const AExpression: IAstNode; const AIdentity: IAstIdentity);
begin
inherited Create(AIdentity);
FExpression := AExpression;
end;
function TUnquoteNode.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitUnquote(Self);
end;
function TUnquoteNode.AsUnquote: IUnquoteNode;
begin
Result := Self;
end;
function TUnquoteNode.GetExpression: IAstNode;
begin
Result := FExpression;
end;
function TUnquoteNode.GetKind: TAstNodeKind;
begin
Result := akUnquote;
end;
{ TUnquoteSplicingNode }
constructor TUnquoteSplicingNode.Create(const AExpression: IQuasiquoteNode; const AIdentity: IAstIdentity);
begin
inherited Create(AIdentity);
FExpression := AExpression;
end;
function TUnquoteSplicingNode.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitUnquoteSplicing(Self);
end;
function TUnquoteSplicingNode.AsUnquoteSplicing: IUnquoteSplicingNode;
begin
Result := Self;
end;
function TUnquoteSplicingNode.GetExpression: IQuasiquoteNode;
begin
Result := FExpression;
end;
function TUnquoteSplicingNode.GetKind: TAstNodeKind;
begin
Result := akUnquoteSplicing;
end;
{ TRecurNode }
constructor TRecurNode.Create(const AArguments: IArgumentList; const AStaticType: IStaticType; const AIdentity: IAstIdentity);
begin
inherited Create(AStaticType, AIdentity);
FArguments := AArguments;
end;
function TRecurNode.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitRecurNode(Self);
end;
function TRecurNode.AsRecur: IRecurNode;
begin
Result := Self;
end;
function TRecurNode.GetArguments: IArgumentList;
begin
Result := FArguments;
end;
function TRecurNode.GetKind: TAstNodeKind;
begin
Result := akRecur;
end;
{ TBlockExpressionNode }
constructor TBlockExpressionNode.Create(const AExpressions: IExpressionList; const AStaticType: IStaticType; const AIdentity: IAstIdentity);
begin
inherited Create(AStaticType, AIdentity);
FExpressions := AExpressions;
end;
function TBlockExpressionNode.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitBlockExpression(Self);
end;
function TBlockExpressionNode.AsBlockExpression: IBlockExpressionNode;
begin
Result := Self;
end;
function TBlockExpressionNode.GetExpressions: IExpressionList;
begin
Result := FExpressions;
end;
function TBlockExpressionNode.GetKind: TAstNodeKind;
begin
Result := akBlockExpression;
end;
{ TVariableDeclarationNode }
constructor TVariableDeclarationNode.Create(
const ATarget: IAstNode;
AInitializer: IAstNode;
const AStaticType: IStaticType;
const AIsBoxed: Boolean;
const AIdentity: IAstIdentity
);
begin
inherited Create(AStaticType, AIdentity);
FTarget := ATarget;
FInitializer := AInitializer;
FIsBoxed := AIsBoxed;
end;
function TVariableDeclarationNode.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitVariableDeclaration(Self);
end;
function TVariableDeclarationNode.AsVariableDeclaration: IVariableDeclarationNode;
begin
Result := Self;
end;
function TVariableDeclarationNode.GetTarget: IAstNode;
begin
Result := FTarget;
end;
function TVariableDeclarationNode.GetInitializer: IAstNode;
begin
Result := FInitializer;
end;
function TVariableDeclarationNode.GetIsBoxed: Boolean;
begin
Result := FIsBoxed;
end;
function TVariableDeclarationNode.GetKind: TAstNodeKind;
begin
Result := akVariableDeclaration;
end;
{ TAssignmentNode }
constructor TAssignmentNode.Create(const ATarget, AValue: IAstNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity);
begin
inherited Create(AStaticType, AIdentity);
FTarget := ATarget;
FValue := AValue;
end;
function TAssignmentNode.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitAssignment(Self);
end;
function TAssignmentNode.AsAssignment: IAssignmentNode;
begin
Result := Self;
end;
function TAssignmentNode.GetTarget: IAstNode;
begin
Result := FTarget;
end;
function TAssignmentNode.GetValue: IAstNode;
begin
Result := FValue;
end;
function TAssignmentNode.GetKind: TAstNodeKind;
begin
Result := akAssignment;
end;
{ TIndexerNode }
constructor TIndexerNode.Create(const ABase, AIndex: IAstNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity);
begin
inherited Create(AStaticType, AIdentity);
FBase := ABase;
FIndex := AIndex;
end;
function TIndexerNode.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitIndexer(Self);
end;
function TIndexerNode.AsIndexer: IIndexerNode;
begin
Result := Self;
end;
function TIndexerNode.GetBase: IAstNode;
begin
Result := FBase;
end;
function TIndexerNode.GetIndex: IAstNode;
begin
Result := FIndex;
end;
function TIndexerNode.GetKind: TAstNodeKind;
begin
Result := akIndexer;
end;
{ TMemberAccessNode }
constructor TMemberAccessNode.Create(
const ABase: IAstNode;
const AMember: IKeywordNode;
const AStaticType: IStaticType;
const AIdentity: IAstIdentity
);
begin
inherited Create(AStaticType, AIdentity);
FBase := ABase;
FMember := AMember;
end;
function TMemberAccessNode.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitMemberAccess(Self);
end;
function TMemberAccessNode.AsMemberAccess: IMemberAccessNode;
begin
Result := Self;
end;
function TMemberAccessNode.GetBase: IAstNode;
begin
Result := FBase;
end;
function TMemberAccessNode.GetMember: IKeywordNode;
begin
Result := FMember;
end;
function TMemberAccessNode.GetKind: TAstNodeKind;
begin
Result := akMemberAccess;
end;
{ TRecordLiteralNode }
constructor TRecordLiteralNode.Create(
const AFields: IRecordFieldList;
const AScalarDef: IScalarRecordDefinition;
const AGenericDef: IGenericRecordDefinition;
const AStaticType: IStaticType;
const AIdentity: IAstIdentity
);
begin
inherited Create(AStaticType, AIdentity);
FFields := AFields;
FScalarDef := AScalarDef;
FGenericDef := AGenericDef;
end;
function TRecordLiteralNode.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitRecordLiteral(Self);
end;
function TRecordLiteralNode.AsRecordLiteral: IRecordLiteralNode;
begin
Result := Self;
end;
function TRecordLiteralNode.GetFields: IRecordFieldList;
begin
Result := FFields;
end;
function TRecordLiteralNode.GetGenericDefinition: IGenericRecordDefinition;
begin
Result := FGenericDef;
end;
function TRecordLiteralNode.GetScalarDefinition: IScalarRecordDefinition;
begin
Result := FScalarDef;
end;
function TRecordLiteralNode.GetKind: TAstNodeKind;
begin
Result := akRecordLiteral;
end;
{ TAddSeriesItemNode }
constructor TAddSeriesItemNode.Create(
const ASeries: IIdentifierNode;
const AValue, ALookback: IAstNode;
const AStaticType: IStaticType;
const AIdentity: IAstIdentity
);
begin
inherited Create(AStaticType, AIdentity);
FSeries := ASeries;
FValue := AValue;
FLookback := ALookback;
end;
function TAddSeriesItemNode.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitAddSeriesItem(Self);
end;
function TAddSeriesItemNode.AsAddSeriesItem: IAddSeriesItemNode;
begin
Result := Self;
end;
function TAddSeriesItemNode.GetSeries: IIdentifierNode;
begin
Result := FSeries;
end;
function TAddSeriesItemNode.GetValue: IAstNode;
begin
Result := FValue;
end;
function TAddSeriesItemNode.GetLookback: IAstNode;
begin
Result := FLookback;
end;
function TAddSeriesItemNode.GetKind: TAstNodeKind;
begin
Result := akAddSeriesItem;
end;
{ TSeriesLengthNode }
constructor TSeriesLengthNode.Create(const ASeries: IIdentifierNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity);
begin
inherited Create(AStaticType, AIdentity);
FSeries := ASeries;
end;
function TSeriesLengthNode.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitSeriesLength(Self);
end;
function TSeriesLengthNode.AsSeriesLength: ISeriesLengthNode;
begin
Result := Self;
end;
function TSeriesLengthNode.GetSeries: IIdentifierNode;
begin
Result := FSeries;
end;
function TSeriesLengthNode.GetKind: TAstNodeKind;
begin
Result := akSeriesLength;
end;
{ TNopNode }
constructor TNopNode.Create(const AStaticType: IStaticType; const AIdentity: IAstIdentity);
begin
inherited Create(AStaticType, AIdentity);
end;
function TNopNode.Accept(const Visitor: IAstVisitor): TDataValue;
begin
Result := Visitor.VisitNop(Self);
end;
function TNopNode.AsNop: INopNode;
begin
Result := Self;
end;
function TNopNode.GetKind: TAstNodeKind;
begin
Result := akNop;
end;
constructor TAstNodeList<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;
end.