1894 lines
55 KiB
ObjectPascal
1894 lines
55 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;
|
|
|
|
type
|
|
// Record acting as a namespace for the factory functions.
|
|
TAst = record
|
|
public
|
|
type
|
|
TRegisterLibraryProc = reference to procedure(const Scope: IExecutionScope);
|
|
private
|
|
class var
|
|
FLibraries: TList<TRegisterLibraryProc>;
|
|
class constructor Create;
|
|
class destructor Destroy;
|
|
public
|
|
class procedure RegisterLibrary(const AProc: TRegisterLibraryProc); static;
|
|
class function CreateScope(
|
|
Parent: IExecutionScope;
|
|
const Descriptor: IScopeDescriptor = nil;
|
|
ARegisterLibraries: Boolean = False
|
|
): IExecutionScope; static;
|
|
|
|
// A No-Operation node, used as a placeholder/stub (e.g., for UI drop targets).
|
|
class function Nop(const AStaticType: IStaticType = nil): IAstNode; static;
|
|
|
|
// --- Factory functions ---
|
|
class function Constant(const AValue: TDataValue; const AStaticType: IStaticType = nil): IConstantNode; overload; static;
|
|
class function Constant(const AValue: String): IConstantNode; overload; static;
|
|
class function Keyword(const AName: string): IKeywordNode; static;
|
|
class function Identifier(AName: string; const AStaticType: IStaticType = nil): IIdentifierNode; overload; static;
|
|
class function Identifier(
|
|
AName: string;
|
|
const Address: TResolvedAddress;
|
|
const AStaticType: IStaticType = nil
|
|
): IIdentifierNode; overload; static;
|
|
class function IfExpr(
|
|
const ACondition: IAstNode;
|
|
const AThenBranch, AElseBranch: IAstNode;
|
|
const AStaticType: IStaticType = nil
|
|
): IIfExpressionNode; static;
|
|
class function TernaryExpr(
|
|
const ACondition: IAstNode;
|
|
const AThenBranch, AElseBranch: IAstNode;
|
|
const AStaticType: IStaticType = nil
|
|
): ITernaryExpressionNode; static;
|
|
|
|
// (* UPDATED Factory: Added AIsPure *)
|
|
class function LambdaExpr(
|
|
const AParameters: TArray<IIdentifierNode>;
|
|
const ABody: IAstNode;
|
|
const ALayout: IScopeLayout = nil;
|
|
const ADescriptor: IScopeDescriptor = nil;
|
|
const AUpvalues: TArray<TResolvedAddress> = nil;
|
|
const AHasNestedLambdas: Boolean = False;
|
|
const AIsPure: Boolean = False; // (* ADDED *)
|
|
const AStaticType: IStaticType = nil
|
|
): ILambdaExpressionNode; static;
|
|
|
|
class function MacroDef(
|
|
const AName: IIdentifierNode;
|
|
const AParameters: TArray<IIdentifierNode>;
|
|
const ABody: IAstNode
|
|
): IMacroDefinitionNode; static;
|
|
class function Quasiquote(const AExpression: IAstNode): IQuasiquoteNode; static;
|
|
class function Unquote(const AExpression: IAstNode): IUnquoteNode; static;
|
|
class function UnquoteSplicing(const AExpression: IQuasiquoteNode): IUnquoteSplicingNode; static;
|
|
|
|
// (* UPDATED Factory: Added AIsTargetPure *)
|
|
class function FunctionCall(
|
|
const ACallee: IAstNode;
|
|
const AArguments: TArray<IAstNode>;
|
|
const AStaticType: IStaticType = nil;
|
|
const AIsTailCall: Boolean = False;
|
|
const AStaticTarget: TDataValue.TFunc = nil;
|
|
const AIsTargetPure: Boolean = False // (* ADDED *)
|
|
): IFunctionCallNode; static;
|
|
|
|
class function MacroExpansionNode(
|
|
const AOriginalCallNode: IFunctionCallNode;
|
|
const AExpandedBody: IAstNode
|
|
): IMacroExpansionNode; static;
|
|
class function Recur(const AArguments: array of IAstNode; const AStaticType: IStaticType = nil): IRecurNode; static;
|
|
class function Block(const AExpressions: array of IAstNode; const AStaticType: IStaticType = nil): IBlockExpressionNode; static;
|
|
|
|
class function VarDecl(
|
|
const AIdentifier: IAstNode;
|
|
AInitializer: IAstNode = nil;
|
|
const AStaticType: IStaticType = nil;
|
|
const AIsBoxed: Boolean = False
|
|
): IVariableDeclarationNode; static;
|
|
|
|
class function Assign(const ATarget, AValue: IAstNode; const AStaticType: IStaticType = nil): IAssignmentNode; static;
|
|
class function AssignResult(const AValue: IAstNode): IAssignmentNode; static; deprecated;
|
|
class function Indexer(const ABase: IAstNode; const AIndex: IAstNode; const AStaticType: IStaticType = nil): IIndexerNode; static;
|
|
class function MemberAccess(
|
|
const ABase: IAstNode;
|
|
const AMember: IKeywordNode;
|
|
const AStaticType: IStaticType = nil
|
|
): IMemberAccessNode; static;
|
|
class function RecordLiteral(
|
|
const AFields: TArray<TRecordFieldLiteral>;
|
|
const AScalarDefinition: IScalarRecordDefinition = nil;
|
|
const AGenericDefinition: IGenericRecordDefinition = nil;
|
|
const AStaticType: IStaticType = nil
|
|
): IRecordLiteralNode; static;
|
|
class function CreateSeries(const ADefinition: String; const AStaticType: IStaticType = nil): ICreateSeriesNode; static;
|
|
class function AddSeriesItem(
|
|
const ASeries: IIdentifierNode;
|
|
const AValue: IAstNode;
|
|
const ALookback: IAstNode = nil;
|
|
const AStaticType: IStaticType = nil
|
|
): IAddSeriesItemNode; static;
|
|
class function SeriesLength(const ASeries: IIdentifierNode; const AStaticType: IStaticType = nil): ISeriesLengthNode; static;
|
|
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
System.Generics.Defaults;
|
|
|
|
type
|
|
// --- Concrete Class Definitions ---
|
|
|
|
TAstNode = class(TInterfacedObject, IAstNode)
|
|
private
|
|
function GetKind: TAstNodeKind; virtual; abstract;
|
|
function GetIsTyped: Boolean; virtual;
|
|
public
|
|
constructor Create;
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; virtual; abstract;
|
|
|
|
// --- As... Accessors Implementation ---
|
|
function AsConstant: IConstantNode; virtual;
|
|
function AsIdentifier: IIdentifierNode; virtual;
|
|
function AsKeyword: IKeywordNode; virtual;
|
|
function AsIfExpression: IIfExpressionNode; virtual;
|
|
function AsTernaryExpression: ITernaryExpressionNode; virtual;
|
|
function AsLambdaExpression: ILambdaExpressionNode; virtual;
|
|
function AsFunctionCall: IFunctionCallNode; virtual;
|
|
function AsMacroExpansion: IMacroExpansionNode; virtual;
|
|
function AsBlockExpression: IBlockExpressionNode; virtual;
|
|
function AsVariableDeclaration: IVariableDeclarationNode; virtual;
|
|
function AsAssignment: IAssignmentNode; virtual;
|
|
function AsMacroDefinition: IMacroDefinitionNode; virtual;
|
|
function AsQuasiquote: IQuasiquoteNode; virtual;
|
|
function AsUnquote: IUnquoteNode; virtual;
|
|
function AsUnquoteSplicing: IUnquoteSplicingNode; virtual;
|
|
function AsIndexer: IIndexerNode; virtual;
|
|
function AsMemberAccess: IMemberAccessNode; virtual;
|
|
function AsRecordLiteral: IRecordLiteralNode; virtual;
|
|
function AsCreateSeries: ICreateSeriesNode; virtual;
|
|
function AsAddSeriesItem: IAddSeriesItemNode; virtual;
|
|
function AsSeriesLength: ISeriesLengthNode; virtual;
|
|
function AsRecur: IRecurNode; virtual;
|
|
function AsNop: INopNode; virtual;
|
|
|
|
function AsTypedNode: IAstTypedNode; virtual;
|
|
|
|
property IsTyped: Boolean read GetIsTyped;
|
|
property Kind: TAstNodeKind read GetKind;
|
|
end;
|
|
|
|
TAstTypedNode = class(TAstNode, IAstTypedNode)
|
|
private
|
|
FStaticType: IStaticType;
|
|
function GetStaticType: IStaticType;
|
|
function GetIsTyped: Boolean; override;
|
|
public
|
|
constructor Create(const AStaticType: IStaticType);
|
|
function AsTypedNode: IAstTypedNode; override;
|
|
property StaticType: IStaticType read GetStaticType;
|
|
end;
|
|
|
|
// Updated TLambdaExpressionNode
|
|
TLambdaExpressionNode = class(TAstTypedNode, ILambdaExpressionNode, IFunctionDefinition)
|
|
private
|
|
FParameters: TArray<IIdentifierNode>;
|
|
FBody: IAstNode;
|
|
FLayout: IScopeLayout;
|
|
FDescriptor: IScopeDescriptor;
|
|
FUpvalues: TArray<TResolvedAddress>;
|
|
FHasNestedLambdas: Boolean;
|
|
FIsPure: Boolean; // (* ADDED *)
|
|
|
|
function GetParameters: TArray<IIdentifierNode>;
|
|
function GetBody: IAstNode;
|
|
function GetLayout: IScopeLayout;
|
|
function GetDescriptor: IScopeDescriptor;
|
|
function GetUpvalues: TArray<TResolvedAddress>;
|
|
function GetHasNestedLambdas: Boolean;
|
|
function GetIsPure: Boolean; // (* ADDED *)
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(
|
|
const AParameters: TArray<IIdentifierNode>;
|
|
const ABody: IAstNode;
|
|
const AStaticType: IStaticType;
|
|
const ALayout: IScopeLayout;
|
|
const ADescriptor: IScopeDescriptor;
|
|
const AUpvalues: TArray<TResolvedAddress>;
|
|
const AHasNestedLambdas: Boolean;
|
|
const AIsPure: Boolean // (* ADDED *)
|
|
);
|
|
destructor Destroy; override;
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsLambdaExpression: ILambdaExpressionNode; override;
|
|
end;
|
|
|
|
TFunctionCallNode = class(TAstTypedNode, IFunctionCallNode)
|
|
private
|
|
FCallee: IAstNode;
|
|
FArguments: TArray<IAstNode>;
|
|
FIsTailCall: Boolean;
|
|
FStaticTarget: TDataValue.TFunc;
|
|
FIsTargetPure: Boolean; // (* ADDED *)
|
|
function GetCallee: IAstNode;
|
|
function GetArguments: TArray<IAstNode>;
|
|
function GetIsTailCall: Boolean;
|
|
function GetStaticTarget: TDataValue.TFunc;
|
|
function GetIsTargetPure: Boolean; // (* ADDED *)
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(
|
|
const ACallee: IAstNode;
|
|
const AArguments: TArray<IAstNode>;
|
|
const AStaticType: IStaticType;
|
|
const AIsTailCall: Boolean;
|
|
const AStaticTarget: TDataValue.TFunc;
|
|
const AIsTargetPure: Boolean // (* ADDED *)
|
|
);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsFunctionCall: IFunctionCallNode; override;
|
|
end;
|
|
|
|
TVariableDeclarationNode = class(TAstTypedNode, IVariableDeclarationNode)
|
|
private
|
|
FInitializer: IAstNode;
|
|
FTarget: IAstNode;
|
|
FIsBoxed: Boolean;
|
|
function GetTarget: IAstNode;
|
|
function GetInitializer: IAstNode;
|
|
function GetIsBoxed: Boolean;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const ATarget: IAstNode; AInitializer: IAstNode; const AStaticType: IStaticType; const AIsBoxed: Boolean);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsVariableDeclaration: IVariableDeclarationNode; override;
|
|
end;
|
|
|
|
TConstantNode = class(TAstTypedNode, IConstantNode)
|
|
private
|
|
FValue: TDataValue;
|
|
function GetValue: TDataValue;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AValue: TDataValue; const AStaticType: IStaticType);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsConstant: IConstantNode; override;
|
|
property Value: TDataValue read GetValue;
|
|
end;
|
|
|
|
TIdentifierNode = class(TAstTypedNode, IIdentifierNode)
|
|
private
|
|
FAddress: TResolvedAddress;
|
|
FName: string;
|
|
function GetAddress: TResolvedAddress;
|
|
function GetName: string;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AName: string; const AAddress: TResolvedAddress; const AStaticType: IStaticType);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsIdentifier: IIdentifierNode; override;
|
|
property Address: TResolvedAddress read GetAddress;
|
|
property Name: string read FName;
|
|
end;
|
|
|
|
TKeywordNode = class(TAstTypedNode, IKeywordNode)
|
|
private
|
|
FValue: IKeyword;
|
|
function GetValue: IKeyword;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AValue: IKeyword);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsKeyword: IKeywordNode; override;
|
|
property Value: IKeyword read FValue;
|
|
end;
|
|
|
|
TMacroDefinitionNode = class(TAstTypedNode, IMacroDefinitionNode)
|
|
private
|
|
FName: IIdentifierNode;
|
|
FParameters: TArray<IIdentifierNode>;
|
|
FBody: IAstNode;
|
|
function GetName: IIdentifierNode;
|
|
function GetParameters: TArray<IIdentifierNode>;
|
|
function GetBody: IAstNode;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AName: IIdentifierNode; const AParameters: TArray<IIdentifierNode>; const ABody: IAstNode);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsMacroDefinition: IMacroDefinitionNode; override;
|
|
property Name: IIdentifierNode read GetName;
|
|
property Parameters: TArray<IIdentifierNode> read FParameters;
|
|
property Body: IAstNode read FBody;
|
|
end;
|
|
|
|
TQuasiquoteNode = class(TAstNode, IQuasiquoteNode)
|
|
private
|
|
FExpression: IAstNode;
|
|
function GetExpression: IAstNode;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AExpression: IAstNode);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsQuasiquote: IQuasiquoteNode; override;
|
|
property Expression: IAstNode read GetExpression;
|
|
end;
|
|
|
|
TUnquoteNode = class(TAstNode, IUnquoteNode)
|
|
private
|
|
FExpression: IAstNode;
|
|
function GetExpression: IAstNode;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AExpression: IAstNode);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsUnquote: IUnquoteNode; override;
|
|
property Expression: IAstNode read GetExpression;
|
|
end;
|
|
|
|
TUnquoteSplicingNode = class(TAstNode, IUnquoteSplicingNode)
|
|
private
|
|
FExpression: IQuasiquoteNode;
|
|
function GetExpression: IQuasiquoteNode;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AExpression: IQuasiquoteNode);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsUnquoteSplicing: IUnquoteSplicingNode; override;
|
|
property Expression: IQuasiquoteNode read GetExpression;
|
|
end;
|
|
|
|
TMacroExpansionNode = class(TAstTypedNode, IMacroExpansionNode)
|
|
private
|
|
FCallNode: IFunctionCallNode;
|
|
FExpandedBody: IAstNode;
|
|
function GetCallNode: IFunctionCallNode;
|
|
function GetExpandedBody: IAstNode;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const ACallNode: IFunctionCallNode; const AExpandedBody: IAstNode);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsMacroExpansion: IMacroExpansionNode; override;
|
|
property CallNode: IFunctionCallNode read GetCallNode;
|
|
property ExpandedBody: IAstNode read FExpandedBody;
|
|
end;
|
|
|
|
TRecurNode = class(TAstTypedNode, IRecurNode)
|
|
private
|
|
FArguments: TArray<IAstNode>;
|
|
function GetArguments: TArray<IAstNode>;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AArguments: TArray<IAstNode>; const AStaticType: IStaticType);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsRecur: IRecurNode; override;
|
|
property Arguments: TArray<IAstNode> read FArguments;
|
|
end;
|
|
|
|
TBlockExpressionNode = class(TAstTypedNode, IBlockExpressionNode)
|
|
private
|
|
FExpressions: TArray<IAstNode>;
|
|
function GetExpressions: TArray<IAstNode>;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AExpressions: array of IAstNode; const AStaticType: IStaticType);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsBlockExpression: IBlockExpressionNode; override;
|
|
property Expressions: TArray<IAstNode> read FExpressions;
|
|
end;
|
|
|
|
TIfExpressionNode = class(TAstTypedNode, IIfExpressionNode)
|
|
private
|
|
FCondition: IAstNode;
|
|
FThenBranch: IAstNode;
|
|
FElseBranch: IAstNode;
|
|
function GetCondition: IAstNode;
|
|
function GetThenBranch: IAstNode;
|
|
function GetElseBranch: IAstNode;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const ACondition, AThenBranch, AElseBranch: IAstNode; const AStaticType: IStaticType);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsIfExpression: IIfExpressionNode; override;
|
|
property Condition: IAstNode read FCondition;
|
|
property ThenBranch: IAstNode read FThenBranch;
|
|
property ElseBranch: IAstNode read FElseBranch;
|
|
end;
|
|
|
|
TTernaryExpressionNode = class(TAstTypedNode, ITernaryExpressionNode)
|
|
private
|
|
FCondition: IAstNode;
|
|
FThenBranch: IAstNode;
|
|
FElseBranch: IAstNode;
|
|
function GetCondition: IAstNode;
|
|
function GetThenBranch: IAstNode;
|
|
function GetElseBranch: IAstNode;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const ACondition, AThenBranch, AElseBranch: IAstNode; const AStaticType: IStaticType);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsTernaryExpression: ITernaryExpressionNode; override;
|
|
property Condition: IAstNode read FCondition;
|
|
property ThenBranch: IAstNode read FThenBranch;
|
|
property ElseBranch: IAstNode read FElseBranch;
|
|
end;
|
|
|
|
TAssignmentNode = class(TAstTypedNode, IAssignmentNode)
|
|
private
|
|
FTarget: IAstNode;
|
|
FValue: IAstNode;
|
|
function GetTarget: IAstNode;
|
|
function GetValue: IAstNode;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const ATarget: IAstNode; const AValue: IAstNode; const AStaticType: IStaticType);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsAssignment: IAssignmentNode; override;
|
|
property Target: IAstNode read FTarget;
|
|
property Value: IAstNode read FValue;
|
|
end;
|
|
|
|
TIndexerNode = class(TAstTypedNode, IIndexerNode)
|
|
private
|
|
FBase: IAstNode;
|
|
FIndex: IAstNode;
|
|
function GetBase: IAstNode;
|
|
function GetIndex: IAstNode;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const ABase: IAstNode; const AIndex: IAstNode; const AStaticType: IStaticType);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsIndexer: IIndexerNode; override;
|
|
property Base: IAstNode read FBase;
|
|
property Index: IAstNode read FIndex;
|
|
end;
|
|
|
|
TMemberAccessNode = class(TAstTypedNode, IMemberAccessNode)
|
|
private
|
|
FBase: IAstNode;
|
|
FMember: IKeywordNode;
|
|
function GetBase: IAstNode;
|
|
function GetMember: IKeywordNode;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const ABase: IAstNode; const AMember: IKeywordNode; const AStaticType: IStaticType);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsMemberAccess: IMemberAccessNode; override;
|
|
property Base: IAstNode read FBase;
|
|
property Member: IKeywordNode read FMember;
|
|
end;
|
|
|
|
TCreateSeriesNode = class(TAstTypedNode, ICreateSeriesNode)
|
|
private
|
|
FDefinition: String;
|
|
function GetDefinition: String;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const ADefinition: String; const AStaticType: IStaticType);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsCreateSeries: ICreateSeriesNode; override;
|
|
property Definition: String read FDefinition;
|
|
end;
|
|
|
|
TAddSeriesItemNode = class(TAstTypedNode, IAddSeriesItemNode)
|
|
private
|
|
FSeries: IIdentifierNode;
|
|
FValue: IAstNode;
|
|
FLookback: IAstNode;
|
|
function GetSeries: IIdentifierNode;
|
|
function GetValue: IAstNode;
|
|
function GetLookback: IAstNode;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(
|
|
const ASeries: IIdentifierNode;
|
|
const AValue: IAstNode;
|
|
const ALookback: IAstNode;
|
|
const AStaticType: IStaticType
|
|
);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsAddSeriesItem: IAddSeriesItemNode; override;
|
|
property Series: IIdentifierNode read FSeries;
|
|
property Value: IAstNode read FValue;
|
|
property Lookback: IAstNode read FLookback;
|
|
end;
|
|
|
|
TSeriesLengthNode = class(TAstTypedNode, ISeriesLengthNode)
|
|
private
|
|
FSeries: IIdentifierNode;
|
|
function GetSeries: IIdentifierNode;
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const ASeries: IIdentifierNode; const AStaticType: IStaticType);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsSeriesLength: ISeriesLengthNode; override;
|
|
property Series: IIdentifierNode read FSeries;
|
|
end;
|
|
|
|
TRecordLiteralNode = class(TAstTypedNode, IRecordLiteralNode)
|
|
private
|
|
FFields: TArray<TRecordFieldLiteral>;
|
|
FScalarDefinition: IScalarRecordDefinition;
|
|
FGenericDefinition: IGenericRecordDefinition;
|
|
function GetFields: TArray<TRecordFieldLiteral>;
|
|
function GetGenericDefinition: IGenericRecordDefinition;
|
|
function GetKind: TAstNodeKind; override;
|
|
function GetScalarDefinition: IScalarRecordDefinition;
|
|
public
|
|
constructor Create(
|
|
const AFields: TArray<TRecordFieldLiteral>;
|
|
const AScalarDefinition: IScalarRecordDefinition;
|
|
const AGenericDefinition: IGenericRecordDefinition;
|
|
const AStaticType: IStaticType
|
|
);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsRecordLiteral: IRecordLiteralNode; override;
|
|
property Fields: TArray<TRecordFieldLiteral> read FFields;
|
|
property ScalarDefinition: IScalarRecordDefinition read GetScalarDefinition;
|
|
property GenericDefinition: IGenericRecordDefinition read GetGenericDefinition;
|
|
end;
|
|
|
|
TNopNode = class(TAstTypedNode, INopNode)
|
|
private
|
|
function GetKind: TAstNodeKind; override;
|
|
public
|
|
constructor Create(const AStaticType: IStaticType);
|
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
|
function AsNop: INopNode; override;
|
|
end;
|
|
|
|
{ TAst }
|
|
|
|
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.CreateSeries(const ADefinition: String; const AStaticType: IStaticType = nil): ICreateSeriesNode;
|
|
begin
|
|
Result :=
|
|
TCreateSeriesNode.Create(
|
|
ADefinition,
|
|
if AStaticType <> nil then AStaticType
|
|
else TTypes.Unknown
|
|
);
|
|
end;
|
|
|
|
class function TAst.AddSeriesItem(
|
|
const ASeries: IIdentifierNode;
|
|
const AValue: IAstNode;
|
|
const ALookback: IAstNode = nil;
|
|
const AStaticType: IStaticType = nil
|
|
): IAddSeriesItemNode;
|
|
begin
|
|
Result :=
|
|
TAddSeriesItemNode.Create(
|
|
ASeries,
|
|
AValue,
|
|
ALookback,
|
|
if AStaticType <> nil then AStaticType
|
|
else TTypes.Void
|
|
);
|
|
end;
|
|
|
|
class function TAst.SeriesLength(const ASeries: IIdentifierNode; const AStaticType: IStaticType = nil): ISeriesLengthNode;
|
|
begin
|
|
Result :=
|
|
TSeriesLengthNode.Create(
|
|
ASeries,
|
|
if AStaticType <> nil then AStaticType
|
|
else TTypes.Ordinal
|
|
);
|
|
end;
|
|
|
|
class function TAst.Assign(const ATarget, AValue: IAstNode; const AStaticType: IStaticType = nil): IAssignmentNode;
|
|
begin
|
|
Result :=
|
|
TAssignmentNode.Create(
|
|
ATarget,
|
|
AValue,
|
|
if AStaticType <> nil then AStaticType
|
|
else TTypes.Unknown
|
|
);
|
|
end;
|
|
|
|
class function TAst.AssignResult(const AValue: IAstNode): IAssignmentNode;
|
|
begin
|
|
Result := TAssignmentNode.Create(TAst.Identifier('Result'), AValue, TTypes.Unknown);
|
|
end;
|
|
|
|
class function TAst.Block(const AExpressions: array of IAstNode; const AStaticType: IStaticType = nil): IBlockExpressionNode;
|
|
begin
|
|
Result :=
|
|
TBlockExpressionNode.Create(
|
|
AExpressions,
|
|
if AStaticType <> nil then AStaticType
|
|
else TTypes.Unknown
|
|
);
|
|
end;
|
|
|
|
class function TAst.Constant(const AValue: TDataValue; const AStaticType: IStaticType = nil): IConstantNode;
|
|
begin
|
|
var constType := AStaticType;
|
|
if constType = nil then
|
|
begin
|
|
case AValue.Kind of
|
|
TDataValueKind.vkScalar: constType := TTypes.FromScalarKind(AValue.AsScalar.Kind);
|
|
TDataValueKind.vkText: constType := TTypes.Text;
|
|
TDataValueKind.vkVoid: constType := TTypes.Void;
|
|
else
|
|
constType := TTypes.Unknown;
|
|
end;
|
|
end;
|
|
Result := TConstantNode.Create(AValue, constType);
|
|
end;
|
|
|
|
class function TAst.Constant(const AValue: String): IConstantNode;
|
|
begin
|
|
Result := TConstantNode.Create(AValue, TTypes.Text);
|
|
end;
|
|
|
|
class constructor TAst.Create;
|
|
begin
|
|
FLibraries := TList<TRegisterLibraryProc>.Create;
|
|
end;
|
|
|
|
class destructor TAst.Destroy;
|
|
begin
|
|
FLibraries.Free;
|
|
end;
|
|
|
|
class procedure TAst.RegisterLibrary(const AProc: TRegisterLibraryProc);
|
|
begin
|
|
FLibraries.Add(AProc);
|
|
end;
|
|
|
|
class function TAst.FunctionCall(
|
|
const ACallee: IAstNode;
|
|
const AArguments: TArray<IAstNode>;
|
|
const AStaticType: IStaticType = nil;
|
|
const AIsTailCall: Boolean = False;
|
|
const AStaticTarget: TDataValue.TFunc = nil;
|
|
const AIsTargetPure: Boolean = False // (* ADDED *)
|
|
): IFunctionCallNode;
|
|
begin
|
|
Result :=
|
|
TFunctionCallNode.Create(
|
|
ACallee,
|
|
AArguments,
|
|
if AStaticType <> nil then AStaticType
|
|
else TTypes.Unknown,
|
|
AIsTailCall,
|
|
AStaticTarget,
|
|
AIsTargetPure
|
|
);
|
|
end;
|
|
|
|
class function TAst.Identifier(AName: string; const AStaticType: IStaticType = nil): IIdentifierNode;
|
|
begin
|
|
Result :=
|
|
TIdentifierNode.Create(
|
|
AName,
|
|
Default(TResolvedAddress),
|
|
if AStaticType <> nil then AStaticType
|
|
else TTypes.Unknown
|
|
);
|
|
end;
|
|
|
|
class function TAst.Identifier(AName: string; const Address: TResolvedAddress; const AStaticType: IStaticType = nil): IIdentifierNode;
|
|
begin
|
|
Result :=
|
|
TIdentifierNode.Create(
|
|
AName,
|
|
Address,
|
|
if AStaticType <> nil then AStaticType
|
|
else TTypes.Unknown
|
|
);
|
|
end;
|
|
|
|
class function TAst.IfExpr(
|
|
const ACondition: IAstNode;
|
|
const AThenBranch, AElseBranch: IAstNode;
|
|
const AStaticType: IStaticType = nil
|
|
): IIfExpressionNode;
|
|
begin
|
|
Result :=
|
|
TIfExpressionNode.Create(
|
|
ACondition,
|
|
AThenBranch,
|
|
AElseBranch,
|
|
if AStaticType <> nil then AStaticType
|
|
else TTypes.Unknown
|
|
);
|
|
end;
|
|
|
|
class function TAst.Indexer(const ABase: IAstNode; const AIndex: IAstNode; const AStaticType: IStaticType = nil): IIndexerNode;
|
|
begin
|
|
Result :=
|
|
TIndexerNode.Create(
|
|
ABase,
|
|
AIndex,
|
|
if AStaticType <> nil then AStaticType
|
|
else TTypes.Unknown
|
|
);
|
|
end;
|
|
|
|
class function TAst.Keyword(const AName: string): IKeywordNode;
|
|
begin
|
|
Result := TKeywordNode.Create(TKeywordRegistry.Intern(AName));
|
|
end;
|
|
|
|
class function TAst.LambdaExpr(
|
|
const AParameters: TArray<IIdentifierNode>;
|
|
const ABody: IAstNode;
|
|
const ALayout: IScopeLayout = nil;
|
|
const ADescriptor: IScopeDescriptor = nil;
|
|
const AUpvalues: TArray<TResolvedAddress> = nil;
|
|
const AHasNestedLambdas: Boolean = False;
|
|
const AIsPure: Boolean = False; // (* ADDED *)
|
|
const AStaticType: IStaticType = nil
|
|
): ILambdaExpressionNode;
|
|
begin
|
|
Result :=
|
|
TLambdaExpressionNode.Create(
|
|
AParameters,
|
|
ABody,
|
|
if AStaticType <> nil then AStaticType
|
|
else TTypes.Unknown,
|
|
ALayout,
|
|
ADescriptor,
|
|
AUpvalues,
|
|
AHasNestedLambdas,
|
|
AIsPure
|
|
);
|
|
end;
|
|
|
|
class function TAst.MacroDef(
|
|
const AName: IIdentifierNode;
|
|
const AParameters: TArray<IIdentifierNode>;
|
|
const ABody: IAstNode
|
|
): IMacroDefinitionNode;
|
|
begin
|
|
Result := TMacroDefinitionNode.Create(AName, AParameters, ABody);
|
|
end;
|
|
|
|
class function TAst.MacroExpansionNode(const AOriginalCallNode: IFunctionCallNode; const AExpandedBody: IAstNode): IMacroExpansionNode;
|
|
begin
|
|
Result := TMacroExpansionNode.Create(AOriginalCallNode, AExpandedBody);
|
|
end;
|
|
|
|
class function TAst.MemberAccess(
|
|
const ABase: IAstNode;
|
|
const AMember: IKeywordNode;
|
|
const AStaticType: IStaticType = nil
|
|
): IMemberAccessNode;
|
|
begin
|
|
Result :=
|
|
TMemberAccessNode.Create(
|
|
ABase,
|
|
AMember,
|
|
if AStaticType <> nil then AStaticType
|
|
else TTypes.Unknown
|
|
);
|
|
end;
|
|
|
|
class function TAst.Nop(const AStaticType: IStaticType = nil): IAstNode;
|
|
begin
|
|
Result := TNopNode.Create(TTypes.Unknown);
|
|
end;
|
|
|
|
class function TAst.Quasiquote(const AExpression: IAstNode): IQuasiquoteNode;
|
|
begin
|
|
Result := TQuasiquoteNode.Create(AExpression);
|
|
end;
|
|
|
|
class function TAst.Recur(const AArguments: array of IAstNode; const AStaticType: IStaticType = nil): IRecurNode;
|
|
var
|
|
args: TArray<IAstNode>;
|
|
i: Integer;
|
|
begin
|
|
SetLength(args, Length(AArguments));
|
|
for i := 0 to High(AArguments) do
|
|
args[i] := AArguments[i];
|
|
Result :=
|
|
TRecurNode.Create(
|
|
args,
|
|
if AStaticType <> nil then AStaticType
|
|
else TTypes.Void
|
|
);
|
|
end;
|
|
|
|
class function TAst.RecordLiteral(
|
|
const AFields: TArray<TRecordFieldLiteral>;
|
|
const AScalarDefinition: IScalarRecordDefinition = nil;
|
|
const AGenericDefinition: IGenericRecordDefinition = nil;
|
|
const AStaticType: IStaticType = nil
|
|
): IRecordLiteralNode;
|
|
begin
|
|
Result :=
|
|
TRecordLiteralNode.Create(
|
|
AFields,
|
|
AScalarDefinition,
|
|
AGenericDefinition,
|
|
if AStaticType <> nil then AStaticType
|
|
else TTypes.Unknown
|
|
);
|
|
end;
|
|
|
|
class function TAst.TernaryExpr(
|
|
const ACondition: IAstNode;
|
|
const AThenBranch, AElseBranch: IAstNode;
|
|
const AStaticType: IStaticType = nil
|
|
): ITernaryExpressionNode;
|
|
begin
|
|
Result :=
|
|
TTernaryExpressionNode.Create(
|
|
ACondition,
|
|
AThenBranch,
|
|
AElseBranch,
|
|
if AStaticType <> nil then AStaticType
|
|
else TTypes.Unknown
|
|
);
|
|
end;
|
|
|
|
class function TAst.Unquote(const AExpression: IAstNode): IUnquoteNode;
|
|
begin
|
|
Result := TUnquoteNode.Create(AExpression);
|
|
end;
|
|
|
|
class function TAst.UnquoteSplicing(const AExpression: IQuasiquoteNode): IUnquoteSplicingNode;
|
|
begin
|
|
Result := TUnquoteSplicingNode.Create(AExpression);
|
|
end;
|
|
|
|
class function TAst.VarDecl(
|
|
const AIdentifier: IAstNode;
|
|
AInitializer: IAstNode = nil;
|
|
const AStaticType: IStaticType = nil;
|
|
const AIsBoxed: Boolean = False
|
|
): IVariableDeclarationNode;
|
|
begin
|
|
Result :=
|
|
TVariableDeclarationNode.Create(
|
|
AIdentifier,
|
|
AInitializer,
|
|
if AStaticType <> nil then AStaticType
|
|
else TTypes.Unknown,
|
|
AIsBoxed
|
|
);
|
|
end;
|
|
|
|
{ TNopNode }
|
|
|
|
constructor TNopNode.Create(const AStaticType: IStaticType);
|
|
begin
|
|
inherited Create(AStaticType);
|
|
end;
|
|
|
|
function TNopNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitNop(Self);
|
|
end;
|
|
|
|
function TNopNode.AsNop: INopNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TNopNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akNop;
|
|
end;
|
|
|
|
{ TAstNode }
|
|
|
|
constructor TAstNode.Create;
|
|
begin
|
|
inherited Create;
|
|
end;
|
|
|
|
function TAstNode.AsAddSeriesItem: IAddSeriesItemNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not an AddSeriesItem');
|
|
end;
|
|
|
|
function TAstNode.AsAssignment: IAssignmentNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not an Assignment');
|
|
end;
|
|
|
|
function TAstNode.AsBlockExpression: IBlockExpressionNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a BlockExpression');
|
|
end;
|
|
|
|
function TAstNode.AsConstant: IConstantNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a Constant');
|
|
end;
|
|
|
|
function TAstNode.AsCreateSeries: ICreateSeriesNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a CreateSeries');
|
|
end;
|
|
|
|
function TAstNode.AsFunctionCall: IFunctionCallNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a FunctionCall');
|
|
end;
|
|
|
|
function TAstNode.AsIdentifier: IIdentifierNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not an Identifier');
|
|
end;
|
|
|
|
function TAstNode.AsIfExpression: IIfExpressionNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not an IfExpression');
|
|
end;
|
|
|
|
function TAstNode.AsIndexer: IIndexerNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not an Indexer');
|
|
end;
|
|
|
|
function TAstNode.AsKeyword: IKeywordNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a Keyword');
|
|
end;
|
|
|
|
function TAstNode.AsLambdaExpression: ILambdaExpressionNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a LambdaExpression');
|
|
end;
|
|
|
|
function TAstNode.AsMacroDefinition: IMacroDefinitionNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a MacroDefinition');
|
|
end;
|
|
|
|
function TAstNode.AsMacroExpansion: IMacroExpansionNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a MacroExpansion');
|
|
end;
|
|
|
|
function TAstNode.AsMemberAccess: IMemberAccessNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a MemberAccess');
|
|
end;
|
|
|
|
function TAstNode.AsNop: INopNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a Nop');
|
|
end;
|
|
|
|
function TAstNode.AsQuasiquote: IQuasiquoteNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a Quasiquote');
|
|
end;
|
|
|
|
function TAstNode.AsRecordLiteral: IRecordLiteralNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a RecordLiteral');
|
|
end;
|
|
|
|
function TAstNode.AsRecur: IRecurNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a Recur');
|
|
end;
|
|
|
|
function TAstNode.AsSeriesLength: ISeriesLengthNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a SeriesLength');
|
|
end;
|
|
|
|
function TAstNode.AsTernaryExpression: ITernaryExpressionNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a TernaryExpression');
|
|
end;
|
|
|
|
function TAstNode.AsTypedNode: IAstTypedNode;
|
|
begin
|
|
raise ETypeException.Create('Node has no type');
|
|
end;
|
|
|
|
function TAstNode.AsUnquote: IUnquoteNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not an Unquote');
|
|
end;
|
|
|
|
function TAstNode.AsUnquoteSplicing: IUnquoteSplicingNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not an UnquoteSplicing');
|
|
end;
|
|
|
|
function TAstNode.AsVariableDeclaration: IVariableDeclarationNode;
|
|
begin
|
|
raise ETypeException.Create('Node is not a VariableDeclaration');
|
|
end;
|
|
|
|
function TAstNode.GetIsTyped: Boolean;
|
|
begin
|
|
Result := false;
|
|
end;
|
|
|
|
{ TAstTypedNode }
|
|
|
|
constructor TAstTypedNode.Create(const AStaticType: IStaticType);
|
|
begin
|
|
inherited Create;
|
|
FStaticType := AStaticType;
|
|
Assert(FStaticType <> nil);
|
|
end;
|
|
|
|
function TAstTypedNode.AsTypedNode: IAstTypedNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TAstTypedNode.GetIsTyped: Boolean;
|
|
begin
|
|
Result := true;
|
|
end;
|
|
|
|
function TAstTypedNode.GetStaticType: IStaticType;
|
|
begin
|
|
Result := FStaticType;
|
|
end;
|
|
|
|
{ TConstantNode }
|
|
|
|
constructor TConstantNode.Create(const AValue: TDataValue; const AStaticType: IStaticType);
|
|
begin
|
|
inherited Create(AStaticType);
|
|
FValue := AValue;
|
|
end;
|
|
|
|
function TConstantNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitConstant(Self);
|
|
end;
|
|
|
|
function TConstantNode.AsConstant: IConstantNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TConstantNode.GetValue: TDataValue;
|
|
begin
|
|
Result := FValue;
|
|
end;
|
|
|
|
function TConstantNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akConstant;
|
|
end;
|
|
|
|
{ TIdentifierNode }
|
|
|
|
constructor TIdentifierNode.Create(const AName: string; const AAddress: TResolvedAddress; const AStaticType: IStaticType);
|
|
begin
|
|
inherited Create(AStaticType);
|
|
FName := AName;
|
|
FAddress := AAddress;
|
|
end;
|
|
|
|
function TIdentifierNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitIdentifier(Self);
|
|
end;
|
|
|
|
function TIdentifierNode.AsIdentifier: IIdentifierNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TIdentifierNode.GetAddress: TResolvedAddress;
|
|
begin
|
|
Result := FAddress;
|
|
end;
|
|
|
|
function TIdentifierNode.GetName: string;
|
|
begin
|
|
Result := FName;
|
|
end;
|
|
|
|
function TIdentifierNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akIdentifier;
|
|
end;
|
|
|
|
{ TKeywordNode }
|
|
|
|
constructor TKeywordNode.Create(const AValue: IKeyword);
|
|
begin
|
|
inherited Create(TTypes.Keyword);
|
|
FValue := AValue;
|
|
end;
|
|
|
|
function TKeywordNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitKeyword(Self);
|
|
end;
|
|
|
|
function TKeywordNode.AsKeyword: IKeywordNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TKeywordNode.GetValue: IKeyword;
|
|
begin
|
|
Result := FValue;
|
|
end;
|
|
|
|
function TKeywordNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akKeyword;
|
|
end;
|
|
|
|
{ TIfExpressionNode }
|
|
|
|
constructor TIfExpressionNode.Create(const ACondition, AThenBranch, AElseBranch: IAstNode; const AStaticType: IStaticType);
|
|
begin
|
|
inherited Create(AStaticType);
|
|
FCondition := ACondition;
|
|
FThenBranch := AThenBranch;
|
|
FElseBranch := AElseBranch;
|
|
end;
|
|
|
|
function TIfExpressionNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitIfExpression(Self);
|
|
end;
|
|
|
|
function TIfExpressionNode.AsIfExpression: IIfExpressionNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TIfExpressionNode.GetCondition: IAstNode;
|
|
begin
|
|
Result := FCondition;
|
|
end;
|
|
|
|
function TIfExpressionNode.GetElseBranch: IAstNode;
|
|
begin
|
|
Result := FElseBranch;
|
|
end;
|
|
|
|
function TIfExpressionNode.GetThenBranch: IAstNode;
|
|
begin
|
|
Result := FThenBranch;
|
|
end;
|
|
|
|
function TIfExpressionNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akIfExpression;
|
|
end;
|
|
|
|
{ TTernaryExpressionNode }
|
|
|
|
constructor TTernaryExpressionNode.Create(const ACondition, AThenBranch, AElseBranch: IAstNode; const AStaticType: IStaticType);
|
|
begin
|
|
inherited Create(AStaticType);
|
|
FCondition := ACondition;
|
|
FThenBranch := AThenBranch;
|
|
FElseBranch := AElseBranch;
|
|
end;
|
|
|
|
function TTernaryExpressionNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitTernaryExpression(Self);
|
|
end;
|
|
|
|
function TTernaryExpressionNode.AsTernaryExpression: ITernaryExpressionNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TTernaryExpressionNode.GetCondition: IAstNode;
|
|
begin
|
|
Result := FCondition;
|
|
end;
|
|
|
|
function TTernaryExpressionNode.GetElseBranch: IAstNode;
|
|
begin
|
|
Result := FElseBranch;
|
|
end;
|
|
|
|
function TTernaryExpressionNode.GetThenBranch: IAstNode;
|
|
begin
|
|
Result := FThenBranch;
|
|
end;
|
|
|
|
function TTernaryExpressionNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akTernaryExpression;
|
|
end;
|
|
|
|
{ TLambdaExpressionNode }
|
|
|
|
constructor TLambdaExpressionNode.Create(
|
|
const AParameters: TArray<IIdentifierNode>;
|
|
const ABody: IAstNode;
|
|
const AStaticType: IStaticType;
|
|
const ALayout: IScopeLayout;
|
|
const ADescriptor: IScopeDescriptor;
|
|
const AUpvalues: TArray<TResolvedAddress>;
|
|
const AHasNestedLambdas: Boolean;
|
|
const AIsPure: Boolean // (* ADDED *)
|
|
);
|
|
begin
|
|
inherited Create(AStaticType);
|
|
FParameters := AParameters;
|
|
FBody := ABody;
|
|
FLayout := ALayout;
|
|
FDescriptor := ADescriptor;
|
|
FUpvalues := AUpvalues;
|
|
FHasNestedLambdas := AHasNestedLambdas;
|
|
FIsPure := AIsPure;
|
|
|
|
// Consistency Check
|
|
if Assigned(FDescriptor) and (FDescriptor.Layout <> FLayout) then
|
|
raise Exception.Create('Consistency Error: Lambda Descriptor does not match Layout.');
|
|
end;
|
|
|
|
destructor TLambdaExpressionNode.Destroy;
|
|
begin
|
|
inherited;
|
|
end;
|
|
|
|
function TLambdaExpressionNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitLambdaExpression(Self);
|
|
end;
|
|
|
|
function TLambdaExpressionNode.AsLambdaExpression: ILambdaExpressionNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TLambdaExpressionNode.GetBody: IAstNode;
|
|
begin
|
|
Result := FBody;
|
|
end;
|
|
|
|
function TLambdaExpressionNode.GetParameters: TArray<IIdentifierNode>;
|
|
begin
|
|
Result := FParameters;
|
|
end;
|
|
|
|
function TLambdaExpressionNode.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; // (* ADDED *)
|
|
begin
|
|
Result := FIsPure;
|
|
end;
|
|
|
|
function TLambdaExpressionNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akLambdaExpression;
|
|
end;
|
|
|
|
{ TMacroDefinitionNode }
|
|
|
|
constructor TMacroDefinitionNode.Create(const AName: IIdentifierNode; const AParameters: TArray<IIdentifierNode>; const ABody: IAstNode);
|
|
begin
|
|
inherited Create(TTypes.Void);
|
|
FName := AName;
|
|
FParameters := AParameters;
|
|
FBody := ABody;
|
|
end;
|
|
|
|
function TMacroDefinitionNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitMacroDefinition(Self);
|
|
end;
|
|
|
|
function TMacroDefinitionNode.AsMacroDefinition: IMacroDefinitionNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TMacroDefinitionNode.GetBody: IAstNode;
|
|
begin
|
|
Result := FBody;
|
|
end;
|
|
|
|
function TMacroDefinitionNode.GetName: IIdentifierNode;
|
|
begin
|
|
Result := FName;
|
|
end;
|
|
|
|
function TMacroDefinitionNode.GetParameters: TArray<IIdentifierNode>;
|
|
begin
|
|
Result := FParameters;
|
|
end;
|
|
|
|
function TMacroDefinitionNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akMacroDefinition;
|
|
end;
|
|
|
|
{ TQuasiquoteNode }
|
|
|
|
constructor TQuasiquoteNode.Create(const AExpression: IAstNode);
|
|
begin
|
|
inherited Create;
|
|
FExpression := AExpression;
|
|
end;
|
|
|
|
function TQuasiquoteNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitQuasiquote(Self);
|
|
end;
|
|
|
|
function TQuasiquoteNode.AsQuasiquote: IQuasiquoteNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TQuasiquoteNode.GetExpression: IAstNode;
|
|
begin
|
|
Result := FExpression;
|
|
end;
|
|
|
|
function TQuasiquoteNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akQuasiquote;
|
|
end;
|
|
|
|
{ TUnquoteNode }
|
|
|
|
constructor TUnquoteNode.Create(const AExpression: IAstNode);
|
|
begin
|
|
inherited Create;
|
|
FExpression := AExpression;
|
|
end;
|
|
|
|
function TUnquoteNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitUnquote(Self);
|
|
end;
|
|
|
|
function TUnquoteNode.AsUnquote: IUnquoteNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TUnquoteNode.GetExpression: IAstNode;
|
|
begin
|
|
Result := FExpression;
|
|
end;
|
|
|
|
function TUnquoteNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akUnquote;
|
|
end;
|
|
|
|
{ TUnquoteSplicingNode }
|
|
|
|
constructor TUnquoteSplicingNode.Create(const AExpression: IQuasiquoteNode);
|
|
begin
|
|
inherited Create;
|
|
FExpression := AExpression;
|
|
end;
|
|
|
|
function TUnquoteSplicingNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitUnquoteSplicing(Self);
|
|
end;
|
|
|
|
function TUnquoteSplicingNode.AsUnquoteSplicing: IUnquoteSplicingNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TUnquoteSplicingNode.GetExpression: IQuasiquoteNode;
|
|
begin
|
|
Result := FExpression;
|
|
end;
|
|
|
|
function TUnquoteSplicingNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akUnquoteSplicing;
|
|
end;
|
|
|
|
{ TFunctionCallNode }
|
|
|
|
constructor TFunctionCallNode.Create(
|
|
const ACallee: IAstNode;
|
|
const AArguments: TArray<IAstNode>;
|
|
const AStaticType: IStaticType;
|
|
const AIsTailCall: Boolean;
|
|
const AStaticTarget: TDataValue.TFunc;
|
|
const AIsTargetPure: Boolean // (* ADDED *)
|
|
);
|
|
begin
|
|
inherited Create(AStaticType);
|
|
FCallee := ACallee;
|
|
FArguments := AArguments;
|
|
FIsTailCall := AIsTailCall;
|
|
FStaticTarget := AStaticTarget;
|
|
FIsTargetPure := AIsTargetPure;
|
|
end;
|
|
|
|
function TFunctionCallNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitFunctionCall(Self);
|
|
end;
|
|
|
|
function TFunctionCallNode.AsFunctionCall: IFunctionCallNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TFunctionCallNode.GetArguments: TArray<IAstNode>;
|
|
begin
|
|
Result := FArguments;
|
|
end;
|
|
|
|
function TFunctionCallNode.GetCallee: IAstNode;
|
|
begin
|
|
Result := FCallee;
|
|
end;
|
|
|
|
function TFunctionCallNode.GetIsTailCall: Boolean;
|
|
begin
|
|
Result := FIsTailCall;
|
|
end;
|
|
|
|
function TFunctionCallNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akFunctionCall;
|
|
end;
|
|
|
|
function TFunctionCallNode.GetStaticTarget: TDataValue.TFunc;
|
|
begin
|
|
Result := FStaticTarget;
|
|
end;
|
|
|
|
function TFunctionCallNode.GetIsTargetPure: Boolean; // (* ADDED *)
|
|
begin
|
|
Result := FIsTargetPure;
|
|
end;
|
|
|
|
{ TMacroExpansionNode }
|
|
|
|
constructor TMacroExpansionNode.Create(const ACallNode: IFunctionCallNode; const AExpandedBody: IAstNode);
|
|
begin
|
|
if AExpandedBody.IsTyped then
|
|
inherited Create(AExpandedBody.AsTypedNode.StaticType)
|
|
else
|
|
inherited Create(TTypes.Unknown);
|
|
|
|
FExpandedBody := AExpandedBody;
|
|
FCallNode := ACallNode;
|
|
end;
|
|
|
|
function TMacroExpansionNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitMacroExpansionNode(Self);
|
|
end;
|
|
|
|
function TMacroExpansionNode.AsMacroExpansion: IMacroExpansionNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TMacroExpansionNode.GetCallNode: IFunctionCallNode;
|
|
begin
|
|
Result := FCallNode;
|
|
end;
|
|
|
|
function TMacroExpansionNode.GetExpandedBody: IAstNode;
|
|
begin
|
|
Result := FExpandedBody;
|
|
end;
|
|
|
|
function TMacroExpansionNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akMacroExpansion;
|
|
end;
|
|
|
|
{ TRecurNode }
|
|
|
|
constructor TRecurNode.Create(const AArguments: TArray<IAstNode>; const AStaticType: IStaticType);
|
|
begin
|
|
inherited Create(AStaticType);
|
|
FArguments := AArguments;
|
|
end;
|
|
|
|
function TRecurNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitRecurNode(Self);
|
|
end;
|
|
|
|
function TRecurNode.AsRecur: IRecurNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TRecurNode.GetArguments: TArray<IAstNode>;
|
|
begin
|
|
Result := FArguments;
|
|
end;
|
|
|
|
function TRecurNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akRecur;
|
|
end;
|
|
|
|
{ TBlockExpressionNode }
|
|
|
|
constructor TBlockExpressionNode.Create(const AExpressions: array of IAstNode; const AStaticType: IStaticType);
|
|
var
|
|
i: Integer;
|
|
begin
|
|
inherited Create(AStaticType);
|
|
SetLength(FExpressions, Length(AExpressions));
|
|
for i := 0 to High(AExpressions) do
|
|
FExpressions[i] := AExpressions[i];
|
|
end;
|
|
|
|
function TBlockExpressionNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitBlockExpression(Self);
|
|
end;
|
|
|
|
function TBlockExpressionNode.AsBlockExpression: IBlockExpressionNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TBlockExpressionNode.GetExpressions: TArray<IAstNode>;
|
|
begin
|
|
Result := FExpressions;
|
|
end;
|
|
|
|
function TBlockExpressionNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akBlockExpression;
|
|
end;
|
|
|
|
{ TVariableDeclarationNode }
|
|
|
|
constructor TVariableDeclarationNode.Create(
|
|
const ATarget: IAstNode;
|
|
AInitializer: IAstNode;
|
|
const AStaticType: IStaticType;
|
|
const AIsBoxed: Boolean
|
|
);
|
|
begin
|
|
inherited Create(AStaticType);
|
|
FTarget := ATarget;
|
|
FInitializer := AInitializer;
|
|
FIsBoxed := AIsBoxed;
|
|
end;
|
|
|
|
function TVariableDeclarationNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitVariableDeclaration(Self);
|
|
end;
|
|
|
|
function TVariableDeclarationNode.AsVariableDeclaration: IVariableDeclarationNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TVariableDeclarationNode.GetTarget: IAstNode;
|
|
begin
|
|
Result := FTarget;
|
|
end;
|
|
|
|
function TVariableDeclarationNode.GetInitializer: IAstNode;
|
|
begin
|
|
Result := FInitializer;
|
|
end;
|
|
|
|
function TVariableDeclarationNode.GetIsBoxed: Boolean;
|
|
begin
|
|
Result := FIsBoxed;
|
|
end;
|
|
|
|
function TVariableDeclarationNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akVariableDeclaration;
|
|
end;
|
|
|
|
{ TAssignmentNode }
|
|
|
|
constructor TAssignmentNode.Create(const ATarget: IAstNode; const AValue: IAstNode; const AStaticType: IStaticType);
|
|
begin
|
|
inherited Create(AStaticType);
|
|
FTarget := ATarget;
|
|
FValue := AValue;
|
|
end;
|
|
|
|
function TAssignmentNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitAssignment(Self);
|
|
end;
|
|
|
|
function TAssignmentNode.AsAssignment: IAssignmentNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TAssignmentNode.GetTarget: IAstNode;
|
|
begin
|
|
Result := FTarget;
|
|
end;
|
|
|
|
function TAssignmentNode.GetValue: IAstNode;
|
|
begin
|
|
Result := FValue;
|
|
end;
|
|
|
|
function TAssignmentNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akAssignment;
|
|
end;
|
|
|
|
{ TIndexerNode }
|
|
|
|
constructor TIndexerNode.Create(const ABase: IAstNode; const AIndex: IAstNode; const AStaticType: IStaticType);
|
|
begin
|
|
inherited Create(AStaticType);
|
|
FBase := ABase;
|
|
FIndex := AIndex;
|
|
end;
|
|
|
|
function TIndexerNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitIndexer(Self);
|
|
end;
|
|
|
|
function TIndexerNode.AsIndexer: IIndexerNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TIndexerNode.GetBase: IAstNode;
|
|
begin
|
|
Result := FBase;
|
|
end;
|
|
|
|
function TIndexerNode.GetIndex: IAstNode;
|
|
begin
|
|
Result := FIndex;
|
|
end;
|
|
|
|
function TIndexerNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akIndexer;
|
|
end;
|
|
|
|
{ TMemberAccessNode }
|
|
|
|
constructor TMemberAccessNode.Create(const ABase: IAstNode; const AMember: IKeywordNode; const AStaticType: IStaticType);
|
|
begin
|
|
inherited Create(AStaticType);
|
|
FBase := ABase;
|
|
FMember := AMember;
|
|
end;
|
|
|
|
function TMemberAccessNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitMemberAccess(Self);
|
|
end;
|
|
|
|
function TMemberAccessNode.AsMemberAccess: IMemberAccessNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TMemberAccessNode.GetBase: IAstNode;
|
|
begin
|
|
Result := FBase;
|
|
end;
|
|
|
|
function TMemberAccessNode.GetMember: IKeywordNode;
|
|
begin
|
|
Result := FMember;
|
|
end;
|
|
|
|
function TMemberAccessNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akMemberAccess;
|
|
end;
|
|
|
|
{ TRecordLiteralNode }
|
|
|
|
constructor TRecordLiteralNode.Create(
|
|
const AFields: TArray<TRecordFieldLiteral>;
|
|
const AScalarDefinition: IScalarRecordDefinition;
|
|
const AGenericDefinition: IGenericRecordDefinition;
|
|
const AStaticType: IStaticType
|
|
);
|
|
begin
|
|
inherited Create(AStaticType);
|
|
FFields := AFields;
|
|
FGenericDefinition := AGenericDefinition;
|
|
FScalarDefinition := AScalarDefinition;
|
|
end;
|
|
|
|
function TRecordLiteralNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitRecordLiteral(Self);
|
|
end;
|
|
|
|
function TRecordLiteralNode.AsRecordLiteral: IRecordLiteralNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TRecordLiteralNode.GetFields: TArray<TRecordFieldLiteral>;
|
|
begin
|
|
Result := FFields;
|
|
end;
|
|
|
|
function TRecordLiteralNode.GetGenericDefinition: IGenericRecordDefinition;
|
|
begin
|
|
Result := FGenericDefinition;
|
|
end;
|
|
|
|
function TRecordLiteralNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akRecordLiteral;
|
|
end;
|
|
|
|
function TRecordLiteralNode.GetScalarDefinition: IScalarRecordDefinition;
|
|
begin
|
|
Result := FScalarDefinition;
|
|
end;
|
|
|
|
{ TCreateSeriesNode }
|
|
|
|
constructor TCreateSeriesNode.Create(const ADefinition: String; const AStaticType: IStaticType);
|
|
begin
|
|
inherited Create(AStaticType);
|
|
FDefinition := ADefinition;
|
|
end;
|
|
|
|
function TCreateSeriesNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitCreateSeries(Self);
|
|
end;
|
|
|
|
function TCreateSeriesNode.AsCreateSeries: ICreateSeriesNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TCreateSeriesNode.GetDefinition: String;
|
|
begin
|
|
Result := FDefinition;
|
|
end;
|
|
|
|
function TCreateSeriesNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akCreateSeries;
|
|
end;
|
|
|
|
{ TAddSeriesItemNode }
|
|
|
|
constructor TAddSeriesItemNode.Create(
|
|
const ASeries: IIdentifierNode;
|
|
const AValue: IAstNode;
|
|
const ALookback: IAstNode;
|
|
const AStaticType: IStaticType
|
|
);
|
|
begin
|
|
inherited Create(AStaticType);
|
|
FSeries := ASeries;
|
|
FValue := AValue;
|
|
FLookback := ALookback;
|
|
end;
|
|
|
|
function TAddSeriesItemNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitAddSeriesItem(Self);
|
|
end;
|
|
|
|
function TAddSeriesItemNode.AsAddSeriesItem: IAddSeriesItemNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TAddSeriesItemNode.GetLookback: IAstNode;
|
|
begin
|
|
Result := FLookback;
|
|
end;
|
|
|
|
function TAddSeriesItemNode.GetSeries: IIdentifierNode;
|
|
begin
|
|
Result := FSeries;
|
|
end;
|
|
|
|
function TAddSeriesItemNode.GetValue: IAstNode;
|
|
begin
|
|
Result := FValue;
|
|
end;
|
|
|
|
function TAddSeriesItemNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akAddSeriesItem;
|
|
end;
|
|
|
|
{ TSeriesLengthNode }
|
|
|
|
constructor TSeriesLengthNode.Create(const ASeries: IIdentifierNode; const AStaticType: IStaticType);
|
|
begin
|
|
inherited Create(AStaticType);
|
|
FSeries := ASeries;
|
|
end;
|
|
|
|
function TSeriesLengthNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
|
begin
|
|
Result := Visitor.VisitSeriesLength(Self);
|
|
end;
|
|
|
|
function TSeriesLengthNode.AsSeriesLength: ISeriesLengthNode;
|
|
begin
|
|
Result := Self;
|
|
end;
|
|
|
|
function TSeriesLengthNode.GetSeries: IIdentifierNode;
|
|
begin
|
|
Result := FSeries;
|
|
end;
|
|
|
|
function TSeriesLengthNode.GetKind: TAstNodeKind;
|
|
begin
|
|
Result := akSeriesLength;
|
|
end;
|
|
|
|
end.
|