837 lines
24 KiB
ObjectPascal
837 lines
24 KiB
ObjectPascal
unit Myc.Ast;
|
|
|
|
interface
|
|
|
|
uses
|
|
System.Classes,
|
|
System.SysUtils,
|
|
System.Generics.Collections,
|
|
System.Generics.Defaults,
|
|
Myc.Data.Scalar,
|
|
Myc.Data.Value,
|
|
Myc.Ast.Nodes,
|
|
Myc.Ast.Scope;
|
|
|
|
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;
|
|
|
|
// --- Existing factory functions ---
|
|
class function Constant(AValue: TScalar): IConstantNode; static;
|
|
class function Identifier(AName: string): IIdentifierNode; static;
|
|
class function BinaryExpr(ALeft: IAstNode; AOperator: TBinaryOperator; ARight: IAstNode): IBinaryExpressionNode; static;
|
|
class function UnaryExpr(const AOperator: TUnaryOperator; 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 FunctionCall(const ACallee: IAstNode; const AArguments: TArray<IAstNode>): IFunctionCallNode; 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: IIdentifierNode): IMemberAccessNode; 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)
|
|
public
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; virtual; abstract;
|
|
end;
|
|
|
|
TConstantNode = class(TAstNode, IConstantNode)
|
|
private
|
|
FValue: TScalar;
|
|
function GetValue: TScalar;
|
|
public
|
|
constructor Create(AValue: TScalar);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
end;
|
|
|
|
TIdentifierNode = class(TAstNode, IIdentifierNode)
|
|
private
|
|
FName: string;
|
|
// --- Annotation fields added for the binder ---
|
|
FResolvedAddress: TResolvedAddress;
|
|
function GetName: string;
|
|
function GetAddress: TResolvedAddress; inline;
|
|
public
|
|
constructor Create(AName: string);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
property Name: string read FName;
|
|
property Address: TResolvedAddress read FResolvedAddress write FResolvedAddress;
|
|
end;
|
|
|
|
TBinaryExpressionNode = class(TAstNode, IBinaryExpressionNode)
|
|
private
|
|
FLeft: IAstNode;
|
|
FOperator: TBinaryOperator;
|
|
FRight: IAstNode;
|
|
function GetLeft: IAstNode;
|
|
function GetOperator: TBinaryOperator;
|
|
function GetRight: IAstNode;
|
|
public
|
|
constructor Create(ALeft: IAstNode; AOperator: TBinaryOperator; ARight: IAstNode);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
end;
|
|
|
|
TUnaryExpressionNode = class(TAstNode, IUnaryExpressionNode)
|
|
private
|
|
FOperator: TUnaryOperator;
|
|
FRight: IAstNode;
|
|
function GetOperator: TUnaryOperator;
|
|
function GetRight: IAstNode;
|
|
public
|
|
constructor Create(const AOperator: TUnaryOperator; const ARight: IAstNode);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
end;
|
|
|
|
TIfExpressionNode = class(TAstNode, IIfExpressionNode)
|
|
private
|
|
FCondition: IAstNode;
|
|
FThenBranch: IAstNode;
|
|
FElseBranch: IAstNode;
|
|
function GetCondition: IAstNode;
|
|
function GetThenBranch: IAstNode;
|
|
function GetElseBranch: IAstNode;
|
|
public
|
|
constructor Create(const ACondition, AThenBranch, AElseBranch: IAstNode);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
end;
|
|
|
|
TTernaryExpressionNode = class(TAstNode, ITernaryExpressionNode)
|
|
private
|
|
FCondition: IAstNode;
|
|
FThenBranch: IAstNode;
|
|
FElseBranch: IAstNode;
|
|
function GetCondition: IAstNode;
|
|
function GetThenBranch: IAstNode;
|
|
function GetElseBranch: IAstNode;
|
|
public
|
|
constructor Create(const ACondition, AThenBranch, AElseBranch: IAstNode);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
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 GetScopeDescriptor: IScopeDescriptor;
|
|
function GetUpvalues: TArray<TResolvedAddress>;
|
|
function GetHasNestedLambdas: Boolean;
|
|
public
|
|
constructor Create(const AParameters: TArray<IIdentifierNode>; const ABody: IAstNode);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
property HasNestedLambdas: Boolean read FHasNestedLambdas write FHasNestedLambdas;
|
|
property ScopeDescriptor: IScopeDescriptor read FScopeDescriptor write FScopeDescriptor;
|
|
property Upvalues: TArray<TResolvedAddress> read FUpvalues write FUpvalues;
|
|
end;
|
|
|
|
TFunctionCallNode = class(TAstNode, IFunctionCallNode)
|
|
private
|
|
FCallee: IAstNode;
|
|
FArguments: TArray<IAstNode>;
|
|
FIsTailCall: Boolean;
|
|
function GetCallee: IAstNode;
|
|
function GetArguments: TArray<IAstNode>;
|
|
function GetIsTailCall: Boolean;
|
|
public
|
|
constructor Create(const ACallee: IAstNode; const AArguments: TArray<IAstNode>);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
property IsTailCall: Boolean read FIsTailCall write FIsTailCall;
|
|
end;
|
|
|
|
TRecurNode = class(TAstNode, IRecurNode)
|
|
private
|
|
FArguments: TArray<IAstNode>;
|
|
FIsTailCall: Boolean;
|
|
function GetArguments: TArray<IAstNode>;
|
|
function GetIsTailCall: Boolean;
|
|
public
|
|
constructor Create(const AArguments: TArray<IAstNode>);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
property IsTailCall: Boolean read FIsTailCall write FIsTailCall;
|
|
end;
|
|
|
|
TBlockExpressionNode = class(TAstNode, IBlockExpressionNode)
|
|
private
|
|
FExpressions: TList<IAstNode>;
|
|
function GetExpressions: TList<IAstNode>;
|
|
public
|
|
constructor Create(const AExpressions: array of IAstNode);
|
|
destructor Destroy; override;
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
end;
|
|
|
|
TVariableDeclarationNode = class(TAstNode, IVariableDeclarationNode)
|
|
private
|
|
FIdentifier: IIdentifierNode;
|
|
FInitializer: IAstNode;
|
|
function GetIdentifier: IIdentifierNode;
|
|
function GetInitializer: IAstNode;
|
|
public
|
|
constructor Create(const AIdentifier: IIdentifierNode; AInitializer: IAstNode);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
end;
|
|
|
|
TAssignmentNode = class(TAstNode, IAssignmentNode)
|
|
private
|
|
FIdentifier: IIdentifierNode;
|
|
FValue: IAstNode;
|
|
function GetIdentifier: IIdentifierNode;
|
|
function GetValue: IAstNode;
|
|
public
|
|
constructor Create(const AIdentifier: IIdentifierNode; const AValue: IAstNode);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
end;
|
|
|
|
TIndexerNode = class(TAstNode, IIndexerNode)
|
|
private
|
|
FBase: IAstNode;
|
|
FIndex: IAstNode;
|
|
function GetBase: IAstNode;
|
|
function GetIndex: IAstNode;
|
|
public
|
|
constructor Create(const ABase: IAstNode; const AIndex: IAstNode);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
end;
|
|
|
|
TMemberAccessNode = class(TAstNode, IMemberAccessNode)
|
|
private
|
|
FBase: IAstNode;
|
|
FMember: IIdentifierNode;
|
|
function GetBase: IAstNode;
|
|
function GetMember: IIdentifierNode;
|
|
public
|
|
constructor Create(const ABase: IAstNode; const AMember: IIdentifierNode);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
end;
|
|
|
|
TCreateSeriesNode = class(TAstNode, ICreateSeriesNode)
|
|
private
|
|
FDefinition: String;
|
|
function GetDefinition: String;
|
|
public
|
|
constructor Create(const ADefinition: String);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
end;
|
|
|
|
TAddSeriesItemNode = class(TAstNode, IAddSeriesItemNode)
|
|
private
|
|
FSeries: IIdentifierNode;
|
|
FValue: IAstNode;
|
|
FLookback: IAstNode;
|
|
function GetSeries: IIdentifierNode;
|
|
function GetValue: IAstNode;
|
|
function GetLookback: IAstNode;
|
|
public
|
|
constructor Create(const ASeries: IIdentifierNode; const AValue: IAstNode; const ALookback: IAstNode);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
end;
|
|
|
|
TSeriesLengthNode = class(TAstNode, ISeriesLengthNode)
|
|
private
|
|
FSeries: IIdentifierNode;
|
|
function GetSeries: IIdentifierNode;
|
|
public
|
|
constructor Create(const ASeries: IIdentifierNode);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
Myc.Ast.Traverser;
|
|
|
|
{ TConstantNode }
|
|
|
|
constructor TConstantNode.Create(AValue: TScalar);
|
|
begin
|
|
inherited Create;
|
|
FValue := AValue;
|
|
end;
|
|
|
|
function TConstantNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitConstant(Self);
|
|
end;
|
|
|
|
function TConstantNode.GetValue: TScalar;
|
|
begin
|
|
Result := FValue;
|
|
end;
|
|
|
|
{ TIdentifierNode }
|
|
|
|
constructor TIdentifierNode.Create(AName: string);
|
|
begin
|
|
inherited Create;
|
|
FName := AName;
|
|
end;
|
|
|
|
function TIdentifierNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitIdentifier(Self);
|
|
end;
|
|
|
|
function TIdentifierNode.GetName: string;
|
|
begin
|
|
Result := FName;
|
|
end;
|
|
|
|
function TIdentifierNode.GetAddress: TResolvedAddress;
|
|
begin
|
|
Result := FResolvedAddress;
|
|
end;
|
|
|
|
{ TBinaryExpressionNode }
|
|
|
|
constructor TBinaryExpressionNode.Create(ALeft: IAstNode; AOperator: TBinaryOperator; 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.GetLeft: IAstNode;
|
|
begin
|
|
Result := FLeft;
|
|
end;
|
|
|
|
function TBinaryExpressionNode.GetOperator: TBinaryOperator;
|
|
begin
|
|
Result := FOperator;
|
|
end;
|
|
|
|
function TBinaryExpressionNode.GetRight: IAstNode;
|
|
begin
|
|
Result := FRight;
|
|
end;
|
|
|
|
{ TUnaryExpressionNode }
|
|
|
|
constructor TUnaryExpressionNode.Create(const AOperator: TUnaryOperator; 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.GetOperator: TUnaryOperator;
|
|
begin
|
|
Result := FOperator;
|
|
end;
|
|
|
|
function TUnaryExpressionNode.GetRight: IAstNode;
|
|
begin
|
|
Result := FRight;
|
|
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.GetCondition: IAstNode;
|
|
begin
|
|
Result := FCondition;
|
|
end;
|
|
|
|
function TIfExpressionNode.GetElseBranch: IAstNode;
|
|
begin
|
|
Result := FElseBranch;
|
|
end;
|
|
|
|
function TIfExpressionNode.GetThenBranch: IAstNode;
|
|
begin
|
|
Result := FThenBranch;
|
|
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.GetCondition: IAstNode;
|
|
begin
|
|
Result := FCondition;
|
|
end;
|
|
|
|
function TTernaryExpressionNode.GetElseBranch: IAstNode;
|
|
begin
|
|
Result := FElseBranch;
|
|
end;
|
|
|
|
function TTernaryExpressionNode.GetThenBranch: IAstNode;
|
|
begin
|
|
Result := FThenBranch;
|
|
end;
|
|
|
|
{ TLambdaExpressionNode }
|
|
|
|
constructor TLambdaExpressionNode.Create(const AParameters: TArray<IIdentifierNode>; const ABody: IAstNode);
|
|
begin
|
|
inherited Create;
|
|
FBody := ABody;
|
|
FParameters := AParameters;
|
|
FScopeDescriptor := nil;
|
|
end;
|
|
|
|
function TLambdaExpressionNode.GetUpvalues: TArray<TResolvedAddress>;
|
|
begin
|
|
Result := FUpvalues;
|
|
end;
|
|
|
|
function TLambdaExpressionNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitLambdaExpression(Self);
|
|
end;
|
|
|
|
function TLambdaExpressionNode.GetBody: IAstNode;
|
|
begin
|
|
Result := FBody;
|
|
end;
|
|
|
|
function TLambdaExpressionNode.GetHasNestedLambdas: Boolean;
|
|
begin
|
|
Result := FHasNestedLambdas;
|
|
end;
|
|
|
|
function TLambdaExpressionNode.GetParameters: TArray<IIdentifierNode>;
|
|
begin
|
|
Result := FParameters;
|
|
end;
|
|
|
|
function TLambdaExpressionNode.GetScopeDescriptor: IScopeDescriptor;
|
|
begin
|
|
Result := FScopeDescriptor;
|
|
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.GetArguments: TArray<IAstNode>;
|
|
begin
|
|
Result := FArguments;
|
|
end;
|
|
|
|
function TFunctionCallNode.GetCallee: IAstNode;
|
|
begin
|
|
Result := FCallee;
|
|
end;
|
|
|
|
function TFunctionCallNode.GetIsTailCall: Boolean;
|
|
begin
|
|
Result := FIsTailCall;
|
|
end;
|
|
|
|
{ TRecurNode }
|
|
|
|
constructor TRecurNode.Create(const AArguments: TArray<IAstNode>);
|
|
begin
|
|
inherited Create;
|
|
FArguments := AArguments;
|
|
FIsTailCall := True;
|
|
end;
|
|
|
|
function TRecurNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitRecurNode(Self);
|
|
end;
|
|
|
|
function TRecurNode.GetArguments: TArray<IAstNode>;
|
|
begin
|
|
Result := FArguments;
|
|
end;
|
|
|
|
function TRecurNode.GetIsTailCall: Boolean;
|
|
begin
|
|
Result := FIsTailCall;
|
|
end;
|
|
|
|
{ TBlockExpressionNode }
|
|
|
|
constructor TBlockExpressionNode.Create(const AExpressions: array of IAstNode);
|
|
var
|
|
expr: IAstNode;
|
|
begin
|
|
inherited Create;
|
|
FExpressions := TList<IAstNode>.Create;
|
|
for expr in AExpressions do
|
|
FExpressions.Add(expr);
|
|
end;
|
|
|
|
destructor TBlockExpressionNode.Destroy;
|
|
begin
|
|
FExpressions.Free;
|
|
inherited;
|
|
end;
|
|
|
|
function TBlockExpressionNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitBlockExpression(Self);
|
|
end;
|
|
|
|
function TBlockExpressionNode.GetExpressions: TList<IAstNode>;
|
|
begin
|
|
Result := FExpressions;
|
|
end;
|
|
|
|
{ TVariableDeclarationNode }
|
|
|
|
constructor TVariableDeclarationNode.Create(const AIdentifier: IIdentifierNode; AInitializer: IAstNode);
|
|
begin
|
|
inherited Create;
|
|
FIdentifier := AIdentifier;
|
|
FInitializer := AInitializer;
|
|
end;
|
|
|
|
function TVariableDeclarationNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitVariableDeclaration(Self);
|
|
end;
|
|
|
|
function TVariableDeclarationNode.GetIdentifier: IIdentifierNode;
|
|
begin
|
|
Result := FIdentifier;
|
|
end;
|
|
|
|
function TVariableDeclarationNode.GetInitializer: IAstNode;
|
|
begin
|
|
Result := FInitializer;
|
|
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.GetIdentifier: IIdentifierNode;
|
|
begin
|
|
Result := FIdentifier;
|
|
end;
|
|
|
|
function TAssignmentNode.GetValue: IAstNode;
|
|
begin
|
|
Result := FValue;
|
|
end;
|
|
|
|
{ TIndexerNode }
|
|
|
|
constructor TIndexerNode.Create(const ABase, 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.GetBase: IAstNode;
|
|
begin
|
|
Result := FBase;
|
|
end;
|
|
|
|
function TIndexerNode.GetIndex: IAstNode;
|
|
begin
|
|
Result := FIndex;
|
|
end;
|
|
|
|
{ TMemberAccessNode }
|
|
|
|
constructor TMemberAccessNode.Create(const ABase: IAstNode; const AMember: IIdentifierNode);
|
|
begin
|
|
inherited Create;
|
|
FBase := ABase;
|
|
FMember := AMember;
|
|
end;
|
|
|
|
function TMemberAccessNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitMemberAccess(Self);
|
|
end;
|
|
|
|
function TMemberAccessNode.GetBase: IAstNode;
|
|
begin
|
|
Result := FBase;
|
|
end;
|
|
|
|
function TMemberAccessNode.GetMember: IIdentifierNode;
|
|
begin
|
|
Result := FMember;
|
|
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.GetDefinition: String;
|
|
begin
|
|
Result := FDefinition;
|
|
end;
|
|
|
|
{ TAddSeriesItemNode }
|
|
|
|
constructor TAddSeriesItemNode.Create(const ASeries: IIdentifierNode; const AValue, 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.GetLookback: IAstNode;
|
|
begin
|
|
Result := FLookback;
|
|
end;
|
|
|
|
function TAddSeriesItemNode.GetSeries: IIdentifierNode;
|
|
begin
|
|
Result := FSeries;
|
|
end;
|
|
|
|
function TAddSeriesItemNode.GetValue: IAstNode;
|
|
begin
|
|
Result := FValue;
|
|
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.GetSeries: IIdentifierNode;
|
|
begin
|
|
Result := FSeries;
|
|
end;
|
|
|
|
{ TAst }
|
|
|
|
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.AddSeriesItem(const ASeries: IIdentifierNode; const AValue: IAstNode; const ALookback: IAstNode): IAddSeriesItemNode;
|
|
begin
|
|
Result := TAddSeriesItemNode.Create(ASeries, AValue, ALookback);
|
|
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
|
|
Result := Assign(TAst.Identifier('Result'), AValue);
|
|
end;
|
|
|
|
class function TAst.Block(const AExpressions: array of IAstNode): IBlockExpressionNode;
|
|
begin
|
|
Result := TBlockExpressionNode.Create(AExpressions);
|
|
end;
|
|
|
|
class function TAst.Constant(AValue: TScalar): IConstantNode;
|
|
begin
|
|
Result := TConstantNode.Create(AValue);
|
|
end;
|
|
|
|
class function TAst.CreateSeries(const ADefinition: String): ICreateSeriesNode;
|
|
begin
|
|
Result := TCreateSeriesNode.Create(ADefinition);
|
|
end;
|
|
|
|
class function TAst.BinaryExpr(ALeft: IAstNode; AOperator: TBinaryOperator; ARight: IAstNode): IBinaryExpressionNode;
|
|
begin
|
|
Result := TBinaryExpressionNode.Create(ALeft, AOperator, ARight);
|
|
end;
|
|
|
|
class function TAst.CreateScope(Parent: IExecutionScope; const Descriptor: IScopeDescriptor = nil): IExecutionScope;
|
|
var
|
|
proc: TRegisterLibraryProc;
|
|
begin
|
|
Result := TExecutionScope.Create(Parent, Descriptor, nil);
|
|
|
|
if Parent = nil then
|
|
begin
|
|
// When creating a root scope, automatically register all standard libraries.
|
|
for proc in FLibraries do
|
|
proc(Result);
|
|
end;
|
|
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.MemberAccess(const ABase: IAstNode; const AMember: IIdentifierNode): IMemberAccessNode;
|
|
begin
|
|
Result := TMemberAccessNode.Create(ABase, AMember);
|
|
end;
|
|
|
|
class function TAst.Recur(const AArguments: array of IAstNode): IRecurNode;
|
|
var
|
|
args: TArray<IAstNode>;
|
|
i: Integer;
|
|
begin
|
|
SetLength(args, Length(AArguments));
|
|
for i := 0 to High(AArguments) do
|
|
args[i] := AArguments[i];
|
|
Result := TRecurNode.Create(args);
|
|
end;
|
|
|
|
class function TAst.SeriesLength(const ASeries: IIdentifierNode): ISeriesLengthNode;
|
|
begin
|
|
Result := TSeriesLengthNode.Create(ASeries);
|
|
end;
|
|
|
|
class function TAst.TernaryExpr(const ACondition: IAstNode; const AThenBranch, AElseBranch: IAstNode): ITernaryExpressionNode;
|
|
begin
|
|
Result := TTernaryExpressionNode.Create(ACondition, AThenBranch, AElseBranch);
|
|
end;
|
|
|
|
class function TAst.LambdaExpr(const AParameters: TArray<IIdentifierNode>; const ABody: IAstNode): ILambdaExpressionNode;
|
|
begin
|
|
Result := TLambdaExpressionNode.Create(AParameters, ABody);
|
|
end;
|
|
|
|
class function TAst.UnaryExpr(const AOperator: TUnaryOperator; const ARight: IAstNode): IUnaryExpressionNode;
|
|
begin
|
|
Result := TUnaryExpressionNode.Create(AOperator, ARight);
|
|
end;
|
|
|
|
class function TAst.VarDecl(const AIdentifier: IIdentifierNode; AInitializer: IAstNode = nil): IVariableDeclarationNode;
|
|
begin
|
|
Result := TVariableDeclarationNode.Create(AIdentifier, AInitializer);
|
|
end;
|
|
|
|
end.
|