1671 lines
50 KiB
ObjectPascal
1671 lines
50 KiB
ObjectPascal
unit Myc.Ast;
|
|
|
|
interface
|
|
|
|
uses
|
|
System.SysUtils,
|
|
System.Classes,
|
|
System.Generics.Collections,
|
|
Myc.Data.Scalar,
|
|
Myc.Data.Value,
|
|
Myc.Data.Keyword,
|
|
Myc.Ast.Nodes, // Contains TAstNodeKind, IAstNode, etc.
|
|
Myc.Ast.Scope,
|
|
Myc.Ast.Types;
|
|
|
|
type
|
|
// Record acting as a namespace for the factory functions.
|
|
TAst = record
|
|
public
|
|
type
|
|
TRegisterLibraryProc = reference to procedure(const Scope: IExecutionScope);
|
|
private
|
|
class var
|
|
FLibraries: TList<TRegisterLibraryProc>;
|
|
class constructor Create;
|
|
class destructor Destroy;
|
|
public
|
|
class procedure RegisterLibrary(const AProc: TRegisterLibraryProc); static;
|
|
class function CreateScope(Parent: IExecutionScope; const Descriptor: IScopeDescriptor = nil): IExecutionScope; static;
|
|
|
|
// A No-Operation node, used as a placeholder/stub (e.g., for UI drop targets).
|
|
// This node is illegal in the compiler (Binder/TypeChecker will reject it).
|
|
class function Nop: IAstNode; static;
|
|
|
|
// --- Factory functions ---
|
|
class function Constant(const AValue: TDataValue): IConstantNode; overload; static;
|
|
class function Constant(const AValue: String): IConstantNode; overload; static;
|
|
class function Keyword(const AName: string): IKeywordNode; static;
|
|
class function Identifier(AName: string): IIdentifierNode; static;
|
|
class function BinaryExpr(ALeft: IAstNode; AOperator: TScalar.TBinaryOp; ARight: IAstNode): IBinaryExpressionNode; static;
|
|
class function UnaryExpr(const AOperator: TScalar.TUnaryOp; const ARight: IAstNode): IUnaryExpressionNode; static;
|
|
class function IfExpr(const ACondition: IAstNode; const AThenBranch, AElseBranch: IAstNode): IIfExpressionNode; static;
|
|
class function TernaryExpr(const ACondition: IAstNode; const AThenBranch, AElseBranch: IAstNode): ITernaryExpressionNode; static;
|
|
class function LambdaExpr(const AParameters: TArray<IIdentifierNode>; const ABody: IAstNode): ILambdaExpressionNode; static;
|
|
class function MacroDef(
|
|
const AName: IIdentifierNode;
|
|
const AParameters: TArray<IIdentifierNode>;
|
|
const ABody: IAstNode
|
|
): IMacroDefinitionNode; static;
|
|
class function Quasiquote(const AExpression: IAstNode): IQuasiquoteNode; static;
|
|
class function Unquote(const AExpression: IAstNode): IUnquoteNode; static;
|
|
class function UnquoteSplicing(const AExpression: IQuasiquoteNode): IUnquoteSplicingNode; static;
|
|
class function FunctionCall(const ACallee: IAstNode; const AArguments: TArray<IAstNode>): IFunctionCallNode; static;
|
|
class function MacroExpansionNode(
|
|
const AOriginalCallNode: IFunctionCallNode;
|
|
const AExpandedBody: IAstNode
|
|
): IMacroExpansionNode; static;
|
|
class function Recur(const AArguments: array of IAstNode): IRecurNode; static;
|
|
class function Block(const AExpressions: array of IAstNode): IBlockExpressionNode; static;
|
|
class function VarDecl(const AIdentifier: IIdentifierNode; AInitializer: IAstNode = nil): IVariableDeclarationNode; static;
|
|
class function Assign(const AIdentifier: IIdentifierNode; const AValue: IAstNode): IAssignmentNode; static;
|
|
class function AssignResult(const AValue: IAstNode): IAssignmentNode; static; deprecated;
|
|
class function Indexer(const ABase: IAstNode; const AIndex: IAstNode): IIndexerNode; static;
|
|
class function MemberAccess(const ABase: IAstNode; const AMember: IKeywordNode): IMemberAccessNode; static;
|
|
class function RecordLiteral(const AFields: TArray<TRecordFieldLiteral>): IRecordLiteralNode; static;
|
|
class function CreateSeries(const ADefinition: String): ICreateSeriesNode; static;
|
|
class function AddSeriesItem(
|
|
const ASeries: IIdentifierNode;
|
|
const AValue: IAstNode;
|
|
const ALookback: IAstNode = nil
|
|
): IAddSeriesItemNode; static;
|
|
class function SeriesLength(const ASeries: IIdentifierNode): ISeriesLengthNode; static;
|
|
end;
|
|
|
|
// Common base class for AST nodes to reduce boilerplate.
|
|
TAstNode = class(TInterfacedObject, IAstNode)
|
|
private
|
|
FStaticType: IStaticType;
|
|
procedure SetStaticType(const AValue: IStaticType);
|
|
function GetKind: TAstNodeKind; virtual; abstract;
|
|
public
|
|
constructor Create;
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; virtual; abstract;
|
|
|
|
// --- As... Accessors Implementation ---
|
|
function AsConstant: IConstantNode; virtual;
|
|
function AsIdentifier: IIdentifierNode; virtual;
|
|
function AsKeyword: IKeywordNode; virtual;
|
|
function AsBinaryExpression: IBinaryExpressionNode; virtual;
|
|
function AsUnaryExpression: IUnaryExpressionNode; virtual;
|
|
function AsIfExpression: IIfExpressionNode; virtual;
|
|
function AsTernaryExpression: ITernaryExpressionNode; virtual;
|
|
function AsLambdaExpression: ILambdaExpressionNode; virtual;
|
|
function AsFunctionCall: IFunctionCallNode; virtual;
|
|
function AsMacroExpansion: IMacroExpansionNode; virtual;
|
|
function AsBlockExpression: IBlockExpressionNode; virtual;
|
|
function AsVariableDeclaration: IVariableDeclarationNode; virtual;
|
|
function AsAssignment: IAssignmentNode; virtual;
|
|
function AsMacroDefinition: IMacroDefinitionNode; virtual;
|
|
function AsQuasiquote: IQuasiquoteNode; virtual;
|
|
function AsUnquote: IUnquoteNode; virtual;
|
|
function AsUnquoteSplicing: IUnquoteSplicingNode; virtual;
|
|
function AsIndexer: IIndexerNode; virtual;
|
|
function AsMemberAccess: IMemberAccessNode; virtual;
|
|
function AsRecordLiteral: IRecordLiteralNode; virtual;
|
|
function AsCreateSeries: ICreateSeriesNode; virtual;
|
|
function AsAddSeriesItem: IAddSeriesItemNode; virtual;
|
|
function AsSeriesLength: ISeriesLengthNode; virtual;
|
|
function AsRecur: IRecurNode; virtual;
|
|
function AsNop: INopNode; virtual; // Added Nop
|
|
|
|
function AsBoundIdentifierNode: IBoundIdentifierNode; virtual;
|
|
|
|
property StaticType: IStaticType read FStaticType write SetStaticType;
|
|
property Kind: TAstNodeKind read GetKind;
|
|
end;
|
|
|
|
TConstantNode = class(TAstNode, IConstantNode)
|
|
private
|
|
FValue: TDataValue;
|
|
function GetValue: TDataValue;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AValue: TDataValue);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsConstant: IConstantNode; override;
|
|
property Value: TDataValue read GetValue; // Value ist immutable
|
|
end;
|
|
|
|
TIdentifierNode = class(TAstNode, IIdentifierNode)
|
|
private
|
|
FName: string;
|
|
function GetName: string;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AName: string);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsIdentifier: IIdentifierNode; override;
|
|
property Name: string read FName; // Name ist immutable
|
|
end;
|
|
|
|
TBoundIdentifierNode = class(TIdentifierNode, IBoundIdentifierNode)
|
|
private
|
|
FAddress: TResolvedAddress;
|
|
function GetAddress: TResolvedAddress;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AName: string; const AAddress: TResolvedAddress);
|
|
function AsBoundIdentifierNode: IBoundIdentifierNode; override;
|
|
property Address: TResolvedAddress read GetAddress;
|
|
end;
|
|
|
|
TKeywordNode = class(TAstNode, IKeywordNode)
|
|
private
|
|
FValue: IKeyword;
|
|
function GetValue: IKeyword;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AValue: IKeyword);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsKeyword: IKeywordNode; override;
|
|
property Value: IKeyword read FValue; // Value ist immutable
|
|
end;
|
|
|
|
TBinaryExpressionNode = class(TAstNode, IBinaryExpressionNode)
|
|
private
|
|
FLeft: IAstNode;
|
|
FOperator: TScalar.TBinaryOp;
|
|
FRight: IAstNode;
|
|
function GetLeft: IAstNode;
|
|
function GetOperator: TScalar.TBinaryOp;
|
|
function GetRight: IAstNode;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const ALeft: IAstNode; AOperator: TScalar.TBinaryOp; const ARight: IAstNode);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsBinaryExpression: IBinaryExpressionNode; override;
|
|
property Left: IAstNode read FLeft write FLeft; // Writeable
|
|
property Operator: TScalar.TBinaryOp read FOperator write FOperator; // Writeable
|
|
property Right: IAstNode read FRight write FRight; // Writeable
|
|
end;
|
|
|
|
TUnaryExpressionNode = class(TAstNode, IUnaryExpressionNode)
|
|
private
|
|
FOperator: TScalar.TUnaryOp;
|
|
FRight: IAstNode;
|
|
function GetOperator: TScalar.TUnaryOp;
|
|
function GetRight: IAstNode;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AOperator: TScalar.TUnaryOp; const ARight: IAstNode);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsUnaryExpression: IUnaryExpressionNode; override;
|
|
property Operator: TScalar.TUnaryOp read FOperator write FOperator; // Writeable
|
|
property Right: IAstNode read FRight write FRight; // Writeable
|
|
end;
|
|
|
|
TIfExpressionNode = class(TAstNode, IIfExpressionNode)
|
|
private
|
|
FCondition: IAstNode;
|
|
FThenBranch: IAstNode;
|
|
FElseBranch: IAstNode;
|
|
function GetCondition: IAstNode;
|
|
function GetThenBranch: IAstNode;
|
|
function GetElseBranch: IAstNode;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const ACondition, AThenBranch, AElseBranch: IAstNode);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsIfExpression: IIfExpressionNode; override;
|
|
property Condition: IAstNode read FCondition write FCondition; // Writeable
|
|
property ThenBranch: IAstNode read FThenBranch write FThenBranch; // Writeable
|
|
property ElseBranch: IAstNode read FElseBranch write FElseBranch; // Writeable
|
|
end;
|
|
|
|
TTernaryExpressionNode = class(TAstNode, ITernaryExpressionNode)
|
|
private
|
|
FCondition: IAstNode;
|
|
FThenBranch: IAstNode;
|
|
FElseBranch: IAstNode;
|
|
function GetCondition: IAstNode;
|
|
function GetThenBranch: IAstNode;
|
|
function GetElseBranch: IAstNode;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const ACondition, AThenBranch, AElseBranch: IAstNode);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsTernaryExpression: ITernaryExpressionNode; override;
|
|
property Condition: IAstNode read FCondition write FCondition; // Writeable
|
|
property ThenBranch: IAstNode read FThenBranch write FThenBranch; // Writeable
|
|
property ElseBranch: IAstNode read FElseBranch write FElseBranch; // Writeable
|
|
end;
|
|
|
|
TLambdaExpressionNode = class(TAstNode, ILambdaExpressionNode)
|
|
private
|
|
FParameters: TArray<IIdentifierNode>;
|
|
FBody: IAstNode;
|
|
FScopeDescriptor: IScopeDescriptor;
|
|
FUpvalues: TArray<TResolvedAddress>;
|
|
FHasNestedLambdas: Boolean;
|
|
function GetParameters: TArray<IIdentifierNode>;
|
|
function GetBody: IAstNode;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AParameters: TArray<IIdentifierNode>; const ABody: IAstNode);
|
|
destructor Destroy; override;
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsLambdaExpression: ILambdaExpressionNode; override;
|
|
property Body: IAstNode read FBody write FBody; // Writeable
|
|
property Parameters: TArray<IIdentifierNode> read FParameters write FParameters;
|
|
property ScopeDescriptor: IScopeDescriptor read FScopeDescriptor write FScopeDescriptor;
|
|
property Upvalues: TArray<TResolvedAddress> read FUpvalues write FUpvalues;
|
|
property HasNestedLambdas: Boolean read FHasNestedLambdas write FHasNestedLambdas;
|
|
end;
|
|
|
|
TMacroDefinitionNode = class(TAstNode, IMacroDefinitionNode)
|
|
private
|
|
FName: IIdentifierNode;
|
|
FParameters: TArray<IIdentifierNode>;
|
|
FBody: IAstNode;
|
|
function GetName: IIdentifierNode;
|
|
function GetParameters: TArray<IIdentifierNode>;
|
|
function GetBody: IAstNode;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AName: IIdentifierNode; const AParameters: TArray<IIdentifierNode>; const ABody: IAstNode);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsMacroDefinition: IMacroDefinitionNode; override;
|
|
property Name: IIdentifierNode read GetName write FName; // Writeable
|
|
property Parameters: TArray<IIdentifierNode> read FParameters write FParameters;
|
|
property Body: IAstNode read FBody write FBody; // Writeable
|
|
end;
|
|
|
|
TQuasiquoteNode = class(TAstNode, IQuasiquoteNode)
|
|
private
|
|
FExpression: IAstNode;
|
|
function GetExpression: IAstNode;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AExpression: IAstNode);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsQuasiquote: IQuasiquoteNode; override;
|
|
property Expression: IAstNode read GetExpression write FExpression; // Writeable
|
|
end;
|
|
|
|
TUnquoteNode = class(TAstNode, IUnquoteNode)
|
|
private
|
|
FExpression: IAstNode;
|
|
function GetExpression: IAstNode;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AExpression: IAstNode);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsUnquote: IUnquoteNode; override;
|
|
property Expression: IAstNode read GetExpression write FExpression; // Writeable
|
|
end;
|
|
|
|
TUnquoteSplicingNode = class(TAstNode, IUnquoteSplicingNode)
|
|
private
|
|
FExpression: IQuasiquoteNode;
|
|
function GetExpression: IQuasiquoteNode;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AExpression: IQuasiquoteNode);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsUnquoteSplicing: IUnquoteSplicingNode; override;
|
|
property Expression: IQuasiquoteNode read GetExpression write FExpression;
|
|
end;
|
|
|
|
TFunctionCallNode = class(TAstNode, IFunctionCallNode)
|
|
private
|
|
FCallee: IAstNode;
|
|
FArguments: TArray<IAstNode>;
|
|
FIsTailCall: Boolean;
|
|
function GetCallee: IAstNode;
|
|
function GetArguments: TArray<IAstNode>;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const ACallee: IAstNode; const AArguments: TArray<IAstNode>);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsFunctionCall: IFunctionCallNode; override;
|
|
property Callee: IAstNode read FCallee write FCallee; // Writeable
|
|
property Arguments: TArray<IAstNode> read FArguments write FArguments; // Writeable
|
|
property IsTailCall: Boolean read FIsTailCall write FIsTailCall;
|
|
end;
|
|
|
|
TRecurNode = class(TAstNode, IRecurNode)
|
|
private
|
|
FArguments: TArray<IAstNode>;
|
|
function GetArguments: TArray<IAstNode>;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AArguments: TArray<IAstNode>);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsRecur: IRecurNode; override;
|
|
property Arguments: TArray<IAstNode> read FArguments write FArguments; // Writeable
|
|
end;
|
|
|
|
TMacroExpansionNode = class(TFunctionCallNode, IMacroExpansionNode)
|
|
private
|
|
FExpandedBody: IAstNode;
|
|
function GetExpandedBody: IAstNode;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AOriginalCallNode: IFunctionCallNode; const AExpandedBody: IAstNode);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsMacroExpansion: IMacroExpansionNode; override;
|
|
property ExpandedBody: IAstNode read FExpandedBody write FExpandedBody; // Writeable
|
|
end;
|
|
TBlockExpressionNode = class(TAstNode, IBlockExpressionNode)
|
|
private
|
|
FExpressions: TArray<IAstNode>;
|
|
function GetExpressions: TArray<IAstNode>;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AExpressions: array of IAstNode);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsBlockExpression: IBlockExpressionNode; override;
|
|
property Expressions: TArray<IAstNode> read FExpressions write FExpressions; // Writeable
|
|
end;
|
|
|
|
TVariableDeclarationNode = class(TAstNode, IVariableDeclarationNode)
|
|
private
|
|
FIdentifier: IIdentifierNode;
|
|
FInitializer: IAstNode;
|
|
FIsBoxed: Boolean;
|
|
function GetIdentifier: IIdentifierNode;
|
|
function GetInitializer: IAstNode;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AIdentifier: IIdentifierNode; AInitializer: IAstNode);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsVariableDeclaration: IVariableDeclarationNode; override;
|
|
property Identifier: IIdentifierNode read FIdentifier write FIdentifier; // Writeable
|
|
property Initializer: IAstNode read FInitializer write FInitializer; // Writeable
|
|
property IsBoxed: Boolean read FIsBoxed write FIsBoxed;
|
|
end;
|
|
|
|
TAssignmentNode = class(TAstNode, IAssignmentNode)
|
|
private
|
|
FIdentifier: IIdentifierNode;
|
|
FValue: IAstNode;
|
|
function GetIdentifier: IIdentifierNode;
|
|
function GetValue: IAstNode;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AIdentifier: IIdentifierNode; const AValue: IAstNode);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsAssignment: IAssignmentNode; override;
|
|
property Identifier: IIdentifierNode read FIdentifier write FIdentifier;
|
|
property Value: IAstNode read FValue write FValue; // Writeable
|
|
end;
|
|
|
|
TIndexerNode = class(TAstNode, IIndexerNode)
|
|
private
|
|
FBase: IAstNode;
|
|
FIndex: IAstNode;
|
|
function GetBase: IAstNode;
|
|
function GetIndex: IAstNode;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const ABase: IAstNode; const AIndex: IAstNode);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsIndexer: IIndexerNode; override;
|
|
property Base: IAstNode read FBase write FBase; // Writeable
|
|
property Index: IAstNode read FIndex write FIndex; // Writeable
|
|
end;
|
|
|
|
TMemberAccessNode = class(TAstNode, 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);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsMemberAccess: IMemberAccessNode; override;
|
|
property Base: IAstNode read FBase write FBase; // Writeable
|
|
property Member: IKeywordNode read FMember write FMember;
|
|
end;
|
|
|
|
TRecordLiteralNode = class(TAstNode, IRecordLiteralNode)
|
|
private
|
|
FFields: TArray<TRecordFieldLiteral>;
|
|
FDefinition: IScalarRecordDefinition;
|
|
function GetFields: TArray<TRecordFieldLiteral>;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AFields: TArray<TRecordFieldLiteral>);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsRecordLiteral: IRecordLiteralNode; override;
|
|
property Fields: TArray<TRecordFieldLiteral> read FFields write FFields; // Writeable
|
|
property Definition: IScalarRecordDefinition read FDefinition write FDefinition;
|
|
end;
|
|
|
|
TGenericRecordLiteralNode = class(TRecordLiteralNode, IRecordLiteralNode)
|
|
private
|
|
FGenericDefinition: IGenericRecordDefinition;
|
|
public
|
|
constructor Create(const AFields: TArray<TRecordFieldLiteral>);
|
|
property GenericDefinition: IGenericRecordDefinition read FGenericDefinition write FGenericDefinition;
|
|
end;
|
|
|
|
TCreateSeriesNode = class(TAstNode, ICreateSeriesNode)
|
|
private
|
|
FDefinition: String;
|
|
function GetDefinition: String;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const ADefinition: String);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsCreateSeries: ICreateSeriesNode; override;
|
|
end;
|
|
|
|
TAddSeriesItemNode = class(TAstNode, IAddSeriesItemNode)
|
|
private
|
|
FSeries: IIdentifierNode;
|
|
FValue: IAstNode;
|
|
FLookback: IAstNode;
|
|
function GetSeries: IIdentifierNode;
|
|
function GetValue: IAstNode;
|
|
function GetLookback: IAstNode;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const ASeries: IIdentifierNode; const AValue: IAstNode; const ALookback: IAstNode);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsAddSeriesItem: IAddSeriesItemNode; override;
|
|
property Series: IIdentifierNode read FSeries write FSeries;
|
|
property Value: IAstNode read FValue write FValue; // Writeable
|
|
property Lookback: IAstNode read FLookback write FLookback; // Writeable
|
|
end;
|
|
|
|
TSeriesLengthNode = class(TAstNode, ISeriesLengthNode)
|
|
private
|
|
FSeries: IIdentifierNode;
|
|
function GetSeries: IIdentifierNode;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const ASeries: IIdentifierNode);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsSeriesLength: ISeriesLengthNode; override;
|
|
property Series: IIdentifierNode read FSeries write FSeries;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
System.Generics.Defaults;
|
|
|
|
// Added Nop
|
|
type
|
|
TNopNode = class(TAstNode, INopNode)
|
|
private
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create;
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsNop: INopNode; override;
|
|
end;
|
|
|
|
{ TAst }
|
|
|
|
class function TAst.CreateScope(Parent: IExecutionScope; const Descriptor: IScopeDescriptor): IExecutionScope;
|
|
begin
|
|
if Assigned(Descriptor) then
|
|
Result := Descriptor.CreateScope(Parent)
|
|
else
|
|
Result := TScope.CreateScope(Parent, nil, nil);
|
|
|
|
// Register libraries in the *new* scope
|
|
for var libProc in FLibraries do
|
|
libProc(Result);
|
|
end;
|
|
|
|
class function TAst.CreateSeries(const ADefinition: String): ICreateSeriesNode;
|
|
begin
|
|
Result := TCreateSeriesNode.Create(ADefinition);
|
|
end;
|
|
|
|
class function TAst.AddSeriesItem(
|
|
const ASeries: IIdentifierNode;
|
|
const AValue: IAstNode;
|
|
const ALookback: IAstNode = nil
|
|
): IAddSeriesItemNode;
|
|
begin
|
|
Result := TAddSeriesItemNode.Create(ASeries, AValue, ALookback);
|
|
end;
|
|
|
|
class function TAst.SeriesLength(const ASeries: IIdentifierNode): ISeriesLengthNode;
|
|
begin
|
|
Result := TSeriesLengthNode.Create(ASeries);
|
|
end;
|
|
|
|
class function TAst.Assign(const AIdentifier: IIdentifierNode; const AValue: IAstNode): IAssignmentNode;
|
|
begin
|
|
Result := TAssignmentNode.Create(AIdentifier, AValue);
|
|
end;
|
|
|
|
class function TAst.AssignResult(const AValue: IAstNode): IAssignmentNode;
|
|
begin
|
|
// The parser ensures 'Result' is a valid identifier, so we create one.
|
|
// The binder will resolve it.
|
|
Result := TAssignmentNode.Create(TAst.Identifier('Result'), AValue);
|
|
end;
|
|
|
|
class function TAst.BinaryExpr(ALeft: IAstNode; AOperator: TScalar.TBinaryOp; ARight: IAstNode): IBinaryExpressionNode;
|
|
begin
|
|
Result := TBinaryExpressionNode.Create(ALeft, AOperator, ARight);
|
|
end;
|
|
|
|
class function TAst.Block(const AExpressions: array of IAstNode): IBlockExpressionNode;
|
|
begin
|
|
Result := TBlockExpressionNode.Create(AExpressions);
|
|
end;
|
|
|
|
class function TAst.Constant(const AValue: TDataValue): IConstantNode;
|
|
begin
|
|
Result := TConstantNode.Create(AValue);
|
|
end;
|
|
|
|
class function TAst.Constant(const AValue: String): IConstantNode;
|
|
begin
|
|
Result := TConstantNode.Create(AValue);
|
|
end;
|
|
|
|
class constructor TAst.Create;
|
|
begin
|
|
FLibraries := TList<TRegisterLibraryProc>.Create;
|
|
end;
|
|
|
|
class destructor TAst.Destroy;
|
|
begin
|
|
FLibraries.Free;
|
|
end;
|
|
|
|
class procedure TAst.RegisterLibrary(const AProc: TRegisterLibraryProc);
|
|
begin
|
|
FLibraries.Add(AProc);
|
|
end;
|
|
|
|
class function TAst.FunctionCall(const ACallee: IAstNode; const AArguments: TArray<IAstNode>): IFunctionCallNode;
|
|
begin
|
|
Result := TFunctionCallNode.Create(ACallee, AArguments);
|
|
end;
|
|
|
|
class function TAst.Identifier(AName: string): IIdentifierNode;
|
|
begin
|
|
Result := TIdentifierNode.Create(AName);
|
|
end;
|
|
|
|
class function TAst.IfExpr(const ACondition: IAstNode; const AThenBranch, AElseBranch: IAstNode): IIfExpressionNode;
|
|
begin
|
|
Result := TIfExpressionNode.Create(ACondition, AThenBranch, AElseBranch);
|
|
end;
|
|
|
|
class function TAst.Indexer(const ABase: IAstNode; const AIndex: IAstNode): IIndexerNode;
|
|
begin
|
|
Result := TIndexerNode.Create(ABase, AIndex);
|
|
end;
|
|
|
|
class function TAst.Keyword(const AName: string): IKeywordNode;
|
|
begin
|
|
Result := TKeywordNode.Create(TKeywordRegistry.Intern(AName));
|
|
end;
|
|
|
|
class function TAst.LambdaExpr(const AParameters: TArray<IIdentifierNode>; const ABody: IAstNode): ILambdaExpressionNode;
|
|
begin
|
|
Result := TLambdaExpressionNode.Create(AParameters, ABody);
|
|
end;
|
|
|
|
class function TAst.MacroDef(
|
|
const AName: IIdentifierNode;
|
|
const AParameters: TArray<IIdentifierNode>;
|
|
const ABody: IAstNode
|
|
): IMacroDefinitionNode;
|
|
begin
|
|
Result := TMacroDefinitionNode.Create(AName, AParameters, ABody);
|
|
end;
|
|
|
|
class function TAst.MacroExpansionNode(const AOriginalCallNode: IFunctionCallNode; const AExpandedBody: IAstNode): IMacroExpansionNode;
|
|
begin
|
|
Result := TMacroExpansionNode.Create(AOriginalCallNode, AExpandedBody);
|
|
end;
|
|
|
|
class function TAst.MemberAccess(const ABase: IAstNode; const AMember: IKeywordNode): IMemberAccessNode;
|
|
begin
|
|
Result := TMemberAccessNode.Create(ABase, AMember);
|
|
end;
|
|
|
|
class function TAst.Nop: IAstNode;
|
|
begin
|
|
// Factory function for the new Nop node
|
|
Result := TNopNode.Create;
|
|
end;
|
|
|
|
class function TAst.Quasiquote(const AExpression: IAstNode): IQuasiquoteNode;
|
|
begin
|
|
Result := TQuasiquoteNode.Create(AExpression);
|
|
end;
|
|
|
|
class function TAst.Recur(const AArguments: array of IAstNode): IRecurNode;
|
|
begin
|
|
var args: TArray<IAstNode>;
|
|
SetLength(args, Length(AArguments));
|
|
for var i := 0 to High(AArguments) do
|
|
args[i] := AArguments[i];
|
|
Result := TRecurNode.Create(args);
|
|
end;
|
|
|
|
class function TAst.RecordLiteral(const AFields: TArray<TRecordFieldLiteral>): IRecordLiteralNode;
|
|
begin
|
|
// By default, the parser creates the generic (most flexible) node type.
|
|
// The TypeChecker (Phase 3) is responsible for "lowering" this to a
|
|
// TRecordLiteralNode if it determines all fields are scalar.
|
|
Result := TGenericRecordLiteralNode.Create(AFields);
|
|
end;
|
|
|
|
class function TAst.TernaryExpr(const ACondition: IAstNode; const AThenBranch, AElseBranch: IAstNode): ITernaryExpressionNode;
|
|
begin
|
|
Result := TTernaryExpressionNode.Create(ACondition, AThenBranch, AElseBranch);
|
|
end;
|
|
|
|
class function TAst.UnaryExpr(const AOperator: TScalar.TUnaryOp; const ARight: IAstNode): IUnaryExpressionNode;
|
|
begin
|
|
Result := TUnaryExpressionNode.Create(AOperator, ARight);
|
|
end;
|
|
|
|
class function TAst.Unquote(const AExpression: IAstNode): IUnquoteNode;
|
|
begin
|
|
Result := TUnquoteNode.Create(AExpression);
|
|
end;
|
|
|
|
class function TAst.UnquoteSplicing(const AExpression: IQuasiquoteNode): IUnquoteSplicingNode;
|
|
begin
|
|
Result := TUnquoteSplicingNode.Create(AExpression);
|
|
end;
|
|
|
|
class function TAst.VarDecl(const AIdentifier: IIdentifierNode; AInitializer: IAstNode = nil): IVariableDeclarationNode;
|
|
begin
|
|
Result := TVariableDeclarationNode.Create(AIdentifier, AInitializer);
|
|
end;
|
|
|
|
{ TNopNode }
|
|
|
|
constructor TNopNode.Create;
|
|
begin
|
|
inherited Create;
|
|
// Nop nodes are 'Void' by default, though TypeChecker will reject them anyway.
|
|
StaticType := TTypes.Void;
|
|
end;
|
|
|
|
function TNopNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitNop(Self);
|
|
end;
|
|
|
|
function TNopNode.AsNop: INopNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TNopNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akNop;
|
|
end;
|
|
|
|
{ TAstNode }
|
|
|
|
constructor TAstNode.Create;
|
|
begin
|
|
inherited Create;
|
|
FStaticType := TTypes.Unknown; // Default
|
|
end;
|
|
|
|
function TAstNode.AsAddSeriesItem: IAddSeriesItemNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not an AddSeriesItem');
|
|
end;
|
|
|
|
function TAstNode.AsAssignment: IAssignmentNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not an Assignment');
|
|
end;
|
|
|
|
function TAstNode.AsBinaryExpression: IBinaryExpressionNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a BinaryExpression');
|
|
end;
|
|
|
|
function TAstNode.AsBlockExpression: IBlockExpressionNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a BlockExpression');
|
|
end;
|
|
|
|
function TAstNode.AsBoundIdentifierNode: IBoundIdentifierNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a bound identifier');
|
|
end;
|
|
|
|
function TAstNode.AsConstant: IConstantNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a Constant');
|
|
end;
|
|
|
|
function TAstNode.AsCreateSeries: ICreateSeriesNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a CreateSeries');
|
|
end;
|
|
|
|
function TAstNode.AsFunctionCall: IFunctionCallNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a FunctionCall');
|
|
end;
|
|
|
|
function TAstNode.AsIdentifier: IIdentifierNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not an Identifier');
|
|
end;
|
|
|
|
function TAstNode.AsIfExpression: IIfExpressionNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not an IfExpression');
|
|
end;
|
|
|
|
function TAstNode.AsIndexer: IIndexerNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not an Indexer');
|
|
end;
|
|
|
|
function TAstNode.AsKeyword: IKeywordNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a Keyword');
|
|
end;
|
|
|
|
function TAstNode.AsLambdaExpression: ILambdaExpressionNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a LambdaExpression');
|
|
end;
|
|
|
|
function TAstNode.AsMacroDefinition: IMacroDefinitionNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a MacroDefinition');
|
|
end;
|
|
|
|
function TAstNode.AsMacroExpansion: IMacroExpansionNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a MacroExpansion');
|
|
end;
|
|
|
|
function TAstNode.AsMemberAccess: IMemberAccessNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a MemberAccess');
|
|
end;
|
|
|
|
function TAstNode.AsNop: INopNode;
|
|
begin
|
|
// Added Nop implementation
|
|
raise ETypeException.Create('Node is not a Nop');
|
|
end;
|
|
|
|
function TAstNode.AsQuasiquote: IQuasiquoteNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a Quasiquote');
|
|
end;
|
|
|
|
function TAstNode.AsRecordLiteral: IRecordLiteralNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a RecordLiteral');
|
|
end;
|
|
|
|
function TAstNode.AsRecur: IRecurNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a Recur');
|
|
end;
|
|
|
|
function TAstNode.AsSeriesLength: ISeriesLengthNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a SeriesLength');
|
|
end;
|
|
|
|
function TAstNode.AsTernaryExpression: ITernaryExpressionNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a TernaryExpression');
|
|
end;
|
|
|
|
function TAstNode.AsUnaryExpression: IUnaryExpressionNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not an UnaryExpression');
|
|
end;
|
|
|
|
function TAstNode.AsUnquote: IUnquoteNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not an Unquote');
|
|
end;
|
|
|
|
function TAstNode.AsUnquoteSplicing: IUnquoteSplicingNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not an UnquoteSplicing');
|
|
end;
|
|
|
|
function TAstNode.AsVariableDeclaration: IVariableDeclarationNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a VariableDeclaration');
|
|
end;
|
|
|
|
procedure TAstNode.SetStaticType(const AValue: IStaticType);
|
|
begin
|
|
FStaticType := AValue;
|
|
end;
|
|
|
|
{ TConstantNode }
|
|
|
|
constructor TConstantNode.Create(const AValue: TDataValue);
|
|
begin
|
|
inherited Create;
|
|
FValue := AValue;
|
|
end;
|
|
|
|
function TConstantNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitConstant(Self);
|
|
end;
|
|
|
|
function TConstantNode.AsConstant: IConstantNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TConstantNode.GetValue: TDataValue;
|
|
begin
|
|
Result := FValue;
|
|
end;
|
|
|
|
function TConstantNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akConstant;
|
|
end;
|
|
|
|
{ TIdentifierNode }
|
|
|
|
constructor TIdentifierNode.Create(const AName: string);
|
|
begin
|
|
inherited Create;
|
|
FName := AName;
|
|
end;
|
|
|
|
function TIdentifierNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitIdentifier(Self);
|
|
end;
|
|
|
|
function TIdentifierNode.AsIdentifier: IIdentifierNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TIdentifierNode.GetName: string;
|
|
begin
|
|
Result := FName;
|
|
end;
|
|
|
|
function TIdentifierNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akIdentifier;
|
|
end;
|
|
|
|
{ TKeywordNode }
|
|
|
|
constructor TKeywordNode.Create(const AValue: IKeyword);
|
|
begin
|
|
inherited Create;
|
|
FValue := AValue;
|
|
end;
|
|
|
|
function TKeywordNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitKeyword(Self);
|
|
end;
|
|
|
|
function TKeywordNode.AsKeyword: IKeywordNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TKeywordNode.GetValue: IKeyword;
|
|
begin
|
|
Result := FValue;
|
|
end;
|
|
|
|
function TKeywordNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akKeyword;
|
|
end;
|
|
|
|
{ TBinaryExpressionNode }
|
|
|
|
constructor TBinaryExpressionNode.Create(const ALeft: IAstNode; AOperator: TScalar.TBinaryOp; const ARight: IAstNode);
|
|
begin
|
|
inherited Create;
|
|
FLeft := ALeft;
|
|
FOperator := AOperator;
|
|
FRight := ARight;
|
|
end;
|
|
|
|
function TBinaryExpressionNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitBinaryExpression(Self);
|
|
end;
|
|
|
|
function TBinaryExpressionNode.AsBinaryExpression: IBinaryExpressionNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TBinaryExpressionNode.GetLeft: IAstNode;
|
|
begin
|
|
Result := FLeft;
|
|
end;
|
|
|
|
function TBinaryExpressionNode.GetOperator: TScalar.TBinaryOp;
|
|
begin
|
|
Result := FOperator;
|
|
end;
|
|
|
|
function TBinaryExpressionNode.GetRight: IAstNode;
|
|
begin
|
|
Result := FRight;
|
|
end;
|
|
|
|
function TBinaryExpressionNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akBinaryExpression;
|
|
end;
|
|
|
|
{ TUnaryExpressionNode }
|
|
|
|
constructor TUnaryExpressionNode.Create(const AOperator: TScalar.TUnaryOp; const ARight: IAstNode);
|
|
begin
|
|
inherited Create;
|
|
FOperator := AOperator;
|
|
FRight := ARight;
|
|
end;
|
|
|
|
function TUnaryExpressionNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitUnaryExpression(Self);
|
|
end;
|
|
|
|
function TUnaryExpressionNode.AsUnaryExpression: IUnaryExpressionNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TUnaryExpressionNode.GetOperator: TScalar.TUnaryOp;
|
|
begin
|
|
Result := FOperator;
|
|
end;
|
|
|
|
function TUnaryExpressionNode.GetRight: IAstNode;
|
|
begin
|
|
Result := FRight;
|
|
end;
|
|
|
|
function TUnaryExpressionNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akUnaryExpression;
|
|
end;
|
|
|
|
{ TIfExpressionNode }
|
|
|
|
constructor TIfExpressionNode.Create(const ACondition, AThenBranch, AElseBranch: IAstNode);
|
|
begin
|
|
inherited Create;
|
|
FCondition := ACondition;
|
|
FThenBranch := AThenBranch;
|
|
FElseBranch := AElseBranch;
|
|
end;
|
|
|
|
function TIfExpressionNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitIfExpression(Self);
|
|
end;
|
|
|
|
function TIfExpressionNode.AsIfExpression: IIfExpressionNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TIfExpressionNode.GetCondition: IAstNode;
|
|
begin
|
|
Result := FCondition;
|
|
end;
|
|
|
|
function TIfExpressionNode.GetElseBranch: IAstNode;
|
|
begin
|
|
Result := FElseBranch;
|
|
end;
|
|
|
|
function TIfExpressionNode.GetThenBranch: IAstNode;
|
|
begin
|
|
Result := FThenBranch;
|
|
end;
|
|
|
|
function TIfExpressionNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akIfExpression;
|
|
end;
|
|
|
|
{ TTernaryExpressionNode }
|
|
|
|
constructor TTernaryExpressionNode.Create(const ACondition, AThenBranch, AElseBranch: IAstNode);
|
|
begin
|
|
inherited Create;
|
|
FCondition := ACondition;
|
|
FThenBranch := AThenBranch;
|
|
FElseBranch := AElseBranch;
|
|
end;
|
|
|
|
function TTernaryExpressionNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitTernaryExpression(Self);
|
|
end;
|
|
|
|
function TTernaryExpressionNode.AsTernaryExpression: ITernaryExpressionNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TTernaryExpressionNode.GetCondition: IAstNode;
|
|
begin
|
|
Result := FCondition;
|
|
end;
|
|
|
|
function TTernaryExpressionNode.GetElseBranch: IAstNode;
|
|
begin
|
|
Result := FElseBranch;
|
|
end;
|
|
|
|
function TTernaryExpressionNode.GetThenBranch: IAstNode;
|
|
begin
|
|
Result := FThenBranch;
|
|
end;
|
|
|
|
function TTernaryExpressionNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akTernaryExpression;
|
|
end;
|
|
|
|
{ TLambdaExpressionNode }
|
|
|
|
constructor TLambdaExpressionNode.Create(const AParameters: TArray<IIdentifierNode>; const ABody: IAstNode);
|
|
begin
|
|
inherited Create;
|
|
FParameters := AParameters;
|
|
FBody := ABody;
|
|
end;
|
|
|
|
destructor TLambdaExpressionNode.Destroy;
|
|
begin
|
|
// FScopeDescriptor is an interface, managed by ARC
|
|
inherited;
|
|
end;
|
|
|
|
function TLambdaExpressionNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitLambdaExpression(Self);
|
|
end;
|
|
|
|
function TLambdaExpressionNode.AsLambdaExpression: ILambdaExpressionNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TLambdaExpressionNode.GetBody: IAstNode;
|
|
begin
|
|
Result := FBody;
|
|
end;
|
|
|
|
function TLambdaExpressionNode.GetParameters: TArray<IIdentifierNode>;
|
|
begin
|
|
Result := FParameters;
|
|
end;
|
|
|
|
function TLambdaExpressionNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akLambdaExpression;
|
|
end;
|
|
|
|
{ TMacroDefinitionNode }
|
|
|
|
constructor TMacroDefinitionNode.Create(const AName: IIdentifierNode; const AParameters: TArray<IIdentifierNode>; const ABody: IAstNode);
|
|
begin
|
|
inherited Create;
|
|
FName := AName;
|
|
FParameters := AParameters;
|
|
FBody := ABody;
|
|
end;
|
|
|
|
function TMacroDefinitionNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitMacroDefinition(Self);
|
|
end;
|
|
|
|
function TMacroDefinitionNode.AsMacroDefinition: IMacroDefinitionNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TMacroDefinitionNode.GetBody: IAstNode;
|
|
begin
|
|
Result := FBody;
|
|
end;
|
|
|
|
function TMacroDefinitionNode.GetName: IIdentifierNode;
|
|
begin
|
|
Result := FName;
|
|
end;
|
|
|
|
function TMacroDefinitionNode.GetParameters: TArray<IIdentifierNode>;
|
|
begin
|
|
Result := FParameters;
|
|
end;
|
|
|
|
function TMacroDefinitionNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akMacroDefinition;
|
|
end;
|
|
|
|
{ TQuasiquoteNode }
|
|
|
|
constructor TQuasiquoteNode.Create(const AExpression: IAstNode);
|
|
begin
|
|
inherited Create;
|
|
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);
|
|
begin
|
|
inherited Create;
|
|
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);
|
|
begin
|
|
inherited Create;
|
|
FExpression := AExpression;
|
|
end;
|
|
|
|
function TUnquoteSplicingNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitUnquoteSplicing(Self);
|
|
end;
|
|
|
|
function TUnquoteSplicingNode.AsUnquoteSplicing: IUnquoteSplicingNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TUnquoteSplicingNode.GetExpression: IQuasiquoteNode;
|
|
begin
|
|
Result := FExpression;
|
|
end;
|
|
|
|
function TUnquoteSplicingNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akUnquoteSplicing;
|
|
end;
|
|
|
|
{ TFunctionCallNode }
|
|
|
|
constructor TFunctionCallNode.Create(const ACallee: IAstNode; const AArguments: TArray<IAstNode>);
|
|
begin
|
|
inherited Create;
|
|
FCallee := ACallee;
|
|
FArguments := AArguments;
|
|
FIsTailCall := False;
|
|
end;
|
|
|
|
function TFunctionCallNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitFunctionCall(Self);
|
|
end;
|
|
|
|
function TFunctionCallNode.AsFunctionCall: IFunctionCallNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TFunctionCallNode.GetArguments: TArray<IAstNode>;
|
|
begin
|
|
Result := FArguments;
|
|
end;
|
|
|
|
function TFunctionCallNode.GetCallee: IAstNode;
|
|
begin
|
|
Result := FCallee;
|
|
end;
|
|
|
|
function TFunctionCallNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akFunctionCall;
|
|
end;
|
|
|
|
{ TMacroExpansionNode }
|
|
|
|
constructor TMacroExpansionNode.Create(const AOriginalCallNode: IFunctionCallNode; const AExpandedBody: IAstNode);
|
|
begin
|
|
// Copy properties from the original call node
|
|
inherited Create(AOriginalCallNode.Callee, AOriginalCallNode.Arguments);
|
|
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.GetExpandedBody: IAstNode;
|
|
begin
|
|
Result := FExpandedBody;
|
|
end;
|
|
|
|
function TMacroExpansionNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akMacroExpansion;
|
|
end;
|
|
|
|
{ TRecurNode }
|
|
|
|
constructor TRecurNode.Create(const AArguments: TArray<IAstNode>);
|
|
begin
|
|
inherited Create;
|
|
FArguments := AArguments;
|
|
end;
|
|
|
|
function TRecurNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitRecurNode(Self);
|
|
end;
|
|
|
|
function TRecurNode.AsRecur: IRecurNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TRecurNode.GetArguments: TArray<IAstNode>;
|
|
begin
|
|
Result := FArguments;
|
|
end;
|
|
|
|
function TRecurNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akRecur;
|
|
end;
|
|
|
|
{ TBlockExpressionNode }
|
|
|
|
constructor TBlockExpressionNode.Create(const AExpressions: array of IAstNode);
|
|
var
|
|
i: Integer;
|
|
begin
|
|
inherited Create;
|
|
SetLength(FExpressions, Length(AExpressions));
|
|
for i := 0 to High(AExpressions) do
|
|
FExpressions[i] := AExpressions[i];
|
|
end;
|
|
|
|
function TBlockExpressionNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitBlockExpression(Self);
|
|
end;
|
|
|
|
function TBlockExpressionNode.AsBlockExpression: IBlockExpressionNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TBlockExpressionNode.GetExpressions: TArray<IAstNode>;
|
|
begin
|
|
Result := FExpressions;
|
|
end;
|
|
|
|
function TBlockExpressionNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akBlockExpression;
|
|
end;
|
|
|
|
{ TVariableDeclarationNode }
|
|
|
|
constructor TVariableDeclarationNode.Create(const AIdentifier: IIdentifierNode; AInitializer: IAstNode);
|
|
begin
|
|
inherited Create;
|
|
FIdentifier := AIdentifier;
|
|
FInitializer := AInitializer;
|
|
FIsBoxed := False;
|
|
end;
|
|
|
|
function TVariableDeclarationNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitVariableDeclaration(Self);
|
|
end;
|
|
|
|
function TVariableDeclarationNode.AsVariableDeclaration: IVariableDeclarationNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TVariableDeclarationNode.GetIdentifier: IIdentifierNode;
|
|
begin
|
|
Result := FIdentifier;
|
|
end;
|
|
|
|
function TVariableDeclarationNode.GetInitializer: IAstNode;
|
|
begin
|
|
Result := FInitializer;
|
|
end;
|
|
|
|
function TVariableDeclarationNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akVariableDeclaration;
|
|
end;
|
|
|
|
{ TAssignmentNode }
|
|
|
|
constructor TAssignmentNode.Create(const AIdentifier: IIdentifierNode; const AValue: IAstNode);
|
|
begin
|
|
inherited Create;
|
|
FIdentifier := AIdentifier;
|
|
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.GetIdentifier: IIdentifierNode;
|
|
begin
|
|
Result := FIdentifier;
|
|
end;
|
|
|
|
function TAssignmentNode.GetValue: IAstNode;
|
|
begin
|
|
Result := FValue;
|
|
end;
|
|
|
|
function TAssignmentNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akAssignment;
|
|
end;
|
|
|
|
{ TIndexerNode }
|
|
|
|
constructor TIndexerNode.Create(const ABase: IAstNode; const AIndex: IAstNode);
|
|
begin
|
|
inherited Create;
|
|
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);
|
|
begin
|
|
inherited Create;
|
|
FBase := ABase;
|
|
FMember := AMember;
|
|
end;
|
|
|
|
function TMemberAccessNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitMemberAccess(Self);
|
|
end;
|
|
|
|
function TMemberAccessNode.AsMemberAccess: IMemberAccessNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TMemberAccessNode.GetBase: IAstNode;
|
|
begin
|
|
Result := FBase;
|
|
end;
|
|
|
|
function TMemberAccessNode.GetMember: IKeywordNode;
|
|
begin
|
|
Result := FMember;
|
|
end;
|
|
|
|
function TMemberAccessNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akMemberAccess;
|
|
end;
|
|
|
|
{ TRecordLiteralNode }
|
|
|
|
constructor TRecordLiteralNode.Create(const AFields: TArray<TRecordFieldLiteral>);
|
|
begin
|
|
inherited Create;
|
|
FFields := AFields;
|
|
end;
|
|
|
|
function TRecordLiteralNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitRecordLiteral(Self);
|
|
end;
|
|
|
|
function TRecordLiteralNode.AsRecordLiteral: IRecordLiteralNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TRecordLiteralNode.GetFields: TArray<TRecordFieldLiteral>;
|
|
begin
|
|
Result := FFields;
|
|
end;
|
|
|
|
function TRecordLiteralNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akRecordLiteral;
|
|
end;
|
|
|
|
{ TGenericRecordLiteralNode }
|
|
|
|
constructor TGenericRecordLiteralNode.Create(const AFields: TArray<TRecordFieldLiteral>);
|
|
begin
|
|
inherited Create(AFields);
|
|
end;
|
|
|
|
{ TCreateSeriesNode }
|
|
|
|
constructor TCreateSeriesNode.Create(const ADefinition: String);
|
|
begin
|
|
inherited Create;
|
|
FDefinition := ADefinition;
|
|
end;
|
|
|
|
function TCreateSeriesNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitCreateSeries(Self);
|
|
end;
|
|
|
|
function TCreateSeriesNode.AsCreateSeries: ICreateSeriesNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TCreateSeriesNode.GetDefinition: String;
|
|
begin
|
|
Result := FDefinition;
|
|
end;
|
|
|
|
function TCreateSeriesNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akCreateSeries;
|
|
end;
|
|
|
|
{ TAddSeriesItemNode }
|
|
|
|
constructor TAddSeriesItemNode.Create(const ASeries: IIdentifierNode; const AValue: IAstNode; const ALookback: IAstNode);
|
|
begin
|
|
inherited Create;
|
|
FSeries := ASeries;
|
|
FValue := AValue;
|
|
FLookback := ALookback;
|
|
end;
|
|
|
|
function TAddSeriesItemNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitAddSeriesItem(Self);
|
|
end;
|
|
|
|
function TAddSeriesItemNode.AsAddSeriesItem: IAddSeriesItemNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TAddSeriesItemNode.GetLookback: IAstNode;
|
|
begin
|
|
Result := FLookback;
|
|
end;
|
|
|
|
function TAddSeriesItemNode.GetSeries: IIdentifierNode;
|
|
begin
|
|
Result := FSeries;
|
|
end;
|
|
|
|
function TAddSeriesItemNode.GetValue: IAstNode;
|
|
begin
|
|
Result := FValue;
|
|
end;
|
|
|
|
function TAddSeriesItemNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akAddSeriesItem;
|
|
end;
|
|
|
|
{ TSeriesLengthNode }
|
|
|
|
constructor TSeriesLengthNode.Create(const ASeries: IIdentifierNode);
|
|
begin
|
|
inherited Create;
|
|
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;
|
|
|
|
{ TBoundIdentifierNode }
|
|
|
|
constructor TBoundIdentifierNode.Create(const AName: string; const AAddress: TResolvedAddress);
|
|
begin
|
|
inherited Create(AName);
|
|
FAddress := AAddress;
|
|
end;
|
|
|
|
function TBoundIdentifierNode.AsBoundIdentifierNode: IBoundIdentifierNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TBoundIdentifierNode.GetAddress: TResolvedAddress;
|
|
begin
|
|
Result := FAddress;
|
|
end;
|
|
|
|
function TBoundIdentifierNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akBoundIdentifier;
|
|
end;
|
|
|
|
end.
|