2132 lines
61 KiB
ObjectPascal
2132 lines
61 KiB
ObjectPascal
unit Myc.Ast.Nodes;
|
|
|
|
{$M+} // Enable RTTI for all interfaces and enums
|
|
|
|
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;
|
|
|
|
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;
|
|
|
|
IConstantNode = interface;
|
|
IIdentifierNode = interface;
|
|
IKeywordNode = interface;
|
|
ITupleNode = interface;
|
|
IRecordFieldNode = interface;
|
|
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;
|
|
IPipeNode = interface;
|
|
|
|
TAstNodeKind = (
|
|
akConstant,
|
|
akIdentifier,
|
|
akKeyword,
|
|
akTuple,
|
|
akRecordField,
|
|
akIfExpression,
|
|
akCondExpression,
|
|
akLambdaExpression,
|
|
akFunctionCall,
|
|
akMacroExpansion,
|
|
akBlockExpression,
|
|
akVariableDeclaration,
|
|
akAssignment,
|
|
akMacroDefinition,
|
|
akQuasiquote,
|
|
akUnquote,
|
|
akUnquoteSplicing,
|
|
akIndexer,
|
|
akMemberAccess,
|
|
akRecordLiteral,
|
|
akCreateSeries,
|
|
akAddSeriesItem,
|
|
akSeriesLength,
|
|
akRecur,
|
|
akNop,
|
|
akPipe
|
|
);
|
|
|
|
TAstNodeKindHelper = record helper for TAstNodeKind
|
|
public
|
|
function ToString: string;
|
|
end;
|
|
|
|
TCondPair = record
|
|
Condition: IAstNode;
|
|
Branch: IAstNode;
|
|
constructor Create(const ACondition, ABranch: IAstNode);
|
|
end;
|
|
|
|
IAstNode = interface
|
|
{$region 'private'}
|
|
function GetKind: TAstNodeKind;
|
|
function GetIsTyped: Boolean;
|
|
function GetIdentity: IAstIdentity;
|
|
{$endregion}
|
|
function Accept(const Visitor: IAstVisitor): TDataValue;
|
|
|
|
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;
|
|
|
|
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;
|
|
|
|
// --- Specialized Node Interfaces with Examples and Docs ---
|
|
|
|
[AstTag('Nop')]
|
|
[AstDoc('A placeholder that performs no action.')]
|
|
[AstExample('["Nop"]')]
|
|
INopNode = interface(IAstTypedNode)
|
|
end;
|
|
|
|
[AstTag('Const')]
|
|
[AstDoc('A literal value (number, string, or boolean).')]
|
|
[AstExample('["Const", 42]')]
|
|
[AstExample('["Const", "Myc"]')]
|
|
[AstField(0, 'value', fkValue)]
|
|
IConstantNode = interface(IAstTypedNode)
|
|
{$region 'private'}
|
|
function GetValue: TDataValue;
|
|
{$endregion}
|
|
property Value: TDataValue read GetValue;
|
|
end;
|
|
|
|
[AstTag('Id')]
|
|
[AstDoc('A name referring to a variable, parameter or function.')]
|
|
[AstExample('["Id", "x"]')]
|
|
[AstField(0, 'name', fkString)]
|
|
IIdentifierNode = interface(IAstTypedNode)
|
|
{$region 'private'}
|
|
function GetAddress: TResolvedAddress;
|
|
function GetName: string;
|
|
{$endregion}
|
|
property Address: TResolvedAddress read GetAddress;
|
|
property Name: string read GetName;
|
|
end;
|
|
|
|
[AstTag('Key')]
|
|
[AstDoc('An interned keyword literal.')]
|
|
[AstExample('["Key", "volume"]')]
|
|
[AstField(0, 'name', fkString)]
|
|
IKeywordNode = interface(IAstTypedNode)
|
|
{$region 'private'}
|
|
function GetValue: IKeyword;
|
|
{$endregion}
|
|
property Value: IKeyword read GetValue;
|
|
end;
|
|
|
|
[AstTag('Tuple')]
|
|
[AstDoc('A positional collection of elements (Vector).')]
|
|
[AstExample('["Tuple", [["Const", 1], ["Id", "y"]]]')]
|
|
[AstField(0, 'elements', fkNode)]
|
|
ITupleNode = interface(IAstTypedNode)
|
|
{$region 'private'}
|
|
function GetElements: TArray<IAstNode>;
|
|
{$endregion}
|
|
property Elements: TArray<IAstNode> read GetElements;
|
|
end;
|
|
|
|
[AstTag('Field')]
|
|
[AstDoc('A single entry in a record literal.')]
|
|
[AstField(0, 'key', fkNode)]
|
|
[AstField(1, 'value', fkNode)]
|
|
IRecordFieldNode = interface(IAstNode)
|
|
{$region 'private'}
|
|
function GetKey: IKeywordNode;
|
|
function GetValue: IAstNode;
|
|
{$endregion}
|
|
property Key: IKeywordNode read GetKey;
|
|
property Value: IAstNode read GetValue;
|
|
end;
|
|
|
|
[AstTag('If')]
|
|
[AstDoc('Conditional ternary expression.')]
|
|
[
|
|
AstExample(
|
|
'''
|
|
["If",
|
|
["Call", ["Id", ">"], ["Tuple", [["Id", "x"], ["Const", 0]]]],
|
|
["Const", "ok"],
|
|
["Const", "fail"]
|
|
]
|
|
'''
|
|
)
|
|
]
|
|
[AstField(0, 'cond', fkNode)]
|
|
[AstField(1, 'then', fkNode)]
|
|
[AstField(2, 'else', fkNullableNode)]
|
|
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;
|
|
|
|
[AstTag('Cond')]
|
|
[AstDoc('Multi-branch condition. Pairs are [ [cond, branch], ... ].')]
|
|
[
|
|
AstExample(
|
|
'''
|
|
["Cond",
|
|
[
|
|
[["Call", ["Id", "="], ["Tuple", [["Id", "s"], ["Const", 1]]]], ["Key", "up"]],
|
|
[["Call", ["Id", "="], ["Tuple", [["Id", "s"], ["Const", 2]]]], ["Key", "down"]]
|
|
],
|
|
["Key", "flat"]
|
|
]
|
|
'''
|
|
)
|
|
]
|
|
[AstField(0, 'pairs', fkArrayOfPairs)]
|
|
[AstField(1, 'else', fkNullableNode)]
|
|
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;
|
|
|
|
[AstTag('Fn')]
|
|
[AstDoc('Anonymous function definition (lambda).')]
|
|
[
|
|
AstExample(
|
|
'''
|
|
["Fn",
|
|
["Tuple", [["Id", "a"], ["Id", "b"]]],
|
|
["Call", ["Id", "+"], ["Tuple", [["Id", "a"], ["Id", "b"]]]]
|
|
]
|
|
'''
|
|
)
|
|
]
|
|
[AstField(0, 'params', fkTuple)]
|
|
[AstField(1, 'body', fkNode)]
|
|
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;
|
|
|
|
[AstTag('Call')]
|
|
[AstDoc('Function or operator invocation.')]
|
|
[AstExample('["Call", ["Id", "abs"], ["Tuple", [["Const", -5]]]]')]
|
|
[AstField(0, 'callee', fkNode)]
|
|
[AstField(1, 'args', fkTuple)]
|
|
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;
|
|
|
|
[AstTag('Block')]
|
|
[AstDoc('Sequential execution of nodes.')]
|
|
[
|
|
AstExample(
|
|
'''
|
|
["Block", ["Tuple", [
|
|
["Var", ["Id", "a"], ["Const", 1]],
|
|
["Assign", ["Id", "a"], ["Call", ["Id", "+"], ["Tuple", [["Id", "a"], ["Const", 1]]]]],
|
|
["Id", "a"]
|
|
]]]
|
|
'''
|
|
)
|
|
]
|
|
[AstField(0, 'expressions', fkTuple)]
|
|
IBlockExpressionNode = interface(IAstTypedNode)
|
|
{$region 'private'}
|
|
function GetExpressions: ITupleNode;
|
|
{$endregion}
|
|
property Expressions: ITupleNode read GetExpressions;
|
|
end;
|
|
|
|
[AstTag('Var')]
|
|
[AstDoc('Variable declaration.')]
|
|
[AstExample('["Var", ["Id", "val"], ["Const", 0]]')]
|
|
[AstField(0, 'target', fkNode)]
|
|
[AstField(1, 'init', fkNullableNode)]
|
|
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;
|
|
|
|
[AstTag('Assign')]
|
|
[AstDoc('Variable assignment.')]
|
|
[AstExample('["Assign", ["Id", "x"], ["Const", 1]]')]
|
|
[AstField(0, 'target', fkNode)]
|
|
[AstField(1, 'value', fkNode)]
|
|
IAssignmentNode = interface(IAstTypedNode)
|
|
{$region 'private'}
|
|
function GetTarget: IAstNode;
|
|
function GetValue: IAstNode;
|
|
{$endregion}
|
|
property Target: IAstNode read GetTarget;
|
|
property Value: IAstNode read GetValue;
|
|
end;
|
|
|
|
[AstTag('Macro')]
|
|
[AstDoc('Syntactic macro definition.')]
|
|
[
|
|
AstExample(
|
|
'''
|
|
["Macro",
|
|
["Id", "unless"],
|
|
["Tuple", [["Id", "condition"], ["Id", "body"]]],
|
|
["Quote", ["If", ["Id", "condition"], ["Nop"], ["Unquote", ["Id", "body"]]]]
|
|
]
|
|
'''
|
|
)
|
|
]
|
|
[AstField(0, 'name', fkNode)]
|
|
[AstField(1, 'params', fkTuple)]
|
|
[AstField(2, 'body', fkNode)]
|
|
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;
|
|
|
|
[AstTag('Quote')]
|
|
[AstDoc('Suppresses evaluation of an expression.')]
|
|
[AstField(0, 'expr', fkNode)]
|
|
IQuasiquoteNode = interface(IAstNode)
|
|
{$region 'private'}
|
|
function GetExpression: IAstNode;
|
|
{$endregion}
|
|
property Expression: IAstNode read GetExpression;
|
|
end;
|
|
|
|
[AstTag('Unquote')]
|
|
[AstDoc('Enables evaluation inside a quoted context.')]
|
|
[AstField(0, 'expr', fkNode)]
|
|
IUnquoteNode = interface(IAstNode)
|
|
{$region 'private'}
|
|
function GetExpression: IAstNode;
|
|
{$endregion}
|
|
property Expression: IAstNode read GetExpression;
|
|
end;
|
|
|
|
[AstTag('Splice')]
|
|
[AstDoc('Splicing evaluation into a list.')]
|
|
[AstField(0, 'expr', fkNode)]
|
|
IUnquoteSplicingNode = interface(IAstNode)
|
|
{$region 'private'}
|
|
function GetExpression: IQuasiquoteNode;
|
|
{$endregion}
|
|
property Expression: IQuasiquoteNode read GetExpression;
|
|
end;
|
|
|
|
[AstTag('Index')]
|
|
[AstDoc('Element access by position.')]
|
|
[AstExample('["Index", ["Id", "v"], ["Const", 0]]')]
|
|
[AstField(0, 'base', fkNode)]
|
|
[AstField(1, 'index', fkNode)]
|
|
IIndexerNode = interface(IAstTypedNode)
|
|
{$region 'private'}
|
|
function GetBase: IAstNode;
|
|
function GetIndex: IAstNode;
|
|
{$endregion}
|
|
property Base: IAstNode read GetBase;
|
|
property Index: IAstNode read GetIndex;
|
|
end;
|
|
|
|
[AstTag('Member')]
|
|
[AstDoc('Field access by keyword.')]
|
|
[AstExample('["Member", ["Id", "rec"], ["Key", "price"]]')]
|
|
[AstField(0, 'base', fkNode)]
|
|
[AstField(1, 'member', fkNode)]
|
|
IMemberAccessNode = interface(IAstTypedNode)
|
|
{$region 'private'}
|
|
function GetBase: IAstNode;
|
|
function GetMember: IKeywordNode;
|
|
{$endregion}
|
|
property Base: IAstNode read GetBase;
|
|
property Member: IKeywordNode read GetMember;
|
|
end;
|
|
|
|
[AstTag('Record')]
|
|
[AstDoc('Defines a record literal.')]
|
|
[
|
|
AstExample(
|
|
'''
|
|
["Record", ["Tuple", [
|
|
["Field", ["Key", "p"], ["Id", "p_val"]],
|
|
["Field", ["Key", "q"], ["Const", 100]]
|
|
]]]
|
|
'''
|
|
)
|
|
]
|
|
[AstField(0, 'fields', fkTuple)]
|
|
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;
|
|
|
|
[AstTag('Series')]
|
|
[AstDoc('Stream schema definition.')]
|
|
[AstExample('["Series", ["Key", "Float"]]')]
|
|
[AstField(0, 'definition', fkNode)]
|
|
ICreateSeriesNode = interface(IAstTypedNode)
|
|
{$region 'private'}
|
|
function GetDefinitionNode: IAstNode;
|
|
function GetRecordDefinition: IScalarRecordDefinition;
|
|
{$endregion}
|
|
property DefinitionNode: IAstNode read GetDefinitionNode;
|
|
property RecordDefinition: IScalarRecordDefinition read GetRecordDefinition;
|
|
end;
|
|
|
|
[AstTag('Add')]
|
|
[AstDoc('Pushes data to a series.')]
|
|
[AstExample('["Add", ["Id", "s"], ["Const", 10]]')]
|
|
[AstField(0, 'series', fkNode)]
|
|
[AstField(1, 'value', fkNode)]
|
|
[AstField(2, 'lookback', fkNullableNode)]
|
|
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;
|
|
|
|
[AstTag('Count')]
|
|
[AstDoc('Series length.')]
|
|
[AstExample('["Count", ["Id", "src"]]')]
|
|
[AstField(0, 'series', fkNode)]
|
|
ISeriesLengthNode = interface(IAstTypedNode)
|
|
{$region 'private'}
|
|
function GetSeries: IIdentifierNode;
|
|
{$endregion}
|
|
property Series: IIdentifierNode read GetSeries;
|
|
end;
|
|
|
|
[AstTag('Recur')]
|
|
[AstDoc('Tail-recursive jump.')]
|
|
[AstExample('["Recur", ["Tuple", [["Call", ["Id", "-"], ["Tuple", [["Id", "i"], ["Const", 1]]]]]]]')]
|
|
[AstField(0, 'args', fkTuple)]
|
|
IRecurNode = interface(IAstTypedNode)
|
|
{$region 'private'}
|
|
function GetArguments: ITupleNode;
|
|
{$endregion}
|
|
property Arguments: ITupleNode read GetArguments;
|
|
end;
|
|
|
|
[AstTag('Pipe')]
|
|
[AstDoc('Reactive pipeline from source streams to a transformation lambda.')]
|
|
[
|
|
AstExample(
|
|
'''
|
|
["Pipe",
|
|
["Tuple", [
|
|
["Tuple", [["Id", "src"], ["Tuple", [["Key", "price"]]]]]
|
|
]],
|
|
["Fn", ["Tuple", [["Id", "p"]]],
|
|
["Record", ["Tuple", [
|
|
["Field", ["Key", "res"], ["Call", ["Id", "*"], ["Tuple", [["Id", "p"], ["Const", 2]]]]]
|
|
]]]
|
|
]
|
|
]
|
|
'''
|
|
)
|
|
]
|
|
[AstField(0, 'inputs', fkTuple)]
|
|
[AstField(1, 'transform', fkNode)]
|
|
IPipeNode = interface(IAstTypedNode)
|
|
{$region 'private'}
|
|
function GetInputs: ITupleNode;
|
|
function GetTransformation: ILambdaExpressionNode;
|
|
{$endregion}
|
|
property Inputs: ITupleNode read GetInputs;
|
|
property Transformation: ILambdaExpressionNode read GetTransformation;
|
|
end;
|
|
|
|
IMacroExpansionNode = interface(IAstTypedNode)
|
|
{$region 'private'}
|
|
function GetCallNode: IFunctionCallNode;
|
|
function GetExpandedBody: IAstNode;
|
|
{$endregion}
|
|
property CallNode: IFunctionCallNode read GetCallNode;
|
|
property ExpandedBody: IAstNode read GetExpandedBody;
|
|
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;
|
|
|
|
// --- Base Implementations ---
|
|
|
|
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 AsTypedNode: IAstTypedNode; virtual;
|
|
function AsConstant: IConstantNode; virtual;
|
|
function AsIdentifier: IIdentifierNode; virtual;
|
|
function AsKeyword: IKeywordNode; virtual;
|
|
function AsTuple: ITupleNode; virtual;
|
|
function AsRecordField: IRecordFieldNode; 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;
|
|
|
|
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;
|
|
|
|
// --- Core Node Concrete Implementations ---
|
|
|
|
TConstantNode = class(TAstTypedNode, IConstantNode)
|
|
private
|
|
FConstIdentity: IConstantIdentity;
|
|
function GetValue: TDataValue;
|
|
protected
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AIdentity: IConstantIdentity; const AStaticType: IStaticType);
|
|
function AsConstant: IConstantNode; override;
|
|
end;
|
|
|
|
TIdentifierNode = class(TAstTypedNode, IIdentifierNode)
|
|
private
|
|
FNamedIdentity: INamedIdentity;
|
|
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;
|
|
|
|
TKeywordNode = class(TAstTypedNode, IKeywordNode)
|
|
private
|
|
FKeywordIdentity: IKeywordIdentity;
|
|
function GetValue: IKeyword;
|
|
protected
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AIdentity: IKeywordIdentity);
|
|
function AsKeyword: IKeywordNode; override;
|
|
end;
|
|
|
|
TTupleNode = class(TAstTypedNode, ITupleNode)
|
|
private
|
|
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;
|
|
|
|
TRecordFieldNode = class(TAstNode, IRecordFieldNode)
|
|
private
|
|
FKey: IKeywordNode;
|
|
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;
|
|
|
|
TIfExpressionNode = class(TAstTypedNode, IIfExpressionNode)
|
|
private
|
|
FCondition, FThenBranch, 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;
|
|
|
|
TCondExpressionNode = class(TAstTypedNode, ICondExpressionNode)
|
|
private
|
|
FPairs: TArray<TCondPair>;
|
|
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;
|
|
|
|
TLambdaExpressionNode = class(TAstTypedNode, ILambdaExpressionNode, IFunctionDefinition)
|
|
private
|
|
FParameters: ITupleNode;
|
|
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;
|
|
|
|
TFunctionCallNode = class(TAstTypedNode, IFunctionCallNode)
|
|
private
|
|
FCallee: IAstNode;
|
|
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;
|
|
|
|
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;
|
|
|
|
TBlockExpressionNode = class(TAstTypedNode, IBlockExpressionNode)
|
|
private
|
|
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;
|
|
|
|
TVariableDeclarationNode = class(TAstTypedNode, IVariableDeclarationNode)
|
|
private
|
|
FTarget, 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;
|
|
|
|
TAssignmentNode = class(TAstTypedNode, IAssignmentNode)
|
|
private
|
|
FTarget, 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;
|
|
|
|
TMacroDefinitionNode = class(TAstTypedNode, IMacroDefinitionNode)
|
|
private
|
|
FName: IIdentifierNode;
|
|
FParameters: ITupleNode;
|
|
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;
|
|
|
|
TQuasiquoteNode = class(TAstNode, IQuasiquoteNode)
|
|
private
|
|
FExpression: IAstNode;
|
|
function GetExpression: IAstNode;
|
|
protected
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AExpression: IAstNode; const AIdentity: IAstIdentity);
|
|
function AsQuasiquote: IQuasiquoteNode; override;
|
|
end;
|
|
|
|
TUnquoteNode = class(TAstNode, IUnquoteNode)
|
|
private
|
|
FExpression: IAstNode;
|
|
function GetExpression: IAstNode;
|
|
protected
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AExpression: IAstNode; const AIdentity: IAstIdentity);
|
|
function AsUnquote: IUnquoteNode; override;
|
|
end;
|
|
|
|
TUnquoteSplicingNode = class(TAstNode, IUnquoteSplicingNode)
|
|
private
|
|
FExpression: IQuasiquoteNode;
|
|
function GetExpression: IQuasiquoteNode;
|
|
protected
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AExpression: IQuasiquoteNode; const AIdentity: IAstIdentity);
|
|
function AsUnquoteSplicing: IUnquoteSplicingNode; override;
|
|
end;
|
|
|
|
TIndexerNode = class(TAstTypedNode, IIndexerNode)
|
|
private
|
|
FBase, 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;
|
|
|
|
TMemberAccessNode = class(TAstTypedNode, IMemberAccessNode)
|
|
private
|
|
FBase: IAstNode;
|
|
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;
|
|
|
|
TRecordLiteralNode = class(TAstTypedNode, IRecordLiteralNode)
|
|
private
|
|
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;
|
|
|
|
TCreateSeriesNode = class(TAstTypedNode, ICreateSeriesNode)
|
|
private
|
|
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;
|
|
|
|
TAddSeriesItemNode = class(TAstTypedNode, IAddSeriesItemNode)
|
|
private
|
|
FSeries: IIdentifierNode;
|
|
FValue, 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;
|
|
|
|
TSeriesLengthNode = class(TAstTypedNode, ISeriesLengthNode)
|
|
private
|
|
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;
|
|
|
|
TRecurNode = class(TAstTypedNode, IRecurNode)
|
|
private
|
|
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;
|
|
|
|
TNopNode = class(TAstTypedNode, INopNode)
|
|
protected
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AStaticType: IStaticType; const AIdentity: IAstIdentity);
|
|
function AsNop: INopNode; override;
|
|
end;
|
|
|
|
TPipeNode = class(TAstTypedNode, IPipeNode)
|
|
private
|
|
FInputs: ITupleNode;
|
|
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.rtti,
|
|
system.strutils,
|
|
system.typinfo;
|
|
|
|
{ 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)).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
|
|
location := Node.Identity.Location.ToString + ' '
|
|
else if Assigned(Node) and Assigned(Node.Identity) then
|
|
location := '[' + Node.Identity.ToString + '] ';
|
|
|
|
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;
|
|
begin
|
|
for var entry in FEntries do
|
|
if entry.Level = elError then
|
|
exit(True);
|
|
Result := False;
|
|
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>);
|
|
begin
|
|
inherited Create(Format('Compilation failed with %d error(s).', [Length(AErrors)]));
|
|
FErrors := AErrors;
|
|
end;
|
|
|
|
function ECompilationFailed.ToString: string;
|
|
var
|
|
sb: TStringBuilder;
|
|
begin
|
|
sb := TStringBuilder.Create;
|
|
try
|
|
sb.AppendLine(inherited Message);
|
|
for var err in FErrors do
|
|
sb.AppendLine(' - ' + err.ToString);
|
|
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
|
|
Result := Visitor.Visit(Self);
|
|
end;
|
|
|
|
function TAstNode.AsTypedNode: IAstTypedNode;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
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.AsTuple: ITupleNode;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
function TAstNode.AsRecordField: IRecordFieldNode;
|
|
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.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;
|
|
|
|
{ TConstantNode }
|
|
|
|
constructor TConstantNode.Create(const AIdentity: IConstantIdentity; const AStaticType: IStaticType);
|
|
begin
|
|
inherited Create(AStaticType, AIdentity);
|
|
FConstIdentity := AIdentity;
|
|
end;
|
|
|
|
function TConstantNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akConstant;
|
|
end;
|
|
function TConstantNode.GetValue: TDataValue;
|
|
begin
|
|
Result := FConstIdentity.Value;
|
|
end;
|
|
function TConstantNode.AsConstant: IConstantNode;
|
|
begin
|
|
Result := Self;
|
|
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.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akIdentifier;
|
|
end;
|
|
function TIdentifierNode.GetAddress: TResolvedAddress;
|
|
begin
|
|
Result := FAddress;
|
|
end;
|
|
function TIdentifierNode.GetName: string;
|
|
begin
|
|
Result := FNamedIdentity.Name;
|
|
end;
|
|
function TIdentifierNode.AsIdentifier: IIdentifierNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
{ TKeywordNode }
|
|
|
|
constructor TKeywordNode.Create(const AIdentity: IKeywordIdentity);
|
|
begin
|
|
inherited Create(TTypes.Keyword, AIdentity);
|
|
FKeywordIdentity := AIdentity;
|
|
end;
|
|
|
|
function TKeywordNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akKeyword;
|
|
end;
|
|
function TKeywordNode.GetValue: IKeyword;
|
|
begin
|
|
Result := FKeywordIdentity.Value;
|
|
end;
|
|
function TKeywordNode.AsKeyword: IKeywordNode;
|
|
begin
|
|
Result := Self;
|
|
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.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akTuple;
|
|
end;
|
|
function TTupleNode.GetElements: TArray<IAstNode>;
|
|
begin
|
|
Result := FElements;
|
|
end;
|
|
function TTupleNode.AsTuple: ITupleNode;
|
|
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.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akRecordField;
|
|
end;
|
|
function TRecordFieldNode.GetKey: IKeywordNode;
|
|
begin
|
|
Result := FKey;
|
|
end;
|
|
function TRecordFieldNode.GetValue: IAstNode;
|
|
begin
|
|
Result := FValue;
|
|
end;
|
|
function TRecordFieldNode.AsRecordField: IRecordFieldNode;
|
|
begin
|
|
Result := Self;
|
|
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.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akIfExpression;
|
|
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.AsIfExpression: IIfExpressionNode;
|
|
begin
|
|
Result := Self;
|
|
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.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akCondExpression;
|
|
end;
|
|
function TCondExpressionNode.GetPairs: TArray<TCondPair>;
|
|
begin
|
|
Result := FPairs;
|
|
end;
|
|
function TCondExpressionNode.GetElseBranch: IAstNode;
|
|
begin
|
|
Result := FElseBranch;
|
|
end;
|
|
function TCondExpressionNode.AsCondExpression: ICondExpressionNode;
|
|
begin
|
|
Result := Self;
|
|
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);
|
|
FParameters := AParameters;
|
|
FBody := ABody;
|
|
FLayout := ALayout;
|
|
FDescriptor := ADescriptor;
|
|
FUpvalues := AUpvalues;
|
|
FHasNestedLambdas := AHasNestedLambdas;
|
|
FIsPure := AIsPure;
|
|
end;
|
|
|
|
function TLambdaExpressionNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akLambdaExpression;
|
|
end;
|
|
function TLambdaExpressionNode.GetParameters: ITupleNode;
|
|
begin
|
|
Result := FParameters;
|
|
end;
|
|
function TLambdaExpressionNode.GetBody: IAstNode;
|
|
begin
|
|
Result := FBody;
|
|
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.AsLambdaExpression: ILambdaExpressionNode;
|
|
begin
|
|
Result := Self;
|
|
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.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akFunctionCall;
|
|
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.AsFunctionCall: IFunctionCallNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
{ TMacroExpansionNode }
|
|
|
|
constructor TMacroExpansionNode.Create(const ACallNode: IFunctionCallNode; const AExpandedBody: IAstNode; const AIdentity: IAstIdentity);
|
|
begin
|
|
inherited Create(
|
|
if AExpandedBody.IsTyped then AExpandedBody.AsTypedNode.StaticType
|
|
else TTypes.Unknown,
|
|
AIdentity
|
|
);
|
|
FCallNode := ACallNode;
|
|
FExpandedBody := AExpandedBody;
|
|
end;
|
|
|
|
function TMacroExpansionNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akMacroExpansion;
|
|
end;
|
|
function TMacroExpansionNode.GetCallNode: IFunctionCallNode;
|
|
begin
|
|
Result := FCallNode;
|
|
end;
|
|
function TMacroExpansionNode.GetExpandedBody: IAstNode;
|
|
begin
|
|
Result := FExpandedBody;
|
|
end;
|
|
function TMacroExpansionNode.AsMacroExpansion: IMacroExpansionNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
{ TBlockExpressionNode }
|
|
|
|
constructor TBlockExpressionNode.Create(const AExpressions: ITupleNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity);
|
|
begin
|
|
inherited Create(AStaticType, AIdentity);
|
|
FExpressions := AExpressions;
|
|
end;
|
|
|
|
function TBlockExpressionNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akBlockExpression;
|
|
end;
|
|
function TBlockExpressionNode.GetExpressions: ITupleNode;
|
|
begin
|
|
Result := FExpressions;
|
|
end;
|
|
function TBlockExpressionNode.AsBlockExpression: IBlockExpressionNode;
|
|
begin
|
|
Result := Self;
|
|
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.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akVariableDeclaration;
|
|
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.AsVariableDeclaration: IVariableDeclarationNode;
|
|
begin
|
|
Result := Self;
|
|
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.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akAssignment;
|
|
end;
|
|
function TAssignmentNode.GetTarget: IAstNode;
|
|
begin
|
|
Result := FTarget;
|
|
end;
|
|
function TAssignmentNode.GetValue: IAstNode;
|
|
begin
|
|
Result := FValue;
|
|
end;
|
|
function TAssignmentNode.AsAssignment: IAssignmentNode;
|
|
begin
|
|
Result := Self;
|
|
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.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akMacroDefinition;
|
|
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.AsMacroDefinition: IMacroDefinitionNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
{ TQuasiquoteNode }
|
|
|
|
constructor TQuasiquoteNode.Create(const AExpression: IAstNode; const AIdentity: IAstIdentity);
|
|
begin
|
|
inherited Create(AIdentity);
|
|
FExpression := AExpression;
|
|
end;
|
|
|
|
function TQuasiquoteNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akQuasiquote;
|
|
end;
|
|
function TQuasiquoteNode.GetExpression: IAstNode;
|
|
begin
|
|
Result := FExpression;
|
|
end;
|
|
function TQuasiquoteNode.AsQuasiquote: IQuasiquoteNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
{ TUnquoteNode }
|
|
|
|
constructor TUnquoteNode.Create(const AExpression: IAstNode; const AIdentity: IAstIdentity);
|
|
begin
|
|
inherited Create(AIdentity);
|
|
FExpression := AExpression;
|
|
end;
|
|
|
|
function TUnquoteNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akUnquote;
|
|
end;
|
|
function TUnquoteNode.GetExpression: IAstNode;
|
|
begin
|
|
Result := FExpression;
|
|
end;
|
|
function TUnquoteNode.AsUnquote: IUnquoteNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
{ TUnquoteSplicingNode }
|
|
|
|
constructor TUnquoteSplicingNode.Create(const AExpression: IQuasiquoteNode; const AIdentity: IAstIdentity);
|
|
begin
|
|
inherited Create(AIdentity);
|
|
FExpression := AExpression;
|
|
end;
|
|
|
|
function TUnquoteSplicingNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akUnquoteSplicing;
|
|
end;
|
|
function TUnquoteSplicingNode.GetExpression: IQuasiquoteNode;
|
|
begin
|
|
Result := FExpression;
|
|
end;
|
|
function TUnquoteSplicingNode.AsUnquoteSplicing: IUnquoteSplicingNode;
|
|
begin
|
|
Result := Self;
|
|
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.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akIndexer;
|
|
end;
|
|
function TIndexerNode.GetBase: IAstNode;
|
|
begin
|
|
Result := FBase;
|
|
end;
|
|
function TIndexerNode.GetIndex: IAstNode;
|
|
begin
|
|
Result := FIndex;
|
|
end;
|
|
function TIndexerNode.AsIndexer: IIndexerNode;
|
|
begin
|
|
Result := Self;
|
|
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.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akMemberAccess;
|
|
end;
|
|
function TMemberAccessNode.GetBase: IAstNode;
|
|
begin
|
|
Result := FBase;
|
|
end;
|
|
function TMemberAccessNode.GetMember: IKeywordNode;
|
|
begin
|
|
Result := FMember;
|
|
end;
|
|
function TMemberAccessNode.AsMemberAccess: IMemberAccessNode;
|
|
begin
|
|
Result := Self;
|
|
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.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akRecordLiteral;
|
|
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.AsRecordLiteral: IRecordLiteralNode;
|
|
begin
|
|
Result := Self;
|
|
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.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akCreateSeries;
|
|
end;
|
|
function TCreateSeriesNode.GetDefinitionNode: IAstNode;
|
|
begin
|
|
Result := FDefinitionNode;
|
|
end;
|
|
function TCreateSeriesNode.GetRecordDefinition: IScalarRecordDefinition;
|
|
begin
|
|
Result := FRecordDefinition;
|
|
end;
|
|
function TCreateSeriesNode.AsCreateSeries: ICreateSeriesNode;
|
|
begin
|
|
Result := Self;
|
|
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.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akAddSeriesItem;
|
|
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.AsAddSeriesItem: IAddSeriesItemNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
{ TSeriesLengthNode }
|
|
|
|
constructor TSeriesLengthNode.Create(const ASeries: IIdentifierNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity);
|
|
begin
|
|
inherited Create(AStaticType, AIdentity);
|
|
FSeries := ASeries;
|
|
end;
|
|
|
|
function TSeriesLengthNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akSeriesLength;
|
|
end;
|
|
function TSeriesLengthNode.GetSeries: IIdentifierNode;
|
|
begin
|
|
Result := FSeries;
|
|
end;
|
|
function TSeriesLengthNode.AsSeriesLength: ISeriesLengthNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
{ TRecurNode }
|
|
|
|
constructor TRecurNode.Create(const AArguments: ITupleNode; const AStaticType: IStaticType; const AIdentity: IAstIdentity);
|
|
begin
|
|
inherited Create(AStaticType, AIdentity);
|
|
FArguments := AArguments;
|
|
end;
|
|
|
|
function TRecurNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akRecur;
|
|
end;
|
|
function TRecurNode.GetArguments: ITupleNode;
|
|
begin
|
|
Result := FArguments;
|
|
end;
|
|
function TRecurNode.AsRecur: IRecurNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
{ TNopNode }
|
|
|
|
constructor TNopNode.Create(const AStaticType: IStaticType; const AIdentity: IAstIdentity);
|
|
begin
|
|
inherited Create(AStaticType, AIdentity);
|
|
end;
|
|
|
|
function TNopNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akNop;
|
|
end;
|
|
function TNopNode.AsNop: INopNode;
|
|
begin
|
|
Result := Self;
|
|
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.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akPipe;
|
|
end;
|
|
function TPipeNode.GetInputs: ITupleNode;
|
|
begin
|
|
Result := FInputs;
|
|
end;
|
|
function TPipeNode.GetTransformation: ILambdaExpressionNode;
|
|
begin
|
|
Result := FTransformation;
|
|
end;
|
|
function TPipeNode.AsPipe: IPipeNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
end.
|