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; 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; // [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 Tuple(const Elements: TArray; const Loc: ISourceLocation = nil): ITupleNode; overload; static; class function Tuple( const Identity: IAstIdentity; const Elements: TArray; const AStaticType: IStaticType = nil ): ITupleNode; overload; static; class function CreateSeries(const ADefinitionNode: IAstNode; const Loc: ISourceLocation = nil): ICreateSeriesNode; overload; static; class function CreateSeries( const Identity: IAstIdentity; const ADefinitionNode: IAstNode; const ARecordDefinition: IScalarRecordDefinition = nil; 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; const AElseBranch: IAstNode; const Loc: ISourceLocation = nil ): ICondExpressionNode; overload; static; class function CondExpr( const Identity: IAstIdentity; const APairs: TArray; 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; const ABody: IAstNode; const Loc: ISourceLocation = nil ): ILambdaExpressionNode; overload; static; class function LambdaExpr( const Identity: IAstIdentity; const AParameters: ITupleNode; const ABody: IAstNode; const ALayout: IScopeLayout = nil; const ADescriptor: IScopeDescriptor = nil; const AUpvalues: TArray = 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; const ABody: IAstNode; const Loc: ISourceLocation = nil ): IMacroDefinitionNode; overload; static; class function MacroDef( const Identity: IAstIdentity; const AName: IIdentifierNode; const AParameters: ITupleNode; 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; const Loc: ISourceLocation = nil ): IFunctionCallNode; overload; static; class function FunctionCall( const Identity: IAstIdentity; const ACallee: IAstNode; const AArguments: ITupleNode; 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: ITupleNode; 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: ITupleNode; // Unification: ITupleNode 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; const Loc: ISourceLocation = nil ): IRecordLiteralNode; overload; static; class function RecordLiteral( const Identity: IAstIdentity; const AFields: ITupleNode; // Unification: ITupleNode 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; // --- PIPES --- class function Pipe( const AInputs: ITupleNode; const ATransformation: ILambdaExpressionNode; const Loc: ISourceLocation = nil ): IPipeNode; overload; static; class function Pipe( const Identity: IAstIdentity; const AInputs: ITupleNode; const ATransformation: ILambdaExpressionNode; const AStaticType: IStaticType = nil ): IPipeNode; overload; static; end; implementation uses System.Generics.Defaults; { TAst } class constructor TAst.Create; begin FLibraries := TList.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; 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.Tuple(const Elements: TArray; const Loc: ISourceLocation): ITupleNode; begin var id := TIdentities.List('[', ']', ' ', Loc); Result := TTupleNode.Create(Elements, id, TTypes.Unknown); end; class function TAst.Tuple(const Identity: IAstIdentity; const Elements: TArray; const AStaticType: IStaticType): ITupleNode; begin Result := TTupleNode.Create( Elements, Identity, if AStaticType <> nil then AStaticType else TTypes.Unknown ); end; class function TAst.CreateSeries(const ADefinitionNode: IAstNode; const Loc: ISourceLocation): ICreateSeriesNode; begin var id := TIdentities.Structural(Loc); // RecordDefinition is nil initially, populated by TypeChecker Result := TCreateSeriesNode.Create(ADefinitionNode, nil, TTypes.Unknown, id); end; class function TAst.CreateSeries( const Identity: IAstIdentity; const ADefinitionNode: IAstNode; const ARecordDefinition: IScalarRecordDefinition; const AStaticType: IStaticType ): ICreateSeriesNode; begin Result := TCreateSeriesNode.Create( ADefinitionNode, ARecordDefinition, if AStaticType <> nil then AStaticType else TTypes.Unknown, Identity ); 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; 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; 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; const ABody: IAstNode; const Loc: ISourceLocation ): ILambdaExpressionNode; var paramNodes: TArray; i: Integer; begin SetLength(paramNodes, Length(AParameters)); for i := 0 to High(AParameters) do paramNodes[i] := AParameters[i]; var listId := TIdentities.List('[', ']', ' ', Loc); var paramTuple := TTupleNode.Create(paramNodes, listId, TTypes.Unknown); var id := TIdentities.Structural(Loc); var body := ABody; if body = nil then body := Block([]); Result := TLambdaExpressionNode.Create(paramTuple, body, TTypes.Unknown, nil, nil, nil, False, False, id); end; class function TAst.LambdaExpr( const Identity: IAstIdentity; const AParameters: ITupleNode; const ABody: IAstNode; const ALayout: IScopeLayout; const ADescriptor: IScopeDescriptor; const AUpvalues: TArray; 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; const ABody: IAstNode; const Loc: ISourceLocation ): IMacroDefinitionNode; var paramNodes: TArray; i: Integer; begin SetLength(paramNodes, Length(AParameters)); for i := 0 to High(AParameters) do paramNodes[i] := AParameters[i]; var listId := TIdentities.List('[', ']', ' ', Loc); var paramTuple := TTupleNode.Create(paramNodes, listId, TTypes.Unknown); var id := TIdentities.Structural(Loc); Result := TMacroDefinitionNode.Create(AName, paramTuple, ABody, id); end; class function TAst.MacroDef( const Identity: IAstIdentity; const AName: IIdentifierNode; const AParameters: ITupleNode; 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; const Loc: ISourceLocation ): IFunctionCallNode; begin var listId := TIdentities.List('', '', ' ', Loc); var argTuple := TTupleNode.Create(AArguments, listId, TTypes.Unknown); var id := TIdentities.Structural(Loc); Result := TFunctionCallNode.Create(ACallee, argTuple, TTypes.Unknown, False, nil, False, id); end; class function TAst.FunctionCall( const Identity: IAstIdentity; const ACallee: IAstNode; const AArguments: ITupleNode; 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; i: Integer; begin SetLength(args, Length(AArguments)); for i := 0 to High(AArguments) do args[i] := AArguments[i]; var listId := TIdentities.List('', '', ' ', Loc); var argTuple := TTupleNode.Create(args, listId, TTypes.Unknown); var id := TIdentities.Structural(Loc); Result := TRecurNode.Create(argTuple, TTypes.Void, id); end; class function TAst.Recur(const Identity: IAstIdentity; const AArguments: ITupleNode; 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; i: Integer; begin SetLength(exprs, Length(AExpressions)); for i := 0 to High(AExpressions) do exprs[i] := AExpressions[i]; var listId := TIdentities.List('', '', ' ', Loc); var exprTuple := TTupleNode.Create(exprs, listId, TTypes.Unknown); var id := TIdentities.Structural(Loc); Result := TBlockExpressionNode.Create(exprTuple, TTypes.Unknown, id); end; class function TAst.Block( const Identity: IAstIdentity; const AExpressions: ITupleNode; 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; const Loc: ISourceLocation): IRecordLiteralNode; begin var listId := TIdentities.List('{', '}', ' ', Loc); var fields: TArray; SetLength(fields, Length(AFields)); for var i := 0 to High(AFields) do fields[i] := AFields[i]; var fieldTuple := TTupleNode.Create(fields, listId, TTypes.Unknown); var id := TIdentities.Structural(Loc); Result := TRecordLiteralNode.Create(fieldTuple, nil, nil, TTypes.Unknown, id); end; class function TAst.RecordLiteral( const Identity: IAstIdentity; const AFields: ITupleNode; 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; // --- PIPES --- class function TAst.Pipe(const AInputs: ITupleNode; const ATransformation: ILambdaExpressionNode; const Loc: ISourceLocation): IPipeNode; begin var id := TIdentities.Structural(Loc); Result := TPipeNode.Create(AInputs, ATransformation, id, TTypes.Unknown); end; class function TAst.Pipe( const Identity: IAstIdentity; const AInputs: ITupleNode; const ATransformation: ILambdaExpressionNode; const AStaticType: IStaticType ): IPipeNode; begin Result := TPipeNode.Create( AInputs, ATransformation, Identity, if AStaticType <> nil then AStaticType else TTypes.Unknown ); end; end.