Files
MycLib/Src/AST/Myc.Ast.pas
T
Michael Schimmel a052dfb20f AST testing
2025-11-23 00:24:43 +01:00

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