Files
MycLib/Src/AST/Myc.Ast.pas
T
2025-11-05 13:21:17 +01:00

1770 lines
54 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; 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): 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;
class function BoundIdentifier(
AName: string;
const Address: TResolvedAddress;
const AStaticType: IStaticType = nil
): IBoundIdentifierNode; static;
end;
// Common base class for AST nodes to reduce boilerplate.
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 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;
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;
TBinaryExpressionNode = class(TAstTypedNode, 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; const AStaticType: IStaticType);
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(TAstTypedNode, 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; const AStaticType: IStaticType);
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(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 write FCondition; // Writeable
property ThenBranch: IAstNode read FThenBranch write FThenBranch; // Writeable
property ElseBranch: IAstNode read FElseBranch write FElseBranch; // Writeable
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 write FCondition; // Writeable
property ThenBranch: IAstNode read FThenBranch write FThenBranch; // Writeable
property ElseBranch: IAstNode read FElseBranch write FElseBranch; // Writeable
end;
TLambdaExpressionNode = class(TAstTypedNode, 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; const AStaticType: IStaticType);
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;
TFunctionCallNode = class(TAstTypedNode, 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>; const AStaticType: IStaticType);
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(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 write FArguments; // Writeable
end;
TMacroExpansionNode = class(TAstTypedNode, IMacroExpansionNode)
private
FCallNode: IFunctionCallNode;
FExpandedBody: IAstTypedNode;
function GetCallNode: IFunctionCallNode;
function GetExpandedBody: IAstNode;
function GetKind: TAstNodeKind; override;
public
constructor Create(const ACallNode: IFunctionCallNode; const AExpandedBody: IAstTypedNode);
function Accept(const Visitor: IAstVisitor): TDataValue; override;
function AsMacroExpansion: IMacroExpansionNode; override;
property CallNode: IFunctionCallNode read GetCallNode;
property ExpandedBody: IAstTypedNode read FExpandedBody;
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 write FExpressions; // Writeable
end;
TVariableDeclarationNode = class(TAstTypedNode, 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; const AStaticType: IStaticType);
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(TAstTypedNode, 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; const AStaticType: IStaticType);
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(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 write FBase; // Writeable
property Index: IAstNode read FIndex write FIndex; // Writeable
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 write FBase; // Writeable
property Member: IKeywordNode read FMember write FMember;
end;
TRecordLiteralNode = class(TAstTypedNode, IRecordLiteralNode)
private
FFields: TArray<TRecordFieldLiteral>;
FDefinition: IScalarRecordDefinition;
function GetFields: TArray<TRecordFieldLiteral>;
function GetKind: TAstNodeKind; override;
public
constructor Create(const AFields: TArray<TRecordFieldLiteral>; const AStaticType: IStaticType);
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>; const AStaticType: IStaticType);
property GenericDefinition: IGenericRecordDefinition read FGenericDefinition write FGenericDefinition;
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;
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 write FSeries;
property Value: IAstNode read FValue write FValue; // Writeable
property Lookback: IAstNode read FLookback write FLookback; // Writeable
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 write FSeries;
end;
implementation
uses
System.Generics.Defaults;
type
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
FName: string;
function GetName: string;
function GetKind: TAstNodeKind; override;
public
constructor Create(const AName: string; const AStaticType: IStaticType);
function Accept(const Visitor: IAstVisitor): TDataValue; override;
function AsIdentifier: IIdentifierNode; override;
property Name: string read FName;
end;
TBoundIdentifierNode = class(TIdentifierNode, IBoundIdentifierNode)
private
FAddress: TResolvedAddress;
function GetAddress: TResolvedAddress;
function GetKind: TAstNodeKind; override;
public
constructor Create(const AName: string; const AAddress: TResolvedAddress; const AStaticType: IStaticType);
function AsBoundIdentifierNode: IBoundIdentifierNode; override;
property Address: TResolvedAddress read GetAddress;
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; // Value ist immutable
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;
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;
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, TTypes.Unknown);
end;
class function TAst.AddSeriesItem(
const ASeries: IIdentifierNode;
const AValue: IAstNode;
const ALookback: IAstNode = nil
): IAddSeriesItemNode;
begin
Result := TAddSeriesItemNode.Create(ASeries, AValue, ALookback, TTypes.Unknown);
end;
class function TAst.SeriesLength(const ASeries: IIdentifierNode): ISeriesLengthNode;
begin
Result := TSeriesLengthNode.Create(ASeries, TTypes.Unknown);
end;
class function TAst.Assign(const AIdentifier: IIdentifierNode; const AValue: IAstNode): IAssignmentNode;
begin
Result := TAssignmentNode.Create(AIdentifier, AValue, TTypes.Unknown);
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, TTypes.Unknown);
end;
class function TAst.BinaryExpr(ALeft: IAstNode; AOperator: TScalar.TBinaryOp; ARight: IAstNode): IBinaryExpressionNode;
begin
Result := TBinaryExpressionNode.Create(ALeft, AOperator, ARight, TTypes.Unknown);
end;
class function TAst.Block(const AExpressions: array of IAstNode): IBlockExpressionNode;
begin
Result := TBlockExpressionNode.Create(AExpressions, 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;
// Create a new node with the correct type
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 function TAst.BoundIdentifier(
AName: string;
const Address: TResolvedAddress;
const AStaticType: IStaticType = nil
): IBoundIdentifierNode;
begin
Result :=
TBoundIdentifierNode.Create(
AName,
Address,
if AStaticType <> nil then AStaticType
else TTypes.Unknown
);
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, TTypes.Unknown);
end;
class function TAst.Identifier(AName: string): IIdentifierNode;
begin
Result := TIdentifierNode.Create(AName, TTypes.Unknown);
end;
class function TAst.IfExpr(const ACondition: IAstNode; const AThenBranch, AElseBranch: IAstNode): IIfExpressionNode;
begin
Result := TIfExpressionNode.Create(ACondition, AThenBranch, AElseBranch, TTypes.Unknown);
end;
class function TAst.Indexer(const ABase: IAstNode; const AIndex: IAstNode): IIndexerNode;
begin
Result := TIndexerNode.Create(ABase, AIndex, 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): ILambdaExpressionNode;
begin
Result := TLambdaExpressionNode.Create(AParameters, ABody, TTypes.Unknown);
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
if AExpandedBody.IsTyped then
Result := TMacroExpansionNode.Create(AOriginalCallNode, AExpandedBody.AsTypedNode)
else
Result := TMacroExpansionNode.Create(AOriginalCallNode, Block([]));
end;
class function TAst.MemberAccess(const ABase: IAstNode; const AMember: IKeywordNode): IMemberAccessNode;
begin
Result := TMemberAccessNode.Create(ABase, AMember, TTypes.Unknown);
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, TTypes.Unknown);
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, TTypes.Unknown);
end;
class function TAst.TernaryExpr(const ACondition: IAstNode; const AThenBranch, AElseBranch: IAstNode): ITernaryExpressionNode;
begin
Result := TTernaryExpressionNode.Create(ACondition, AThenBranch, AElseBranch, TTypes.Unknown);
end;
class function TAst.UnaryExpr(const AOperator: TScalar.TUnaryOp; const ARight: IAstNode): IUnaryExpressionNode;
begin
Result := TUnaryExpressionNode.Create(AOperator, ARight, 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: IIdentifierNode; AInitializer: IAstNode = nil): IVariableDeclarationNode;
begin
Result := TVariableDeclarationNode.Create(AIdentifier, AInitializer, TTypes.Unknown);
end;
{ TNopNode }
constructor TNopNode.Create;
begin
inherited Create;
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.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.AsTypedNode: IAstTypedNode;
begin
raise ETypeException.Create('Node has no type');
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;
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 AStaticType: IStaticType);
begin
inherited Create(AStaticType);
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(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;
{ TBinaryExpressionNode }
constructor TBinaryExpressionNode.Create(
const ALeft: IAstNode;
AOperator: TScalar.TBinaryOp;
const ARight: IAstNode;
const AStaticType: IStaticType
);
begin
inherited Create(AStaticType);
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; const AStaticType: IStaticType);
begin
inherited Create(AStaticType);
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; 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);
begin
inherited Create(AStaticType);
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>; const AStaticType: IStaticType);
begin
inherited Create(AStaticType);
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 ACallNode: IFunctionCallNode; const AExpandedBody: IAstTypedNode);
begin
// Copy properties from the original call node
inherited Create(AExpandedBody.StaticType);
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 AIdentifier: IIdentifierNode; AInitializer: IAstNode; const AStaticType: IStaticType);
begin
inherited Create(AStaticType);
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; const AStaticType: IStaticType);
begin
inherited Create(AStaticType);
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; 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 AStaticType: IStaticType);
begin
inherited Create(AStaticType);
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>; const AStaticType: IStaticType);
begin
inherited Create(AFields, AStaticType);
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;
{ TBoundIdentifierNode }
constructor TBoundIdentifierNode.Create(const AName: string; const AAddress: TResolvedAddress; const AStaticType: IStaticType);
begin
inherited Create(AName, AStaticType);
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.