Files
MycLib/Src/AST/Myc.Ast.pas
T
Michael Schimmel 8b765487ae Implementing Pipes
2025-12-21 16:30:09 +01:00

907 lines
31 KiB
ObjectPascal

unit Myc.Ast;
interface
uses
System.SysUtils,
System.Classes,
System.Generics.Collections,
Myc.Data.Scalar,
Myc.Data.Value,
Myc.Data.Keyword,
Myc.Ast.Nodes,
Myc.Ast.Scope,
Myc.Ast.Types,
Myc.Ast.Identities;
type
TAst = record
public
type
TRegisterLibraryProc = reference to procedure(const Scope: IExecutionScope);
private
class var
FLibraries: TList<TRegisterLibraryProc>;
class constructor Create;
class destructor Destroy;
public
class procedure RegisterLibrary(const AProc: TRegisterLibraryProc); static;
class function CreateScope(
Parent: IExecutionScope;
const Descriptor: IScopeDescriptor = nil;
ARegisterLibraries: Boolean = False
): IExecutionScope; static;
// ... (Keep existing methods: Identifier, Constant, Keyword, CreateSeries, Nop, IfExpr, CondExpr, LambdaExpr, MacroDef, Quotes, Call, etc.) ...
// [Creation] Raw Name -> New INamedIdentity
class function Identifier(const AName: string; const Loc: ISourceLocation = nil): IIdentifierNode; overload; static;
class function Identifier(
const Identity: INamedIdentity;
const Address: TResolvedAddress;
const AStaticType: IStaticType = nil
): IIdentifierNode; overload; static;
class function Constant(const AValue: TDataValue; const Loc: ISourceLocation = nil): IConstantNode; overload; static;
class function Constant(const AValue: String; const Loc: ISourceLocation = nil): IConstantNode; overload; static;
class function Constant(const Identity: IConstantIdentity; const AStaticType: IStaticType = nil): IConstantNode; overload; static;
class function Keyword(const AName: string; const Loc: ISourceLocation = nil): IKeywordNode; overload; static;
class function Keyword(const Identity: IKeywordIdentity): IKeywordNode; overload; static;
class function CreateSeries(const ADefinition: String; const Loc: ISourceLocation = nil): ICreateSeriesNode; overload; static;
class function CreateSeries(
const Identity: IDefinitionIdentity;
const AStaticType: IStaticType = nil
): ICreateSeriesNode; overload; static;
class function Nop(const Loc: ISourceLocation = nil): IAstNode; overload; static;
class function Nop(const Identity: IAstIdentity; const AStaticType: IStaticType = nil): IAstNode; overload; static;
class function IfExpr(
const ACondition: IAstNode;
const AThenBranch, AElseBranch: IAstNode;
const Loc: ISourceLocation = nil
): IIfExpressionNode; overload; static;
class function IfExpr(
const Identity: IAstIdentity;
const ACondition: IAstNode;
const AThenBranch, AElseBranch: IAstNode;
const AStaticType: IStaticType = nil
): IIfExpressionNode; overload; static;
class function CondExpr(
const APairs: TArray<TCondPair>;
const AElseBranch: IAstNode;
const Loc: ISourceLocation = nil
): ICondExpressionNode; overload; static;
class function CondExpr(
const Identity: IAstIdentity;
const APairs: TArray<TCondPair>;
const AElseBranch: IAstNode;
const AStaticType: IStaticType = nil
): ICondExpressionNode; overload; static;
class function TernaryExpr(
const ACondition: IAstNode;
const AThenBranch, AElseBranch: IAstNode;
const Loc: ISourceLocation = nil
): ICondExpressionNode; overload; static;
class function LambdaExpr(
const AParameters: TArray<IIdentifierNode>;
const ABody: IAstNode;
const Loc: ISourceLocation = nil
): ILambdaExpressionNode; overload; static;
class function LambdaExpr(
const Identity: IAstIdentity;
const AParameters: IParameterList;
const ABody: IAstNode;
const ALayout: IScopeLayout = nil;
const ADescriptor: IScopeDescriptor = nil;
const AUpvalues: TArray<TResolvedAddress> = nil;
const AHasNestedLambdas: Boolean = False;
const AIsPure: Boolean = False;
const AStaticType: IStaticType = nil
): ILambdaExpressionNode; overload; static;
class function MacroDef(
const AName: IIdentifierNode;
const AParameters: TArray<IIdentifierNode>;
const ABody: IAstNode;
const Loc: ISourceLocation = nil
): IMacroDefinitionNode; overload; static;
class function MacroDef(
const Identity: IAstIdentity;
const AName: IIdentifierNode;
const AParameters: IParameterList;
const ABody: IAstNode
): IMacroDefinitionNode; overload; static;
class function Quasiquote(const AExpression: IAstNode; const Loc: ISourceLocation = nil): IQuasiquoteNode; overload; static;
class function Quasiquote(const Identity: IAstIdentity; const AExpression: IAstNode): IQuasiquoteNode; overload; static;
class function Unquote(const AExpression: IAstNode; const Loc: ISourceLocation = nil): IUnquoteNode; overload; static;
class function Unquote(const Identity: IAstIdentity; const AExpression: IAstNode): IUnquoteNode; overload; static;
class function UnquoteSplicing(
const AExpression: IQuasiquoteNode;
const Loc: ISourceLocation = nil
): IUnquoteSplicingNode; overload; static;
class function UnquoteSplicing(
const Identity: IAstIdentity;
const AExpression: IQuasiquoteNode
): IUnquoteSplicingNode; overload; static;
class function FunctionCall(
const ACallee: IAstNode;
const AArguments: TArray<IAstNode>;
const Loc: ISourceLocation = nil
): IFunctionCallNode; overload; static;
class function FunctionCall(
const Identity: IAstIdentity;
const ACallee: IAstNode;
const AArguments: IArgumentList;
const AStaticType: IStaticType = nil;
const AIsTailCall: Boolean = False;
const AStaticTarget: TDataValue.TFunc = nil;
const AIsTargetPure: Boolean = False
): IFunctionCallNode; overload; static;
class function MacroExpansionNode(
const AOriginalCallNode: IFunctionCallNode;
const AExpandedBody: IAstNode;
const Loc: ISourceLocation = nil
): IMacroExpansionNode; overload; static;
class function MacroExpansionNode(
const Identity: IAstIdentity;
const AOriginalCallNode: IFunctionCallNode;
const AExpandedBody: IAstNode
): IMacroExpansionNode; overload; static;
class function Recur(const AArguments: array of IAstNode; const Loc: ISourceLocation = nil): IRecurNode; overload; static;
class function Recur(
const Identity: IAstIdentity;
const AArguments: IArgumentList;
const AStaticType: IStaticType = nil
): IRecurNode; overload; static;
class function Block(
const AExpressions: array of IAstNode;
const Loc: ISourceLocation = nil
): IBlockExpressionNode; overload; static;
class function Block(
const Identity: IAstIdentity;
const AExpressions: IExpressionList;
const AStaticType: IStaticType = nil
): IBlockExpressionNode; overload; static;
class function VarDecl(
const AIdentifier: IAstNode;
AInitializer: IAstNode = nil;
const Loc: ISourceLocation = nil
): IVariableDeclarationNode; overload; static;
class function VarDecl(
const Identity: IAstIdentity;
const AIdentifier: IAstNode;
AInitializer: IAstNode;
const AStaticType: IStaticType = nil;
const AIsBoxed: Boolean = False
): IVariableDeclarationNode; overload; static;
class function Assign(const ATarget, AValue: IAstNode; const Loc: ISourceLocation = nil): IAssignmentNode; overload; static;
class function Assign(
const Identity: IAstIdentity;
const ATarget, AValue: IAstNode;
const AStaticType: IStaticType = nil
): IAssignmentNode; overload; static;
class function Indexer(
const ABase: IAstNode;
const AIndex: IAstNode;
const Loc: ISourceLocation = nil
): IIndexerNode; overload; static;
class function Indexer(
const Identity: IAstIdentity;
const ABase, AIndex: IAstNode;
const AStaticType: IStaticType = nil
): IIndexerNode; overload; static;
class function MemberAccess(
const ABase: IAstNode;
const AMember: IKeywordNode;
const Loc: ISourceLocation = nil
): IMemberAccessNode; overload; static;
class function MemberAccess(
const Identity: IAstIdentity;
const ABase: IAstNode;
const AMember: IKeywordNode;
const AStaticType: IStaticType = nil
): IMemberAccessNode; overload; static;
class function RecordField(
const AKey: IKeywordNode;
const AValue: IAstNode;
const Loc: ISourceLocation = nil
): IRecordFieldNode; overload; static;
class function RecordField(
const Identity: IAstIdentity;
const AKey: IKeywordNode;
const AValue: IAstNode
): IRecordFieldNode; overload; static;
class function RecordLiteral(
const AFields: TArray<IRecordFieldNode>;
const Loc: ISourceLocation = nil
): IRecordLiteralNode; overload; static;
class function RecordLiteral(
const Identity: IAstIdentity;
const AFields: IRecordFieldList;
const AScalarDefinition: IScalarRecordDefinition = nil;
const AGenericDefinition: IGenericRecordDefinition = nil;
const AStaticType: IStaticType = nil
): IRecordLiteralNode; overload; static;
class function AddSeriesItem(
const ASeries: IIdentifierNode;
const AValue: IAstNode;
const ALookback: IAstNode = nil;
const Loc: ISourceLocation = nil
): IAddSeriesItemNode; overload; static;
class function AddSeriesItem(
const Identity: IAstIdentity;
const ASeries: IIdentifierNode;
const AValue: IAstNode;
const ALookback: IAstNode;
const AStaticType: IStaticType = nil
): IAddSeriesItemNode; overload; static;
class function SeriesLength(const ASeries: IIdentifierNode; const Loc: ISourceLocation = nil): ISeriesLengthNode; overload; static;
class function SeriesLength(
const Identity: IAstIdentity;
const ASeries: IIdentifierNode;
const AStaticType: IStaticType = nil
): ISeriesLengthNode; overload; static;
// --- PIPES (Updated) ---
// Helper: Create a SelectorList from an array of KeywordNodes
class function PipeSelectorList(const AKeywords: TArray<IKeywordNode>; const Loc: ISourceLocation = nil): IPipeSelectorList; static;
// Updated PipeInput: Accepts IPipeSelectorList instead of single Keyword
class function PipeInput(
const AStream: IIdentifierNode;
const ASelectors: IPipeSelectorList;
const Loc: ISourceLocation = nil
): IPipeInputNode; static;
class function Pipe(
const AInputs: TArray<IPipeInputNode>;
const ATransformation: ILambdaExpressionNode;
const Loc: ISourceLocation = nil
): IPipeNode; overload; static;
class function Pipe(
const Identity: IAstIdentity;
const AInputs: IPipeInputList;
const ATransformation: ILambdaExpressionNode;
const AStaticType: IStaticType = nil
): IPipeNode; overload; static;
end;
implementation
uses
System.Generics.Defaults;
// ... (Keep existing implementation for other methods) ...
{ TAst }
class constructor TAst.Create;
begin
FLibraries := TList<TRegisterLibraryProc>.Create;
end;
class destructor TAst.Destroy;
begin
FLibraries.Free;
end;
class procedure TAst.RegisterLibrary(const AProc: TRegisterLibraryProc);
begin
FLibraries.Add(AProc);
end;
class function TAst.CreateScope(
Parent: IExecutionScope;
const Descriptor: IScopeDescriptor = nil;
ARegisterLibraries: Boolean = False
): IExecutionScope;
begin
if Assigned(Descriptor) then
Result := Descriptor.CreateScope(Parent)
else
Result := TScope.CreateScope(Parent, nil, nil);
if ARegisterLibraries then
begin
for var libProc in FLibraries do
libProc(Result);
end;
end;
// ... (Keep existing Node Factory Methods) ...
class function TAst.Identifier(const AName: string; const Loc: ISourceLocation): IIdentifierNode;
begin
var id := TIdentities.Identifier(AName, Loc);
Result := TIdentifierNode.Create(id, Default(TResolvedAddress), TTypes.Unknown);
end;
class function TAst.Identifier(
const Identity: INamedIdentity;
const Address: TResolvedAddress;
const AStaticType: IStaticType
): IIdentifierNode;
begin
Result :=
TIdentifierNode.Create(
Identity,
Address,
if AStaticType <> nil then AStaticType
else TTypes.Unknown
);
end;
class function TAst.Constant(const AValue: TDataValue; const Loc: ISourceLocation): IConstantNode;
begin
var constType: IStaticType;
case AValue.Kind of
TDataValueKind.vkScalar: constType := TTypes.FromScalarKind(AValue.AsScalar.Kind);
TDataValueKind.vkText: constType := TTypes.Text;
TDataValueKind.vkVoid: constType := TTypes.Void;
else
constType := TTypes.Unknown;
end;
var id := TIdentities.Constant(AValue, Loc);
Result := TConstantNode.Create(id, constType);
end;
class function TAst.Constant(const AValue: String; const Loc: ISourceLocation): IConstantNode;
begin
Result := TAst.Constant(TDataValue(AValue), Loc);
end;
class function TAst.Constant(const Identity: IConstantIdentity; const AStaticType: IStaticType): IConstantNode;
begin
Result :=
TConstantNode.Create(
Identity,
if AStaticType <> nil then AStaticType
else TTypes.Unknown
);
end;
class function TAst.Keyword(const AName: string; const Loc: ISourceLocation): IKeywordNode;
begin
var val := TKeywordRegistry.Intern(AName);
var id := TIdentities.Keyword(val, Loc);
Result := TKeywordNode.Create(id);
end;
class function TAst.Keyword(const Identity: IKeywordIdentity): IKeywordNode;
begin
Result := TKeywordNode.Create(Identity);
end;
class function TAst.CreateSeries(const ADefinition: String; const Loc: ISourceLocation): ICreateSeriesNode;
begin
var id := TIdentities.Definition(ADefinition, Loc);
Result := TCreateSeriesNode.Create(id, TTypes.Unknown);
end;
class function TAst.CreateSeries(const Identity: IDefinitionIdentity; const AStaticType: IStaticType): ICreateSeriesNode;
begin
Result :=
TCreateSeriesNode.Create(
Identity,
if AStaticType <> nil then AStaticType
else TTypes.Unknown
);
end;
class function TAst.Nop(const Loc: ISourceLocation): IAstNode;
begin
var id := TIdentities.Structural(Loc);
Result := TNopNode.Create(TTypes.Unknown, id);
end;
class function TAst.Nop(const Identity: IAstIdentity; const AStaticType: IStaticType): IAstNode;
begin
Result :=
TNopNode.Create(
if AStaticType <> nil then AStaticType
else TTypes.Unknown,
Identity
);
end;
class function TAst.IfExpr(const ACondition, AThenBranch, AElseBranch: IAstNode; const Loc: ISourceLocation): IIfExpressionNode;
begin
var id := TIdentities.Structural(Loc);
Result := TIfExpressionNode.Create(ACondition, AThenBranch, AElseBranch, TTypes.Unknown, id);
end;
class function TAst.IfExpr(
const Identity: IAstIdentity;
const ACondition, AThenBranch, AElseBranch: IAstNode;
const AStaticType: IStaticType
): IIfExpressionNode;
begin
Result :=
TIfExpressionNode.Create(
ACondition,
AThenBranch,
AElseBranch,
if AStaticType <> nil then AStaticType
else TTypes.Unknown,
Identity
);
end;
class function TAst.CondExpr(const APairs: TArray<TCondPair>; const AElseBranch: IAstNode; const Loc: ISourceLocation): ICondExpressionNode;
begin
var id := TIdentities.Structural(Loc);
Result := TCondExpressionNode.Create(APairs, AElseBranch, TTypes.Unknown, id);
end;
class function TAst.CondExpr(
const Identity: IAstIdentity;
const APairs: TArray<TCondPair>;
const AElseBranch: IAstNode;
const AStaticType: IStaticType
): ICondExpressionNode;
begin
Result :=
TCondExpressionNode.Create(
APairs,
AElseBranch,
if AStaticType <> nil then AStaticType
else TTypes.Unknown,
Identity
);
end;
class function TAst.TernaryExpr(const ACondition, AThenBranch, AElseBranch: IAstNode; const Loc: ISourceLocation): ICondExpressionNode;
begin
var pair := TCondPair.Create(ACondition, AThenBranch);
Result := TAst.CondExpr([pair], AElseBranch, Loc);
end;
class function TAst.LambdaExpr(
const AParameters: TArray<IIdentifierNode>;
const ABody: IAstNode;
const Loc: ISourceLocation
): ILambdaExpressionNode;
begin
var listId := TIdentities.List('[', ']', ' ', Loc);
var paramList := TParameterList.Create(AParameters, listId);
var id := TIdentities.Structural(Loc);
var body := ABody;
if body = nil then
body := Block([]);
Result := TLambdaExpressionNode.Create(paramList, body, TTypes.Unknown, nil, nil, nil, False, False, id);
end;
class function TAst.LambdaExpr(
const Identity: IAstIdentity;
const AParameters: IParameterList;
const ABody: IAstNode;
const ALayout: IScopeLayout;
const ADescriptor: IScopeDescriptor;
const AUpvalues: TArray<TResolvedAddress>;
const AHasNestedLambdas, AIsPure: Boolean;
const AStaticType: IStaticType
): ILambdaExpressionNode;
begin
Result :=
TLambdaExpressionNode.Create(
AParameters,
ABody,
if AStaticType <> nil then AStaticType
else TTypes.Unknown,
ALayout,
ADescriptor,
AUpvalues,
AHasNestedLambdas,
AIsPure,
Identity
);
end;
class function TAst.MacroDef(
const AName: IIdentifierNode;
const AParameters: TArray<IIdentifierNode>;
const ABody: IAstNode;
const Loc: ISourceLocation
): IMacroDefinitionNode;
begin
var listId := TIdentities.List('[', ']', ' ', Loc);
var paramList := TParameterList.Create(AParameters, listId);
var id := TIdentities.Structural(Loc);
Result := TMacroDefinitionNode.Create(AName, paramList, ABody, id);
end;
class function TAst.MacroDef(
const Identity: IAstIdentity;
const AName: IIdentifierNode;
const AParameters: IParameterList;
const ABody: IAstNode
): IMacroDefinitionNode;
begin
Result := TMacroDefinitionNode.Create(AName, AParameters, ABody, Identity);
end;
class function TAst.Quasiquote(const AExpression: IAstNode; const Loc: ISourceLocation): IQuasiquoteNode;
begin
var id := TIdentities.Structural(Loc);
Result := TQuasiquoteNode.Create(AExpression, id);
end;
class function TAst.Quasiquote(const Identity: IAstIdentity; const AExpression: IAstNode): IQuasiquoteNode;
begin
Result := TQuasiquoteNode.Create(AExpression, Identity);
end;
class function TAst.Unquote(const AExpression: IAstNode; const Loc: ISourceLocation): IUnquoteNode;
begin
var id := TIdentities.Structural(Loc);
Result := TUnquoteNode.Create(AExpression, id);
end;
class function TAst.Unquote(const Identity: IAstIdentity; const AExpression: IAstNode): IUnquoteNode;
begin
Result := TUnquoteNode.Create(AExpression, Identity);
end;
class function TAst.UnquoteSplicing(const AExpression: IQuasiquoteNode; const Loc: ISourceLocation): IUnquoteSplicingNode;
begin
var id := TIdentities.Structural(Loc);
Result := TUnquoteSplicingNode.Create(AExpression, id);
end;
class function TAst.UnquoteSplicing(const Identity: IAstIdentity; const AExpression: IQuasiquoteNode): IUnquoteSplicingNode;
begin
Result := TUnquoteSplicingNode.Create(AExpression, Identity);
end;
class function TAst.FunctionCall(
const ACallee: IAstNode;
const AArguments: TArray<IAstNode>;
const Loc: ISourceLocation
): IFunctionCallNode;
begin
var listId := TIdentities.List('', '', ' ', Loc);
var argList := TArgumentList.Create(AArguments, listId);
var id := TIdentities.Structural(Loc);
Result := TFunctionCallNode.Create(ACallee, argList, TTypes.Unknown, False, nil, False, id);
end;
class function TAst.FunctionCall(
const Identity: IAstIdentity;
const ACallee: IAstNode;
const AArguments: IArgumentList;
const AStaticType: IStaticType;
const AIsTailCall: Boolean;
const AStaticTarget: TDataValue.TFunc;
const AIsTargetPure: Boolean
): IFunctionCallNode;
begin
Result :=
TFunctionCallNode.Create(
ACallee,
AArguments,
if AStaticType <> nil then AStaticType
else TTypes.Unknown,
AIsTailCall,
AStaticTarget,
AIsTargetPure,
Identity
);
end;
class function TAst.MacroExpansionNode(
const AOriginalCallNode: IFunctionCallNode;
const AExpandedBody: IAstNode;
const Loc: ISourceLocation
): IMacroExpansionNode;
begin
var id := TIdentities.Structural(Loc);
Result := TMacroExpansionNode.Create(AOriginalCallNode, AExpandedBody, id);
end;
class function TAst.MacroExpansionNode(
const Identity: IAstIdentity;
const AOriginalCallNode: IFunctionCallNode;
const AExpandedBody: IAstNode
): IMacroExpansionNode;
begin
Result := TMacroExpansionNode.Create(AOriginalCallNode, AExpandedBody, Identity);
end;
class function TAst.Recur(const AArguments: array of IAstNode; const Loc: ISourceLocation): IRecurNode;
var
args: TArray<IAstNode>;
i: Integer;
begin
SetLength(args, Length(AArguments));
for i := 0 to High(AArguments) do
args[i] := AArguments[i];
var listId := TIdentities.List('', '', ' ', Loc);
var argList := TArgumentList.Create(args, listId);
var id := TIdentities.Structural(Loc);
Result := TRecurNode.Create(argList, TTypes.Void, id);
end;
class function TAst.Recur(const Identity: IAstIdentity; const AArguments: IArgumentList; const AStaticType: IStaticType): IRecurNode;
begin
Result :=
TRecurNode.Create(
AArguments,
if AStaticType <> nil then AStaticType
else TTypes.Void,
Identity
);
end;
class function TAst.Block(const AExpressions: array of IAstNode; const Loc: ISourceLocation): IBlockExpressionNode;
var
exprs: TArray<IAstNode>;
i: Integer;
begin
SetLength(exprs, Length(AExpressions));
for i := 0 to High(AExpressions) do
exprs[i] := AExpressions[i];
var listId := TIdentities.List('', '', ' ', Loc);
var exprList := TExpressionList.Create(exprs, listId);
var id := TIdentities.Structural(Loc);
Result := TBlockExpressionNode.Create(exprList, TTypes.Unknown, id);
end;
class function TAst.Block(
const Identity: IAstIdentity;
const AExpressions: IExpressionList;
const AStaticType: IStaticType
): IBlockExpressionNode;
begin
Result :=
TBlockExpressionNode.Create(
AExpressions,
if AStaticType <> nil then AStaticType
else TTypes.Unknown,
Identity
);
end;
class function TAst.VarDecl(const AIdentifier: IAstNode; AInitializer: IAstNode; const Loc: ISourceLocation): IVariableDeclarationNode;
begin
var id := TIdentities.Structural(Loc);
Result := TVariableDeclarationNode.Create(AIdentifier, AInitializer, TTypes.Unknown, False, id);
end;
class function TAst.VarDecl(
const Identity: IAstIdentity;
const AIdentifier: IAstNode;
AInitializer: IAstNode;
const AStaticType: IStaticType;
const AIsBoxed: Boolean
): IVariableDeclarationNode;
begin
Result :=
TVariableDeclarationNode.Create(
AIdentifier,
AInitializer,
if AStaticType <> nil then AStaticType
else TTypes.Unknown,
AIsBoxed,
Identity
);
end;
class function TAst.Assign(const ATarget, AValue: IAstNode; const Loc: ISourceLocation): IAssignmentNode;
begin
var id := TIdentities.Structural(Loc);
Result := TAssignmentNode.Create(ATarget, AValue, TTypes.Unknown, id);
end;
class function TAst.Assign(const Identity: IAstIdentity; const ATarget, AValue: IAstNode; const AStaticType: IStaticType): IAssignmentNode;
begin
Result :=
TAssignmentNode.Create(
ATarget,
AValue,
if AStaticType <> nil then AStaticType
else TTypes.Unknown,
Identity
);
end;
class function TAst.Indexer(const ABase, AIndex: IAstNode; const Loc: ISourceLocation): IIndexerNode;
begin
var id := TIdentities.Structural(Loc);
Result := TIndexerNode.Create(ABase, AIndex, TTypes.Unknown, id);
end;
class function TAst.Indexer(const Identity: IAstIdentity; const ABase, AIndex: IAstNode; const AStaticType: IStaticType): IIndexerNode;
begin
Result :=
TIndexerNode.Create(
ABase,
AIndex,
if AStaticType <> nil then AStaticType
else TTypes.Unknown,
Identity
);
end;
class function TAst.MemberAccess(const ABase: IAstNode; const AMember: IKeywordNode; const Loc: ISourceLocation): IMemberAccessNode;
begin
var id := TIdentities.Structural(Loc);
Result := TMemberAccessNode.Create(ABase, AMember, TTypes.Unknown, id);
end;
class function TAst.MemberAccess(
const Identity: IAstIdentity;
const ABase: IAstNode;
const AMember: IKeywordNode;
const AStaticType: IStaticType
): IMemberAccessNode;
begin
Result :=
TMemberAccessNode.Create(
ABase,
AMember,
if AStaticType <> nil then AStaticType
else TTypes.Unknown,
Identity
);
end;
class function TAst.RecordField(const AKey: IKeywordNode; const AValue: IAstNode; const Loc: ISourceLocation): IRecordFieldNode;
begin
var id := TIdentities.Structural(Loc);
Result := TRecordFieldNode.Create(AKey, AValue, id);
end;
class function TAst.RecordField(const Identity: IAstIdentity; const AKey: IKeywordNode; const AValue: IAstNode): IRecordFieldNode;
begin
Result := TRecordFieldNode.Create(AKey, AValue, Identity);
end;
class function TAst.RecordLiteral(const AFields: TArray<IRecordFieldNode>; const Loc: ISourceLocation): IRecordLiteralNode;
begin
var listId := TIdentities.List('{', '}', ' ', Loc);
var fieldList := TRecordFieldList.Create(AFields, listId);
var id := TIdentities.Structural(Loc);
Result := TRecordLiteralNode.Create(fieldList, nil, nil, TTypes.Unknown, id);
end;
class function TAst.RecordLiteral(
const Identity: IAstIdentity;
const AFields: IRecordFieldList;
const AScalarDefinition: IScalarRecordDefinition;
const AGenericDefinition: IGenericRecordDefinition;
const AStaticType: IStaticType
): IRecordLiteralNode;
begin
Result :=
TRecordLiteralNode.Create(
AFields,
AScalarDefinition,
AGenericDefinition,
if AStaticType <> nil then AStaticType
else TTypes.Unknown,
Identity
);
end;
class function TAst.AddSeriesItem(
const ASeries: IIdentifierNode;
const AValue: IAstNode;
const ALookback: IAstNode;
const Loc: ISourceLocation
): IAddSeriesItemNode;
begin
var id := TIdentities.Structural(Loc);
Result := TAddSeriesItemNode.Create(ASeries, AValue, ALookback, TTypes.Void, id);
end;
class function TAst.AddSeriesItem(
const Identity: IAstIdentity;
const ASeries: IIdentifierNode;
const AValue: IAstNode;
const ALookback: IAstNode;
const AStaticType: IStaticType
): IAddSeriesItemNode;
begin
Result :=
TAddSeriesItemNode.Create(
ASeries,
AValue,
ALookback,
if AStaticType <> nil then AStaticType
else TTypes.Void,
Identity
);
end;
class function TAst.SeriesLength(const ASeries: IIdentifierNode; const Loc: ISourceLocation): ISeriesLengthNode;
begin
var id := TIdentities.Structural(Loc);
Result := TSeriesLengthNode.Create(ASeries, TTypes.Ordinal, id);
end;
class function TAst.SeriesLength(
const Identity: IAstIdentity;
const ASeries: IIdentifierNode;
const AStaticType: IStaticType
): ISeriesLengthNode;
begin
Result :=
TSeriesLengthNode.Create(
ASeries,
if AStaticType <> nil then AStaticType
else TTypes.Ordinal,
Identity
);
end;
// --- PIPES ---
class function TAst.PipeSelectorList(const AKeywords: TArray<IKeywordNode>; const Loc: ISourceLocation): IPipeSelectorList;
begin
var listId := TIdentities.List('[', ']', ' ', Loc);
Result := TPipeSelectorList.Create(AKeywords, listId);
end;
class function TAst.PipeInput(
const AStream: IIdentifierNode;
const ASelectors: IPipeSelectorList;
const Loc: ISourceLocation
): IPipeInputNode;
begin
var id := TIdentities.Structural(Loc);
Result := TPipeInputNode.Create(AStream, ASelectors, id, TTypes.Unknown);
end;
class function TAst.Pipe(
const AInputs: TArray<IPipeInputNode>;
const ATransformation: ILambdaExpressionNode;
const Loc: ISourceLocation
): IPipeNode;
begin
var listId := TIdentities.List('[', ']', ' ', Loc);
var inputList := TPipeInputList.Create(AInputs, listId);
var id := TIdentities.Structural(Loc);
Result := TPipeNode.Create(inputList, ATransformation, id, TTypes.Unknown);
end;
class function TAst.Pipe(
const Identity: IAstIdentity;
const AInputs: IPipeInputList;
const ATransformation: ILambdaExpressionNode;
const AStaticType: IStaticType
): IPipeNode;
begin
Result :=
TPipeNode.Create(
AInputs,
ATransformation,
Identity,
if AStaticType <> nil then AStaticType
else TTypes.Unknown
);
end;
end.