Files
MycLib/Src/AST/Myc.Ast.Nodes.pas
T
Michael Schimmel 7313848538 Ast Schema
2026-01-06 14:37:22 +01:00

2135 lines
60 KiB
ObjectPascal

//==================================================================================================
//== FULL UNIT START: Myc.Ast.Nodes (from Myc.Ast.Nodes.pas)
//==================================================================================================
unit Myc.Ast.Nodes;
interface
uses
System.SysUtils,
System.Generics.Collections,
Myc.Data.Scalar,
Myc.Data.Value,
Myc.Data.Keyword,
Myc.Ast.Scope,
Myc.Ast.Types,
Myc.Ast.Identities,
Myc.Ast.Attributes; // Hinzugefügt für [AstTag] und [AstField]
type
// --- Forward Declarations ---
IAstNode = interface;
// --- Error Handling ---
TCompilerErrorLevel = (elHint, elWarning, elError);
TCompilerError = record
Level: TCompilerErrorLevel;
Message: string;
Node: IAstNode;
constructor Create(ALevel: TCompilerErrorLevel; const AMessage: string; const ANode: IAstNode = nil);
function ToString: string;
end;
ICompilerLog = interface
procedure Add(ALevel: TCompilerErrorLevel; const AMessage: string; const ANode: IAstNode = nil);
procedure AddError(const AMessage: string; const ANode: IAstNode = nil);
procedure AddWarning(const AMessage: string; const ANode: IAstNode = nil);
function HasErrors: Boolean;
function GetEntryCount: Integer;
function GetEntries: TArray<TCompilerError>;
property Entries: TArray<TCompilerError> read GetEntries;
end;
TCompilerLog = class(TInterfacedObject, ICompilerLog)
private
FEntries: TList<TCompilerError>;
public
constructor Create;
destructor Destroy; override;
procedure Add(ALevel: TCompilerErrorLevel; const AMessage: string; const ANode: IAstNode = nil);
procedure AddError(const AMessage: string; const ANode: IAstNode = nil);
procedure AddWarning(const AMessage: string; const ANode: IAstNode = nil);
function HasErrors: Boolean;
function GetEntryCount: Integer;
function GetEntries: TArray<TCompilerError>;
end;
EAstException = class(Exception);
ECompilationFailed = class(EAstException)
private
FErrors: TArray<TCompilerError>;
public
constructor Create(const AErrors: TArray<TCompilerError>);
function ToString: string; override;
property Errors: TArray<TCompilerError> read FErrors;
end;
TCompiledFunction = record
public
Func: TDataValue.TFunc;
StaticType: IStaticType;
IsPure: Boolean;
constructor Create(const AFunc: TDataValue.TFunc; const AStaticType: IStaticType; AIsPure: Boolean);
end;
// --- AST Interfaces ---
IAstVisitor = interface;
IAstTypedNode = interface;
// Core Nodes
IConstantNode = interface;
IIdentifierNode = interface;
IKeywordNode = interface;
// Structure
ITupleNode = interface;
IRecordFieldNode = interface;
// Control Flow & Structure
IIfExpressionNode = interface;
ICondExpressionNode = interface;
ILambdaExpressionNode = interface;
IFunctionCallNode = interface;
IMacroExpansionNode = interface;
IBlockExpressionNode = interface;
IVariableDeclarationNode = interface;
IAssignmentNode = interface;
IMacroDefinitionNode = interface;
IQuasiquoteNode = interface;
IUnquoteNode = interface;
IUnquoteSplicingNode = interface;
IIndexerNode = interface;
IMemberAccessNode = interface;
IRecordLiteralNode = interface;
ICreateSeriesNode = interface;
IAddSeriesItemNode = interface;
ISeriesLengthNode = interface;
IRecurNode = interface;
INopNode = interface;
// Pipes
IPipeNode = interface;
// Node Kinds & Helpers
TAstNodeKind = (
akConstant,
akIdentifier,
akKeyword,
// Containers
akTuple, // The universal list (replaces ArgList, ParamList, ExprList, FieldList)
akRecordField, // Single key-value pair
// Control Flow
akIfExpression,
akCondExpression,
akLambdaExpression,
akFunctionCall,
akMacroExpansion,
akBlockExpression,
akVariableDeclaration,
akAssignment,
akMacroDefinition,
akQuasiquote,
akUnquote,
akUnquoteSplicing,
akIndexer,
akMemberAccess,
akRecordLiteral,
akCreateSeries,
akAddSeriesItem,
akSeriesLength,
akRecur,
akNop,
// Pipes
akPipe
);
TAstNodeKindHelper = record helper for TAstNodeKind
public
function ToString: string;
end;
// Represents a single branch in a Cond expression (Condition -> Branch)
TCondPair = record
Condition: IAstNode;
Branch: IAstNode;
constructor Create(const ACondition, ABranch: IAstNode);
end;
// --- Base Interfaces ---
IAstNode = interface
{$region 'private'}
function GetKind: TAstNodeKind;
function GetIsTyped: Boolean;
function GetIdentity: IAstIdentity;
{$endregion}
function Accept(const Visitor: IAstVisitor): TDataValue;
// Fluent Casts / Accessors (Interface based)
function AsTypedNode: IAstTypedNode;
function AsConstant: IConstantNode;
function AsIdentifier: IIdentifierNode;
function AsKeyword: IKeywordNode;
function AsTuple: ITupleNode;
function AsRecordField: IRecordFieldNode;
function AsIfExpression: IIfExpressionNode;
function AsCondExpression: ICondExpressionNode;
function AsLambdaExpression: ILambdaExpressionNode;
function AsFunctionCall: IFunctionCallNode;
function AsMacroExpansion: IMacroExpansionNode;
function AsBlockExpression: IBlockExpressionNode;
function AsVariableDeclaration: IVariableDeclarationNode;
function AsAssignment: IAssignmentNode;
function AsMacroDefinition: IMacroDefinitionNode;
function AsQuasiquote: IQuasiquoteNode;
function AsUnquote: IUnquoteNode;
function AsUnquoteSplicing: IUnquoteSplicingNode;
function AsIndexer: IIndexerNode;
function AsMemberAccess: IMemberAccessNode;
function AsRecordLiteral: IRecordLiteralNode;
function AsCreateSeries: ICreateSeriesNode;
function AsAddSeriesItem: IAddSeriesItemNode;
function AsSeriesLength: ISeriesLengthNode;
function AsRecur: IRecurNode;
function AsNop: INopNode;
function AsPipe: IPipeNode;
property IsTyped: Boolean read GetIsTyped;
property Kind: TAstNodeKind read GetKind;
property Identity: IAstIdentity read GetIdentity;
end;
IAstTypedNode = interface(IAstNode)
{$region 'private'}
function GetStaticType: IStaticType;
{$endregion}
property StaticType: IStaticType read GetStaticType;
end;
IRecordFieldNode = interface(IAstNode)
{$region 'private'}
function GetKey: IKeywordNode;
function GetValue: IAstNode;
{$endregion}
property Key: IKeywordNode read GetKey;
property Value: IAstNode read GetValue;
end;
// --- Node Interfaces (Definitions) ---
// Function Definition (Lambda)
IFunctionDefinition = interface(IAstTypedNode)
{$region 'private'}
function GetBody: IAstNode;
function GetParameters: ITupleNode;
function GetIsPure: Boolean;
{$endregion}
property Body: IAstNode read GetBody;
property Parameters: ITupleNode read GetParameters;
property IsPure: Boolean read GetIsPure;
end;
INopNode = interface(IAstTypedNode)
end;
IConstantNode = interface(IAstTypedNode)
{$region 'private'}
function GetValue: TDataValue;
{$endregion}
property Value: TDataValue read GetValue;
end;
IIdentifierNode = interface(IAstTypedNode)
{$region 'private'}
function GetAddress: TResolvedAddress;
function GetName: string;
{$endregion}
property Address: TResolvedAddress read GetAddress;
property Name: string read GetName;
end;
IKeywordNode = interface(IAstTypedNode)
{$region 'private'}
function GetValue: IKeyword;
{$endregion}
property Value: IKeyword read GetValue;
end;
ITupleNode = interface(IAstTypedNode)
{$region 'private'}
function GetElements: TArray<IAstNode>;
{$endregion}
property Elements: TArray<IAstNode> read GetElements;
end;
IIfExpressionNode = interface(IAstTypedNode)
{$region 'private'}
function GetCondition: IAstNode;
function GetThenBranch: IAstNode;
function GetElseBranch: IAstNode;
{$endregion}
property Condition: IAstNode read GetCondition;
property ThenBranch: IAstNode read GetThenBranch;
property ElseBranch: IAstNode read GetElseBranch;
end;
ICondExpressionNode = interface(IAstTypedNode)
{$region 'private'}
function GetPairs: TArray<TCondPair>;
function GetElseBranch: IAstNode;
{$endregion}
property Pairs: TArray<TCondPair> read GetPairs;
property ElseBranch: IAstNode read GetElseBranch;
end;
ILambdaExpressionNode = interface(IFunctionDefinition)
{$region 'private'}
function GetLayout: IScopeLayout;
function GetDescriptor: IScopeDescriptor;
function GetUpvalues: TArray<TResolvedAddress>;
function GetHasNestedLambdas: Boolean;
{$endregion}
property Layout: IScopeLayout read GetLayout;
property Descriptor: IScopeDescriptor read GetDescriptor;
property Upvalues: TArray<TResolvedAddress> read GetUpvalues;
property HasNestedLambdas: Boolean read GetHasNestedLambdas;
end;
IFunctionCallNode = interface(IAstTypedNode)
{$region 'private'}
function GetCallee: IAstNode;
function GetArguments: ITupleNode;
function GetIsTailCall: Boolean;
function GetStaticTarget: TDataValue.TFunc;
function GetIsTargetPure: Boolean;
{$endregion}
property Callee: IAstNode read GetCallee;
property Arguments: ITupleNode read GetArguments;
property IsTailCall: Boolean read GetIsTailCall;
property StaticTarget: TDataValue.TFunc read GetStaticTarget;
property IsTargetPure: Boolean read GetIsTargetPure;
end;
IMacroExpansionNode = interface(IAstTypedNode)
{$region 'private'}
function GetCallNode: IFunctionCallNode;
function GetExpandedBody: IAstNode;
{$endregion}
property CallNode: IFunctionCallNode read GetCallNode;
property ExpandedBody: IAstNode read GetExpandedBody;
end;
IRecurNode = interface(IAstTypedNode)
{$region 'private'}
function GetArguments: ITupleNode;
{$endregion}
property Arguments: ITupleNode read GetArguments;
end;
IBlockExpressionNode = interface(IAstTypedNode)
{$region 'private'}
function GetExpressions: ITupleNode;
{$endregion}
property Expressions: ITupleNode read GetExpressions;
end;
IVariableDeclarationNode = interface(IAstTypedNode)
{$region 'private'}
function GetTarget: IAstNode;
function GetInitializer: IAstNode;
function GetIsBoxed: Boolean;
{$endregion}
property Target: IAstNode read GetTarget;
property Initializer: IAstNode read GetInitializer;
property IsBoxed: Boolean read GetIsBoxed;
end;
IAssignmentNode = interface(IAstTypedNode)
{$region 'private'}
function GetTarget: IAstNode;
function GetValue: IAstNode;
{$endregion}
property Target: IAstNode read GetTarget;
property Value: IAstNode read GetValue;
end;
IMacroDefinitionNode = interface(IAstTypedNode)
{$region 'private'}
function GetName: IIdentifierNode;
function GetParameters: ITupleNode;
function GetBody: IAstNode;
{$endregion}
property Name: IIdentifierNode read GetName;
property Parameters: ITupleNode read GetParameters;
property Body: IAstNode read GetBody;
end;
IQuasiquoteNode = interface(IAstNode)
{$region 'private'}
function GetExpression: IAstNode;
{$endregion}
property Expression: IAstNode read GetExpression;
end;
IUnquoteNode = interface(IAstNode)
{$region 'private'}
function GetExpression: IAstNode;
{$endregion}
property Expression: IAstNode read GetExpression;
end;
IUnquoteSplicingNode = interface(IAstNode)
{$region 'private'}
function GetExpression: IQuasiquoteNode;
{$endregion}
property Expression: IQuasiquoteNode read GetExpression;
end;
IIndexerNode = interface(IAstTypedNode)
{$region 'private'}
function GetBase: IAstNode;
function GetIndex: IAstNode;
{$endregion}
property Base: IAstNode read GetBase;
property Index: IAstNode read GetIndex;
end;
IMemberAccessNode = interface(IAstTypedNode)
{$region 'private'}
function GetBase: IAstNode;
function GetMember: IKeywordNode;
{$endregion}
property Base: IAstNode read GetBase;
property Member: IKeywordNode read GetMember;
end;
IRecordLiteralNode = interface(IAstTypedNode)
{$region 'private'}
function GetFields: ITupleNode;
function GetGenericDefinition: IGenericRecordDefinition;
function GetScalarDefinition: IScalarRecordDefinition;
{$endregion}
property Fields: ITupleNode read GetFields;
property GenericDefinition: IGenericRecordDefinition read GetGenericDefinition;
property ScalarDefinition: IScalarRecordDefinition read GetScalarDefinition;
end;
ICreateSeriesNode = interface(IAstTypedNode)
{$region 'private'}
function GetDefinitionNode: IAstNode;
function GetRecordDefinition: IScalarRecordDefinition;
{$endregion}
property DefinitionNode: IAstNode read GetDefinitionNode;
property RecordDefinition: IScalarRecordDefinition read GetRecordDefinition;
end;
IAddSeriesItemNode = interface(IAstTypedNode)
{$region 'private'}
function GetSeries: IIdentifierNode;
function GetValue: IAstNode;
function GetLookback: IAstNode;
{$endregion}
property Series: IIdentifierNode read GetSeries;
property Value: IAstNode read GetValue;
property Lookback: IAstNode read GetLookback;
end;
ISeriesLengthNode = interface(IAstTypedNode)
{$region 'private'}
function GetSeries: IIdentifierNode;
{$endregion}
property Series: IIdentifierNode read GetSeries;
end;
// The main pipe definition: (pipe [[source [:sel]]...] (fn ...))
IPipeNode = interface(IAstTypedNode)
{$region 'private'}
function GetInputs: ITupleNode;
function GetTransformation: ILambdaExpressionNode;
{$endregion}
property Inputs: ITupleNode read GetInputs;
property Transformation: ILambdaExpressionNode read GetTransformation;
end;
IAstVisitor = interface
function Visit(const Node: IAstNode): TDataValue;
end;
IEvaluatorVisitor = interface(IAstVisitor)
function Execute(const RootNode: IAstNode): TDataValue;
end;
TEvaluatorFactory = reference to function(const Scope: IExecutionScope): IEvaluatorVisitor;
TAstNode = class(TInterfacedObject, IAstNode)
private
FIdentity: IAstIdentity;
function GetIdentity: IAstIdentity;
protected
function GetKind: TAstNodeKind; virtual; abstract;
function GetIsTyped: Boolean; virtual;
public
constructor Create(const AIdentity: IAstIdentity);
function Accept(const Visitor: IAstVisitor): TDataValue; virtual;
function AsConstant: IConstantNode; virtual;
function AsIdentifier: IIdentifierNode; virtual;
function AsKeyword: IKeywordNode; virtual;
function AsRecordField: IRecordFieldNode; virtual;
function AsTuple: ITupleNode; virtual;
function AsIfExpression: IIfExpressionNode; virtual;
function AsCondExpression: ICondExpressionNode; virtual;
function AsLambdaExpression: ILambdaExpressionNode; virtual;
function AsFunctionCall: IFunctionCallNode; virtual;
function AsMacroExpansion: IMacroExpansionNode; virtual;
function AsBlockExpression: IBlockExpressionNode; virtual;
function AsVariableDeclaration: IVariableDeclarationNode; virtual;
function AsAssignment: IAssignmentNode; virtual;
function AsMacroDefinition: IMacroDefinitionNode; virtual;
function AsQuasiquote: IQuasiquoteNode; virtual;
function AsUnquote: IUnquoteNode; virtual;
function AsUnquoteSplicing: IUnquoteSplicingNode; virtual;
function AsIndexer: IIndexerNode; virtual;
function AsMemberAccess: IMemberAccessNode; virtual;
function AsRecordLiteral: IRecordLiteralNode; virtual;
function AsCreateSeries: ICreateSeriesNode; virtual;
function AsAddSeriesItem: IAddSeriesItemNode; virtual;
function AsSeriesLength: ISeriesLengthNode; virtual;
function AsRecur: IRecurNode; virtual;
function AsNop: INopNode; virtual;
function AsPipe: IPipeNode; virtual;
function AsTypedNode: IAstTypedNode; virtual;
property IsTyped: Boolean read GetIsTyped;
property Kind: TAstNodeKind read GetKind;
property Identity: IAstIdentity read GetIdentity;
end;
TAstTypedNode = class(TAstNode, IAstTypedNode)
private
FStaticType: IStaticType;
function GetStaticType: IStaticType;
protected
function GetIsTyped: Boolean; override;
public
constructor Create(const AStaticType: IStaticType; const AIdentity: IAstIdentity);
function AsTypedNode: IAstTypedNode; override;
property StaticType: IStaticType read GetStaticType;
end;
[AstTag('Field')]
TRecordFieldNode = class(TAstNode, IRecordFieldNode)
private
[AstField(0, 'key', fkNode)]
FKey: IKeywordNode;
[AstField(1, 'value', fkNode)]
FValue: IAstNode;
function GetKey: IKeywordNode;
function GetValue: IAstNode;
protected
function GetKind: TAstNodeKind; override;
public
constructor Create(const AKey: IKeywordNode; const AValue: IAstNode; const AIdentity: IAstIdentity);
function AsRecordField: IRecordFieldNode; override;
end;
// --- Core Nodes Implementations ---
[AstTag('Const')]
TConstantNode = class(TAstTypedNode, IConstantNode)
private
[AstField(0, 'value', fkValue)]
FConstIdentity: IConstantIdentity; // Typed reference for fast access
function GetValue: TDataValue;
protected
function GetKind: TAstNodeKind; override;
public
constructor Create(const AIdentity: IConstantIdentity; const AStaticType: IStaticType);
function AsConstant: IConstantNode; override;
end;
[AstTag('Id')]
TIdentifierNode = class(TAstTypedNode, IIdentifierNode)
private
[AstField(0, 'name', fkString)]
FNamedIdentity: INamedIdentity; // Typed reference for fast access
FAddress: TResolvedAddress;
function GetAddress: TResolvedAddress;
function GetName: string;
protected
function GetKind: TAstNodeKind; override;
public
constructor Create(const AIdentity: INamedIdentity; const AAddress: TResolvedAddress; const AStaticType: IStaticType);
function AsIdentifier: IIdentifierNode; override;
end;
[AstTag('Key')]
TKeywordNode = class(TAstTypedNode, IKeywordNode)
private
[AstField(0, 'name', fkString)]
FKeywordIdentity: IKeywordIdentity;
function GetValue: IKeyword;
protected
function GetKind: TAstNodeKind; override;
public
constructor Create(const AIdentity: IKeywordIdentity);
function AsKeyword: IKeywordNode; override;
end;
[AstTag('Tuple')]
TTupleNode = class(TAstTypedNode, ITupleNode)
private
[AstField(0, 'elements', fkNode)] // Represents array
FElements: TArray<IAstNode>;
function GetElements: TArray<IAstNode>;
protected
function GetKind: TAstNodeKind; override;
public
constructor Create(const AElements: TArray<IAstNode>; const AIdentity: IAstIdentity; const AStaticType: IStaticType);
function AsTuple: ITupleNode; override;
end;
[AstTag('Series')]
TCreateSeriesNode = class(TAstTypedNode, ICreateSeriesNode)
private
[AstField(0, 'definition', fkNode)]
FDefinitionNode: IAstNode;
FRecordDefinition: IScalarRecordDefinition;
function GetDefinitionNode: IAstNode;
function GetRecordDefinition: IScalarRecordDefinition;
protected
function GetKind: TAstNodeKind; override;
public
constructor Create(
const ADefinitionNode: IAstNode;
const ARecordDefinition: IScalarRecordDefinition;
const AStaticType: IStaticType;
const AIdentity: IAstIdentity
);
function AsCreateSeries: ICreateSeriesNode; override;
end;
// --- Structural Nodes (Identity only for location) ---
[AstTag('If')]
TIfExpressionNode = class(TAstTypedNode, IIfExpressionNode)
private
[AstField(0, 'cond', fkNode)]
FCondition: IAstNode;
[AstField(1, 'then', fkNode)]
FThenBranch: IAstNode;
[AstField(2, 'else', fkNullableNode)]
FElseBranch: IAstNode;
function GetCondition: IAstNode;
function GetThenBranch: IAstNode;
function GetElseBranch: IAstNode;
protected
function GetKind: TAstNodeKind; override;
public
constructor Create(
const ACondition, AThenBranch, AElseBranch: IAstNode;
const AStaticType: IStaticType;
const AIdentity: IAstIdentity
);
function AsIfExpression: IIfExpressionNode; override;
end;
[AstTag('Cond')]
TCondExpressionNode = class(TAstTypedNode, ICondExpressionNode)
private
[AstField(0, 'pairs', fkArrayOfPairs)]
FPairs: TArray<TCondPair>;
[AstField(1, 'else', fkNullableNode)]
FElseBranch: IAstNode;
function GetPairs: TArray<TCondPair>;
function GetElseBranch: IAstNode;
protected
function GetKind: TAstNodeKind; override;
public
constructor Create(
const APairs: TArray<TCondPair>;
const AElseBranch: IAstNode;
const AStaticType: IStaticType;
const AIdentity: IAstIdentity
);
function AsCondExpression: ICondExpressionNode; override;
end;
[AstTag('Fn')]
TLambdaExpressionNode = class(TAstTypedNode, ILambdaExpressionNode, IFunctionDefinition)
private
[AstField(0, 'params', fkTuple)]
FParameters: ITupleNode;
[AstField(1, 'body', fkNode)]
FBody: IAstNode;
FLayout: IScopeLayout;
FDescriptor: IScopeDescriptor;
FUpvalues: TArray<TResolvedAddress>;
FHasNestedLambdas, FIsPure: Boolean;
function GetParameters: ITupleNode;
function GetBody: IAstNode;
function GetLayout: IScopeLayout;
function GetDescriptor: IScopeDescriptor;
function GetUpvalues: TArray<TResolvedAddress>;
function GetHasNestedLambdas: Boolean;
function GetIsPure: Boolean;
protected
function GetKind: TAstNodeKind; override;
public
constructor Create(
const AParameters: ITupleNode;
const ABody: IAstNode;
const AStaticType: IStaticType;
const ALayout: IScopeLayout;
const ADescriptor: IScopeDescriptor;
const AUpvalues: TArray<TResolvedAddress>;
const AHasNestedLambdas, AIsPure: Boolean;
const AIdentity: IAstIdentity
);
function AsLambdaExpression: ILambdaExpressionNode; override;
end;
[AstTag('Call')]
TFunctionCallNode = class(TAstTypedNode, IFunctionCallNode)
private
[AstField(0, 'callee', fkNode)]
FCallee: IAstNode;
[AstField(1, 'args', fkTuple)]
FArguments: ITupleNode;
FIsTailCall: Boolean;
FStaticTarget: TDataValue.TFunc;
FIsTargetPure: Boolean;
function GetCallee: IAstNode;
function GetArguments: ITupleNode;
function GetIsTailCall: Boolean;
function GetStaticTarget: TDataValue.TFunc;
function GetIsTargetPure: Boolean;
protected
function GetKind: TAstNodeKind; override;
public
constructor Create(
const ACallee: IAstNode;
const AArguments: ITupleNode;
const AStaticType: IStaticType;
const AIsTailCall: Boolean;
const AStaticTarget: TDataValue.TFunc;
const AIsTargetPure: Boolean;
const AIdentity: IAstIdentity
);
function AsFunctionCall: IFunctionCallNode; override;
end;
[AstTag('Macro')]
TMacroDefinitionNode = class(TAstTypedNode, IMacroDefinitionNode)
private
[AstField(0, 'name', fkNode)]
FName: IIdentifierNode;
[AstField(1, 'params', fkTuple)]
FParameters: ITupleNode;
[AstField(2, 'body', fkNode)]
FBody: IAstNode;
function GetName: IIdentifierNode;
function GetParameters: ITupleNode;
function GetBody: IAstNode;
protected
function GetKind: TAstNodeKind; override;
public
constructor Create(
const AName: IIdentifierNode;
const AParameters: ITupleNode;
const ABody: IAstNode;
const AIdentity: IAstIdentity
);
function AsMacroDefinition: IMacroDefinitionNode; override;
end;
TMacroExpansionNode = class(TAstTypedNode, IMacroExpansionNode)
private
FCallNode: IFunctionCallNode;
FExpandedBody: IAstNode;
function GetCallNode: IFunctionCallNode;
function GetExpandedBody: IAstNode;
protected
function GetKind: TAstNodeKind; override;
public
constructor Create(const ACallNode: IFunctionCallNode; const AExpandedBody: IAstNode; const AIdentity: IAstIdentity);
function AsMacroExpansion: IMacroExpansionNode; override;
end;
[AstTag('Quote')]
TQuasiquoteNode = class(TAstNode, IQuasiquoteNode)
private
[AstField(0, 'expr', fkNode)]
FExpression: IAstNode;
function GetExpression: IAstNode;
protected
function GetKind: TAstNodeKind; override;
public
constructor Create(const AExpression: IAstNode; const AIdentity: IAstIdentity);
function AsQuasiquote: IQuasiquoteNode; override;
end;
[AstTag('Unquote')]
TUnquoteNode = class(TAstNode, IUnquoteNode)
private
[AstField(0, 'expr', fkNode)]
FExpression: IAstNode;
function GetExpression: IAstNode;
protected
function GetKind: TAstNodeKind; override;
public
constructor Create(const AExpression: IAstNode; const AIdentity: IAstIdentity);
function AsUnquote: IUnquoteNode; override;
end;
[AstTag('Splice')]
TUnquoteSplicingNode = class(TAstNode, IUnquoteSplicingNode)
private
[AstField(0, 'expr', fkNode)]
FExpression: IQuasiquoteNode;
function GetExpression: IQuasiquoteNode;
protected
function GetKind: TAstNodeKind; override;
public
constructor Create(const AExpression: IQuasiquoteNode; const AIdentity: IAstIdentity);
function AsUnquoteSplicing: IUnquoteSplicingNode; override;
end;
[AstTag('Recur')]
TRecurNode = class(TAstTypedNode, IRecurNode)
private
[AstField(0, 'args', fkTuple)]
FArguments: ITupleNode;
function GetArguments: ITupleNode;
protected
function GetKind: TAstNodeKind; override;
public
constructor Create(const AArguments: ITupleNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity);
function AsRecur: IRecurNode; override;
end;
[AstTag('Block')]
TBlockExpressionNode = class(TAstTypedNode, IBlockExpressionNode)
private
[AstField(0, 'expressions', fkTuple)]
FExpressions: ITupleNode;
function GetExpressions: ITupleNode;
protected
function GetKind: TAstNodeKind; override;
public
constructor Create(const AExpressions: ITupleNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity);
function AsBlockExpression: IBlockExpressionNode; override;
end;
[AstTag('Var')]
TVariableDeclarationNode = class(TAstTypedNode, IVariableDeclarationNode)
private
[AstField(0, 'target', fkNode)]
FTarget: IAstNode;
[AstField(1, 'init', fkNullableNode)]
FInitializer: IAstNode;
FIsBoxed: Boolean;
function GetTarget: IAstNode;
function GetInitializer: IAstNode;
function GetIsBoxed: Boolean;
protected
function GetKind: TAstNodeKind; override;
public
constructor Create(
const ATarget: IAstNode;
AInitializer: IAstNode;
const AStaticType: IStaticType;
const AIsBoxed: Boolean;
const AIdentity: IAstIdentity
);
function AsVariableDeclaration: IVariableDeclarationNode; override;
end;
[AstTag('Assign')]
TAssignmentNode = class(TAstTypedNode, IAssignmentNode)
private
[AstField(0, 'target', fkNode)]
FTarget: IAstNode;
[AstField(1, 'value', fkNode)]
FValue: IAstNode;
function GetTarget: IAstNode;
function GetValue: IAstNode;
protected
function GetKind: TAstNodeKind; override;
public
constructor Create(const ATarget, AValue: IAstNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity);
function AsAssignment: IAssignmentNode; override;
end;
[AstTag('Index')]
TIndexerNode = class(TAstTypedNode, IIndexerNode)
private
[AstField(0, 'base', fkNode)]
FBase: IAstNode;
[AstField(1, 'index', fkNode)]
FIndex: IAstNode;
function GetBase: IAstNode;
function GetIndex: IAstNode;
protected
function GetKind: TAstNodeKind; override;
public
constructor Create(const ABase, AIndex: IAstNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity);
function AsIndexer: IIndexerNode; override;
end;
[AstTag('Member')]
TMemberAccessNode = class(TAstTypedNode, IMemberAccessNode)
private
[AstField(0, 'base', fkNode)]
FBase: IAstNode;
[AstField(1, 'member', fkNode)]
FMember: IKeywordNode;
function GetBase: IAstNode;
function GetMember: IKeywordNode;
protected
function GetKind: TAstNodeKind; override;
public
constructor Create(
const ABase: IAstNode;
const AMember: IKeywordNode;
const AStaticType: IStaticType;
const AIdentity: IAstIdentity
);
function AsMemberAccess: IMemberAccessNode; override;
end;
[AstTag('Record')]
TRecordLiteralNode = class(TAstTypedNode, IRecordLiteralNode)
private
[AstField(0, 'fields', fkTuple)]
FFields: ITupleNode;
FScalarDef: IScalarRecordDefinition;
FGenericDef: IGenericRecordDefinition;
function GetFields: ITupleNode;
function GetGenericDefinition: IGenericRecordDefinition;
function GetScalarDefinition: IScalarRecordDefinition;
protected
function GetKind: TAstNodeKind; override;
public
constructor Create(
const AFields: ITupleNode;
const AScalarDef: IScalarRecordDefinition;
const AGenericDef: IGenericRecordDefinition;
const AStaticType: IStaticType;
const AIdentity: IAstIdentity
);
function AsRecordLiteral: IRecordLiteralNode; override;
end;
[AstTag('Add')]
TAddSeriesItemNode = class(TAstTypedNode, IAddSeriesItemNode)
private
[AstField(0, 'series', fkNode)]
FSeries: IIdentifierNode;
[AstField(1, 'value', fkNode)]
FValue: IAstNode;
[AstField(2, 'lookback', fkNullableNode)]
FLookback: IAstNode;
function GetSeries: IIdentifierNode;
function GetValue: IAstNode;
function GetLookback: IAstNode;
protected
function GetKind: TAstNodeKind; override;
public
constructor Create(
const ASeries: IIdentifierNode;
const AValue, ALookback: IAstNode;
const AStaticType: IStaticType;
const AIdentity: IAstIdentity
);
function AsAddSeriesItem: IAddSeriesItemNode; override;
end;
[AstTag('Count')]
TSeriesLengthNode = class(TAstTypedNode, ISeriesLengthNode)
private
[AstField(0, 'series', fkNode)]
FSeries: IIdentifierNode;
function GetSeries: IIdentifierNode;
protected
function GetKind: TAstNodeKind; override;
public
constructor Create(const ASeries: IIdentifierNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity);
function AsSeriesLength: ISeriesLengthNode; override;
end;
[AstTag('Nop')]
TNopNode = class(TAstTypedNode, INopNode)
protected
function GetKind: TAstNodeKind; override;
public
constructor Create(const AStaticType: IStaticType; const AIdentity: IAstIdentity);
function AsNop: INopNode; override;
end;
[AstTag('Pipe')]
TPipeNode = class(TAstTypedNode, IPipeNode)
private
[AstField(0, 'inputs', fkTuple)]
FInputs: ITupleNode;
[AstField(1, 'transform', fkNode)]
FTransformation: ILambdaExpressionNode;
function GetInputs: ITupleNode;
function GetTransformation: ILambdaExpressionNode;
protected
function GetKind: TAstNodeKind; override;
public
constructor Create(
const AInputs: ITupleNode;
const ATransformation: ILambdaExpressionNode;
const AIdentity: IAstIdentity;
const AStaticType: IStaticType
);
function AsPipe: IPipeNode; override;
end;
implementation
uses
System.Classes,
System.TypInfo,
System.Rtti,
System.StrUtils;
{ TCompiledFunction }
constructor TCompiledFunction.Create(const AFunc: TDataValue.TFunc; const AStaticType: IStaticType; AIsPure: Boolean);
begin
Func := AFunc;
StaticType := AStaticType;
IsPure := AIsPure;
end;
{ TAstNodeKindHelper }
function TAstNodeKindHelper.ToString: string;
begin
Result := GetEnumName(TypeInfo(TAstNodeKind), Ord(Self));
Assert(StartsText('ak', Result));
Result := Result.Substring(2);
end;
{ TCondPair }
constructor TCondPair.Create(const ACondition, ABranch: IAstNode);
begin
Condition := ACondition;
Branch := ABranch;
end;
{ TCompilerError }
constructor TCompilerError.Create(ALevel: TCompilerErrorLevel; const AMessage: string; const ANode: IAstNode);
begin
Level := ALevel;
Message := AMessage;
Node := ANode;
end;
function TCompilerError.ToString: string;
var
location: string;
begin
location := '';
if Assigned(Node) and Assigned(Node.Identity) and Assigned(Node.Identity.Location) then
begin
location := Node.Identity.Location.ToString + ' ';
end
else if Assigned(Node) and Assigned(Node.Identity) then
begin
location := '[' + Node.Identity.ToString + '] ';
end;
case Level of
elHint: Result := '[Hint] ';
elWarning: Result := '[Warning] ';
elError: Result := '[Error] ';
end;
Result := Result + location + Message;
end;
{ TCompilerLog }
constructor TCompilerLog.Create;
begin
inherited Create;
FEntries := TList<TCompilerError>.Create;
end;
destructor TCompilerLog.Destroy;
begin
FEntries.Free;
inherited;
end;
procedure TCompilerLog.Add(ALevel: TCompilerErrorLevel; const AMessage: string; const ANode: IAstNode);
begin
FEntries.Add(TCompilerError.Create(ALevel, AMessage, ANode));
end;
procedure TCompilerLog.AddError(const AMessage: string; const ANode: IAstNode);
begin
Add(elError, AMessage, ANode);
end;
procedure TCompilerLog.AddWarning(const AMessage: string; const ANode: IAstNode);
begin
Add(elWarning, AMessage, ANode);
end;
function TCompilerLog.HasErrors: Boolean;
var
entry: TCompilerError;
begin
Result := False;
for entry in FEntries do
if entry.Level = elError then
Exit(True);
end;
function TCompilerLog.GetEntryCount: Integer;
begin
Result := FEntries.Count;
end;
function TCompilerLog.GetEntries: TArray<TCompilerError>;
begin
Result := FEntries.ToArray;
end;
{ ECompilationFailed }
constructor ECompilationFailed.Create(const AErrors: TArray<TCompilerError>);
var
msg: string;
begin
if Length(AErrors) > 0 then
msg := Format('Compilation failed with %d error(s). First: %s', [Length(AErrors), AErrors[0].Message])
else
msg := 'Compilation failed with unspecified errors.';
inherited Create(msg);
FErrors := AErrors;
end;
function ECompilationFailed.ToString: string;
var
sb: TStringBuilder;
err: TCompilerError;
begin
sb := TStringBuilder.Create;
try
sb.AppendLine(Message);
for err in FErrors do
begin
sb.Append(' - ');
sb.AppendLine(err.ToString);
end;
Result := sb.ToString;
finally
sb.Free;
end;
end;
{ TAstNode }
constructor TAstNode.Create(const AIdentity: IAstIdentity);
begin
inherited Create;
FIdentity := AIdentity;
end;
function TAstNode.GetIdentity: IAstIdentity;
begin
Result := FIdentity;
end;
function TAstNode.GetIsTyped: Boolean;
begin
Result := False;
end;
function TAstNode.Accept(const Visitor: IAstVisitor): TDataValue;
begin
// Central Dispatch: Delegate to the generic Visit method of the visitor.
// The visitor uses Node.Kind to look up the correct handler.
Result := Visitor.Visit(Self);
end;
// Default implementations for As... casting methods (Return nil)
function TAstNode.AsConstant: IConstantNode;
begin
Result := nil;
end;
function TAstNode.AsIdentifier: IIdentifierNode;
begin
Result := nil;
end;
function TAstNode.AsKeyword: IKeywordNode;
begin
Result := nil;
end;
function TAstNode.AsRecordField: IRecordFieldNode;
begin
Result := nil;
end;
function TAstNode.AsTuple: ITupleNode;
begin
Result := nil;
end;
function TAstNode.AsIfExpression: IIfExpressionNode;
begin
Result := nil;
end;
function TAstNode.AsCondExpression: ICondExpressionNode;
begin
Result := nil;
end;
function TAstNode.AsLambdaExpression: ILambdaExpressionNode;
begin
Result := nil;
end;
function TAstNode.AsFunctionCall: IFunctionCallNode;
begin
Result := nil;
end;
function TAstNode.AsMacroExpansion: IMacroExpansionNode;
begin
Result := nil;
end;
function TAstNode.AsBlockExpression: IBlockExpressionNode;
begin
Result := nil;
end;
function TAstNode.AsVariableDeclaration: IVariableDeclarationNode;
begin
Result := nil;
end;
function TAstNode.AsAssignment: IAssignmentNode;
begin
Result := nil;
end;
function TAstNode.AsMacroDefinition: IMacroDefinitionNode;
begin
Result := nil;
end;
function TAstNode.AsQuasiquote: IQuasiquoteNode;
begin
Result := nil;
end;
function TAstNode.AsUnquote: IUnquoteNode;
begin
Result := nil;
end;
function TAstNode.AsUnquoteSplicing: IUnquoteSplicingNode;
begin
Result := nil;
end;
function TAstNode.AsIndexer: IIndexerNode;
begin
Result := nil;
end;
function TAstNode.AsMemberAccess: IMemberAccessNode;
begin
Result := nil;
end;
function TAstNode.AsRecordLiteral: IRecordLiteralNode;
begin
Result := nil;
end;
function TAstNode.AsCreateSeries: ICreateSeriesNode;
begin
Result := nil;
end;
function TAstNode.AsAddSeriesItem: IAddSeriesItemNode;
begin
Result := nil;
end;
function TAstNode.AsSeriesLength: ISeriesLengthNode;
begin
Result := nil;
end;
function TAstNode.AsRecur: IRecurNode;
begin
Result := nil;
end;
function TAstNode.AsNop: INopNode;
begin
Result := nil;
end;
function TAstNode.AsTypedNode: IAstTypedNode;
begin
Result := nil;
end;
function TAstNode.AsPipe: IPipeNode;
begin
Result := nil;
end;
{ TAstTypedNode }
constructor TAstTypedNode.Create(const AStaticType: IStaticType; const AIdentity: IAstIdentity);
begin
inherited Create(AIdentity);
FStaticType := AStaticType;
end;
function TAstTypedNode.GetStaticType: IStaticType;
begin
Result := FStaticType;
end;
function TAstTypedNode.GetIsTyped: Boolean;
begin
Result := True;
end;
function TAstTypedNode.AsTypedNode: IAstTypedNode;
begin
Result := Self;
end;
{ TRecordFieldNode }
constructor TRecordFieldNode.Create(const AKey: IKeywordNode; const AValue: IAstNode; const AIdentity: IAstIdentity);
begin
inherited Create(AIdentity);
FKey := AKey;
FValue := AValue;
end;
function TRecordFieldNode.AsRecordField: IRecordFieldNode;
begin
Result := Self;
end;
function TRecordFieldNode.GetKey: IKeywordNode;
begin
Result := FKey;
end;
function TRecordFieldNode.GetKind: TAstNodeKind;
begin
Result := akRecordField;
end;
function TRecordFieldNode.GetValue: IAstNode;
begin
Result := FValue;
end;
{ TConstantNode }
constructor TConstantNode.Create(const AIdentity: IConstantIdentity; const AStaticType: IStaticType);
begin
inherited Create(AStaticType, AIdentity);
FConstIdentity := AIdentity;
end;
function TConstantNode.AsConstant: IConstantNode;
begin
Result := Self;
end;
function TConstantNode.GetKind: TAstNodeKind;
begin
Result := akConstant;
end;
function TConstantNode.GetValue: TDataValue;
begin
Result := FConstIdentity.Value;
end;
{ TIdentifierNode }
constructor TIdentifierNode.Create(const AIdentity: INamedIdentity; const AAddress: TResolvedAddress; const AStaticType: IStaticType);
begin
inherited Create(AStaticType, AIdentity);
FNamedIdentity := AIdentity;
FAddress := AAddress;
end;
function TIdentifierNode.AsIdentifier: IIdentifierNode;
begin
Result := Self;
end;
function TIdentifierNode.GetAddress: TResolvedAddress;
begin
Result := FAddress;
end;
function TIdentifierNode.GetKind: TAstNodeKind;
begin
Result := akIdentifier;
end;
function TIdentifierNode.GetName: string;
begin
Result := FNamedIdentity.Name;
end;
{ TKeywordNode }
constructor TKeywordNode.Create(const AIdentity: IKeywordIdentity);
begin
inherited Create(TTypes.Keyword, AIdentity);
FKeywordIdentity := AIdentity;
end;
function TKeywordNode.AsKeyword: IKeywordNode;
begin
Result := Self;
end;
function TKeywordNode.GetKind: TAstNodeKind;
begin
Result := akKeyword;
end;
function TKeywordNode.GetValue: IKeyword;
begin
Result := FKeywordIdentity.Value;
end;
{ TTupleNode }
constructor TTupleNode.Create(const AElements: TArray<IAstNode>; const AIdentity: IAstIdentity; const AStaticType: IStaticType);
begin
inherited Create(AStaticType, AIdentity);
FElements := AElements;
end;
function TTupleNode.AsTuple: ITupleNode;
begin
Result := Self;
end;
function TTupleNode.GetElements: TArray<IAstNode>;
begin
Result := FElements;
end;
function TTupleNode.GetKind: TAstNodeKind;
begin
Result := akTuple;
end;
{ TCreateSeriesNode }
constructor TCreateSeriesNode.Create(
const ADefinitionNode: IAstNode;
const ARecordDefinition: IScalarRecordDefinition;
const AStaticType: IStaticType;
const AIdentity: IAstIdentity
);
begin
inherited Create(AStaticType, AIdentity);
FDefinitionNode := ADefinitionNode;
FRecordDefinition := ARecordDefinition;
end;
function TCreateSeriesNode.AsCreateSeries: ICreateSeriesNode;
begin
Result := Self;
end;
function TCreateSeriesNode.GetDefinitionNode: IAstNode;
begin
Result := FDefinitionNode;
end;
function TCreateSeriesNode.GetRecordDefinition: IScalarRecordDefinition;
begin
Result := FRecordDefinition;
end;
function TCreateSeriesNode.GetKind: TAstNodeKind;
begin
Result := akCreateSeries;
end;
{ TIfExpressionNode }
constructor TIfExpressionNode.Create(
const ACondition, AThenBranch, AElseBranch: IAstNode;
const AStaticType: IStaticType;
const AIdentity: IAstIdentity
);
begin
inherited Create(AStaticType, AIdentity);
FCondition := ACondition;
FThenBranch := AThenBranch;
FElseBranch := AElseBranch;
end;
function TIfExpressionNode.AsIfExpression: IIfExpressionNode;
begin
Result := Self;
end;
function TIfExpressionNode.GetCondition: IAstNode;
begin
Result := FCondition;
end;
function TIfExpressionNode.GetThenBranch: IAstNode;
begin
Result := FThenBranch;
end;
function TIfExpressionNode.GetElseBranch: IAstNode;
begin
Result := FElseBranch;
end;
function TIfExpressionNode.GetKind: TAstNodeKind;
begin
Result := akIfExpression;
end;
{ TCondExpressionNode }
constructor TCondExpressionNode.Create(
const APairs: TArray<TCondPair>;
const AElseBranch: IAstNode;
const AStaticType: IStaticType;
const AIdentity: IAstIdentity
);
begin
inherited Create(AStaticType, AIdentity);
FPairs := APairs;
FElseBranch := AElseBranch;
end;
function TCondExpressionNode.AsCondExpression: ICondExpressionNode;
begin
Result := Self;
end;
function TCondExpressionNode.GetPairs: TArray<TCondPair>;
begin
Result := FPairs;
end;
function TCondExpressionNode.GetElseBranch: IAstNode;
begin
Result := FElseBranch;
end;
function TCondExpressionNode.GetKind: TAstNodeKind;
begin
Result := akCondExpression;
end;
{ TLambdaExpressionNode }
constructor TLambdaExpressionNode.Create(
const AParameters: ITupleNode;
const ABody: IAstNode;
const AStaticType: IStaticType;
const ALayout: IScopeLayout;
const ADescriptor: IScopeDescriptor;
const AUpvalues: TArray<TResolvedAddress>;
const AHasNestedLambdas, AIsPure: Boolean;
const AIdentity: IAstIdentity
);
begin
inherited Create(AStaticType, AIdentity);
Assert(Assigned(AParameters));
Assert(Assigned(ABody));
FParameters := AParameters;
FBody := ABody;
FLayout := ALayout;
FDescriptor := ADescriptor;
FUpvalues := AUpvalues;
FHasNestedLambdas := AHasNestedLambdas;
FIsPure := AIsPure;
end;
function TLambdaExpressionNode.AsLambdaExpression: ILambdaExpressionNode;
begin
Result := Self;
end;
function TLambdaExpressionNode.GetBody: IAstNode;
begin
Result := FBody;
end;
function TLambdaExpressionNode.GetParameters: ITupleNode;
begin
Result := FParameters;
end;
function TLambdaExpressionNode.GetLayout: IScopeLayout;
begin
Result := FLayout;
end;
function TLambdaExpressionNode.GetDescriptor: IScopeDescriptor;
begin
Result := FDescriptor;
end;
function TLambdaExpressionNode.GetUpvalues: TArray<TResolvedAddress>;
begin
Result := FUpvalues;
end;
function TLambdaExpressionNode.GetHasNestedLambdas: Boolean;
begin
Result := FHasNestedLambdas;
end;
function TLambdaExpressionNode.GetIsPure: Boolean;
begin
Result := FIsPure;
end;
function TLambdaExpressionNode.GetKind: TAstNodeKind;
begin
Result := akLambdaExpression;
end;
{ TFunctionCallNode }
constructor TFunctionCallNode.Create(
const ACallee: IAstNode;
const AArguments: ITupleNode;
const AStaticType: IStaticType;
const AIsTailCall: Boolean;
const AStaticTarget: TDataValue.TFunc;
const AIsTargetPure: Boolean;
const AIdentity: IAstIdentity
);
begin
inherited Create(AStaticType, AIdentity);
FCallee := ACallee;
FArguments := AArguments;
FIsTailCall := AIsTailCall;
FStaticTarget := AStaticTarget;
FIsTargetPure := AIsTargetPure;
end;
function TFunctionCallNode.AsFunctionCall: IFunctionCallNode;
begin
Result := Self;
end;
function TFunctionCallNode.GetCallee: IAstNode;
begin
Result := FCallee;
end;
function TFunctionCallNode.GetArguments: ITupleNode;
begin
Result := FArguments;
end;
function TFunctionCallNode.GetIsTailCall: Boolean;
begin
Result := FIsTailCall;
end;
function TFunctionCallNode.GetStaticTarget: TDataValue.TFunc;
begin
Result := FStaticTarget;
end;
function TFunctionCallNode.GetIsTargetPure: Boolean;
begin
Result := FIsTargetPure;
end;
function TFunctionCallNode.GetKind: TAstNodeKind;
begin
Result := akFunctionCall;
end;
{ TMacroDefinitionNode }
constructor TMacroDefinitionNode.Create(
const AName: IIdentifierNode;
const AParameters: ITupleNode;
const ABody: IAstNode;
const AIdentity: IAstIdentity
);
begin
inherited Create(TTypes.Void, AIdentity);
FName := AName;
FParameters := AParameters;
FBody := ABody;
end;
function TMacroDefinitionNode.AsMacroDefinition: IMacroDefinitionNode;
begin
Result := Self;
end;
function TMacroDefinitionNode.GetName: IIdentifierNode;
begin
Result := FName;
end;
function TMacroDefinitionNode.GetParameters: ITupleNode;
begin
Result := FParameters;
end;
function TMacroDefinitionNode.GetBody: IAstNode;
begin
Result := FBody;
end;
function TMacroDefinitionNode.GetKind: TAstNodeKind;
begin
Result := akMacroDefinition;
end;
{ TMacroExpansionNode }
constructor TMacroExpansionNode.Create(const ACallNode: IFunctionCallNode; const AExpandedBody: IAstNode; const AIdentity: IAstIdentity);
begin
if AExpandedBody.IsTyped then
inherited Create(AExpandedBody.AsTypedNode.StaticType, AIdentity)
else
inherited Create(TTypes.Unknown, AIdentity);
FCallNode := ACallNode;
FExpandedBody := AExpandedBody;
end;
function TMacroExpansionNode.AsMacroExpansion: IMacroExpansionNode;
begin
Result := Self;
end;
function TMacroExpansionNode.GetCallNode: IFunctionCallNode;
begin
Result := FCallNode;
end;
function TMacroExpansionNode.GetExpandedBody: IAstNode;
begin
Result := FExpandedBody;
end;
function TMacroExpansionNode.GetKind: TAstNodeKind;
begin
Result := akMacroExpansion;
end;
{ TQuasiquoteNode }
constructor TQuasiquoteNode.Create(const AExpression: IAstNode; const AIdentity: IAstIdentity);
begin
inherited Create(AIdentity);
FExpression := AExpression;
end;
function TQuasiquoteNode.AsQuasiquote: IQuasiquoteNode;
begin
Result := Self;
end;
function TQuasiquoteNode.GetExpression: IAstNode;
begin
Result := FExpression;
end;
function TQuasiquoteNode.GetKind: TAstNodeKind;
begin
Result := akQuasiquote;
end;
{ TUnquoteNode }
constructor TUnquoteNode.Create(const AExpression: IAstNode; const AIdentity: IAstIdentity);
begin
inherited Create(AIdentity);
FExpression := AExpression;
end;
function TUnquoteNode.AsUnquote: IUnquoteNode;
begin
Result := Self;
end;
function TUnquoteNode.GetExpression: IAstNode;
begin
Result := FExpression;
end;
function TUnquoteNode.GetKind: TAstNodeKind;
begin
Result := akUnquote;
end;
{ TUnquoteSplicingNode }
constructor TUnquoteSplicingNode.Create(const AExpression: IQuasiquoteNode; const AIdentity: IAstIdentity);
begin
inherited Create(AIdentity);
FExpression := AExpression;
end;
function TUnquoteSplicingNode.AsUnquoteSplicing: IUnquoteSplicingNode;
begin
Result := Self;
end;
function TUnquoteSplicingNode.GetExpression: IQuasiquoteNode;
begin
Result := FExpression;
end;
function TUnquoteSplicingNode.GetKind: TAstNodeKind;
begin
Result := akUnquoteSplicing;
end;
{ TRecurNode }
constructor TRecurNode.Create(const AArguments: ITupleNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity);
begin
inherited Create(AStaticType, AIdentity);
FArguments := AArguments;
end;
function TRecurNode.AsRecur: IRecurNode;
begin
Result := Self;
end;
function TRecurNode.GetArguments: ITupleNode;
begin
Result := FArguments;
end;
function TRecurNode.GetKind: TAstNodeKind;
begin
Result := akRecur;
end;
{ TBlockExpressionNode }
constructor TBlockExpressionNode.Create(const AExpressions: ITupleNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity);
begin
inherited Create(AStaticType, AIdentity);
FExpressions := AExpressions;
end;
function TBlockExpressionNode.AsBlockExpression: IBlockExpressionNode;
begin
Result := Self;
end;
function TBlockExpressionNode.GetExpressions: ITupleNode;
begin
Result := FExpressions;
end;
function TBlockExpressionNode.GetKind: TAstNodeKind;
begin
Result := akBlockExpression;
end;
{ TVariableDeclarationNode }
constructor TVariableDeclarationNode.Create(
const ATarget: IAstNode;
AInitializer: IAstNode;
const AStaticType: IStaticType;
const AIsBoxed: Boolean;
const AIdentity: IAstIdentity
);
begin
inherited Create(AStaticType, AIdentity);
FTarget := ATarget;
FInitializer := AInitializer;
FIsBoxed := AIsBoxed;
end;
function TVariableDeclarationNode.AsVariableDeclaration: IVariableDeclarationNode;
begin
Result := Self;
end;
function TVariableDeclarationNode.GetTarget: IAstNode;
begin
Result := FTarget;
end;
function TVariableDeclarationNode.GetInitializer: IAstNode;
begin
Result := FInitializer;
end;
function TVariableDeclarationNode.GetIsBoxed: Boolean;
begin
Result := FIsBoxed;
end;
function TVariableDeclarationNode.GetKind: TAstNodeKind;
begin
Result := akVariableDeclaration;
end;
{ TAssignmentNode }
constructor TAssignmentNode.Create(const ATarget, AValue: IAstNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity);
begin
inherited Create(AStaticType, AIdentity);
FTarget := ATarget;
FValue := AValue;
end;
function TAssignmentNode.AsAssignment: IAssignmentNode;
begin
Result := Self;
end;
function TAssignmentNode.GetTarget: IAstNode;
begin
Result := FTarget;
end;
function TAssignmentNode.GetValue: IAstNode;
begin
Result := FValue;
end;
function TAssignmentNode.GetKind: TAstNodeKind;
begin
Result := akAssignment;
end;
{ TIndexerNode }
constructor TIndexerNode.Create(const ABase, AIndex: IAstNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity);
begin
inherited Create(AStaticType, AIdentity);
FBase := ABase;
FIndex := AIndex;
end;
function TIndexerNode.AsIndexer: IIndexerNode;
begin
Result := Self;
end;
function TIndexerNode.GetBase: IAstNode;
begin
Result := FBase;
end;
function TIndexerNode.GetIndex: IAstNode;
begin
Result := FIndex;
end;
function TIndexerNode.GetKind: TAstNodeKind;
begin
Result := akIndexer;
end;
{ TMemberAccessNode }
constructor TMemberAccessNode.Create(
const ABase: IAstNode;
const AMember: IKeywordNode;
const AStaticType: IStaticType;
const AIdentity: IAstIdentity
);
begin
inherited Create(AStaticType, AIdentity);
FBase := ABase;
FMember := AMember;
end;
function TMemberAccessNode.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: ITupleNode;
const AScalarDef: IScalarRecordDefinition;
const AGenericDef: IGenericRecordDefinition;
const AStaticType: IStaticType;
const AIdentity: IAstIdentity
);
begin
inherited Create(AStaticType, AIdentity);
FFields := AFields;
FScalarDef := AScalarDef;
FGenericDef := AGenericDef;
end;
function TRecordLiteralNode.AsRecordLiteral: IRecordLiteralNode;
begin
Result := Self;
end;
function TRecordLiteralNode.GetFields: ITupleNode;
begin
Result := FFields;
end;
function TRecordLiteralNode.GetGenericDefinition: IGenericRecordDefinition;
begin
Result := FGenericDef;
end;
function TRecordLiteralNode.GetScalarDefinition: IScalarRecordDefinition;
begin
Result := FScalarDef;
end;
function TRecordLiteralNode.GetKind: TAstNodeKind;
begin
Result := akRecordLiteral;
end;
{ TAddSeriesItemNode }
constructor TAddSeriesItemNode.Create(
const ASeries: IIdentifierNode;
const AValue, ALookback: IAstNode;
const AStaticType: IStaticType;
const AIdentity: IAstIdentity
);
begin
inherited Create(AStaticType, AIdentity);
FSeries := ASeries;
FValue := AValue;
FLookback := ALookback;
end;
function TAddSeriesItemNode.AsAddSeriesItem: IAddSeriesItemNode;
begin
Result := Self;
end;
function TAddSeriesItemNode.GetSeries: IIdentifierNode;
begin
Result := FSeries;
end;
function TAddSeriesItemNode.GetValue: IAstNode;
begin
Result := FValue;
end;
function TAddSeriesItemNode.GetLookback: IAstNode;
begin
Result := FLookback;
end;
function TAddSeriesItemNode.GetKind: TAstNodeKind;
begin
Result := akAddSeriesItem;
end;
{ TSeriesLengthNode }
constructor TSeriesLengthNode.Create(const ASeries: IIdentifierNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity);
begin
inherited Create(AStaticType, AIdentity);
FSeries := ASeries;
end;
function TSeriesLengthNode.AsSeriesLength: ISeriesLengthNode;
begin
Result := Self;
end;
function TSeriesLengthNode.GetSeries: IIdentifierNode;
begin
Result := FSeries;
end;
function TSeriesLengthNode.GetKind: TAstNodeKind;
begin
Result := akSeriesLength;
end;
{ TNopNode }
constructor TNopNode.Create(const AStaticType: IStaticType; const AIdentity: IAstIdentity);
begin
inherited Create(AStaticType, AIdentity);
end;
function TNopNode.AsNop: INopNode;
begin
Result := Self;
end;
function TNopNode.GetKind: TAstNodeKind;
begin
Result := akNop;
end;
{ TPipeNode }
constructor TPipeNode.Create(
const AInputs: ITupleNode;
const ATransformation: ILambdaExpressionNode;
const AIdentity: IAstIdentity;
const AStaticType: IStaticType
);
begin
inherited Create(AStaticType, AIdentity);
FInputs := AInputs;
FTransformation := ATransformation;
end;
function TPipeNode.AsPipe: IPipeNode;
begin
Result := Self;
end;
function TPipeNode.GetInputs: ITupleNode;
begin
Result := FInputs;
end;
function TPipeNode.GetKind: TAstNodeKind;
begin
Result := akPipe;
end;
function TPipeNode.GetTransformation: ILambdaExpressionNode;
begin
Result := FTransformation;
end;
end.
//==================================================================================================
//== FULL UNIT END: Myc.Ast.Nodes
//==================================================================================================