Refactoring node to be immutable
This commit is contained in:
@@ -256,7 +256,7 @@ begin
|
|||||||
|
|
||||||
// --- Replace Node ---
|
// --- Replace Node ---
|
||||||
// Create a new TBoundIdentifierNode (implementation is in Myc.Ast)
|
// Create a new TBoundIdentifierNode (implementation is in Myc.Ast)
|
||||||
var boundParamNode := TAst.BoundIdentifier(paramNode.Name, adr);
|
var boundParamNode := TAst.Identifier(paramNode.Name, adr);
|
||||||
// Replace it in the parameter array
|
// Replace it in the parameter array
|
||||||
N.Parameters[i] := boundParamNode;
|
N.Parameters[i] := boundParamNode;
|
||||||
end;
|
end;
|
||||||
@@ -345,7 +345,7 @@ begin
|
|||||||
|
|
||||||
// --- Replace Node ---
|
// --- Replace Node ---
|
||||||
// Create the new TBoundIdentifierNode (implementation is in Myc.Ast)
|
// Create the new TBoundIdentifierNode (implementation is in Myc.Ast)
|
||||||
Result := TAst.BoundIdentifier(Node.Name, adr);
|
Result := TAst.Identifier(Node.Name, adr);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
@@ -375,7 +375,7 @@ begin
|
|||||||
|
|
||||||
// 3. --- Replace Node ---
|
// 3. --- Replace Node ---
|
||||||
// Replace the TIdentifierNode with a new TBoundIdentifierNode
|
// Replace the TIdentifierNode with a new TBoundIdentifierNode
|
||||||
N.Identifier := TAst.BoundIdentifier(N.Identifier.Name, address);
|
N.Identifier := TAst.Identifier(N.Identifier.Name, address);
|
||||||
|
|
||||||
// 4. Mutate this declaration node
|
// 4. Mutate this declaration node
|
||||||
N.IsBoxed := (FBoxedDeclarations <> nil) and FBoxedDeclarations.Contains(Node);
|
N.IsBoxed := (FBoxedDeclarations <> nil) and FBoxedDeclarations.Contains(Node);
|
||||||
|
|||||||
@@ -145,8 +145,7 @@ procedure TAstDumper.VisitIdentifier(const Node: IIdentifierNode);
|
|||||||
var
|
var
|
||||||
adr: TResolvedAddress;
|
adr: TResolvedAddress;
|
||||||
begin
|
begin
|
||||||
if Node.Kind = akBoundIdentifier then
|
adr := Node.AsIdentifier.Address;
|
||||||
adr := Node.AsBoundIdentifierNode.Address;
|
|
||||||
|
|
||||||
if adr.Kind <> akUnresolved then
|
if adr.Kind <> akUnresolved then
|
||||||
LogFmt('Identifier: %s -> %s', [Node.Name, FormatAddress(adr)])
|
LogFmt('Identifier: %s -> %s', [Node.Name, FormatAddress(adr)])
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ begin
|
|||||||
for i := 0 to High(ArgValues) do
|
for i := 0 to High(ArgValues) do
|
||||||
begin
|
begin
|
||||||
// Parameters in a bound lambda must be bound identifiers.
|
// Parameters in a bound lambda must be bound identifiers.
|
||||||
adr.SlotIndex := params[i].AsBoundIdentifierNode.Address.SlotIndex; // Changed
|
adr.SlotIndex := params[i].AsIdentifier.Address.SlotIndex; // Changed
|
||||||
lambdaScope[adr] := ArgValues[i];
|
lambdaScope[adr] := ArgValues[i];
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@@ -334,7 +334,7 @@ var
|
|||||||
itemValue, lookbackValue, seriesVar: TDataValue;
|
itemValue, lookbackValue, seriesVar: TDataValue;
|
||||||
lookback: Int64;
|
lookback: Int64;
|
||||||
begin
|
begin
|
||||||
seriesVar := FScope[Node.Series.AsBoundIdentifierNode.Address]; // Changed
|
seriesVar := FScope[Node.Series.AsIdentifier.Address]; // Changed
|
||||||
itemValue := Node.Value.Accept(Self);
|
itemValue := Node.Value.Accept(Self);
|
||||||
lookback := -1;
|
lookback := -1;
|
||||||
|
|
||||||
@@ -368,7 +368,7 @@ begin
|
|||||||
// Evaluate the new value.
|
// Evaluate the new value.
|
||||||
Result := Node.Value.Accept(Self);
|
Result := Node.Value.Accept(Self);
|
||||||
// Assign it. The scope's SetValues implementation now handles boxing correctly.
|
// Assign it. The scope's SetValues implementation now handles boxing correctly.
|
||||||
FScope[Node.Identifier.AsBoundIdentifierNode.Address] := Result; // Changed
|
FScope[Node.Identifier.AsIdentifier.Address] := Result; // Changed
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TEvaluatorVisitor.VisitConstant(const Node: IConstantNode): TDataValue;
|
function TEvaluatorVisitor.VisitConstant(const Node: IConstantNode): TDataValue;
|
||||||
@@ -405,7 +405,7 @@ end;
|
|||||||
function TEvaluatorVisitor.VisitIdentifier(const Node: IIdentifierNode): TDataValue;
|
function TEvaluatorVisitor.VisitIdentifier(const Node: IIdentifierNode): TDataValue;
|
||||||
begin
|
begin
|
||||||
// The scope's GetValues implementation now handles unboxing automatically.
|
// The scope's GetValues implementation now handles unboxing automatically.
|
||||||
Result := FScope[Node.AsBoundIdentifierNode.Address]; // Changed
|
Result := FScope[Node.AsIdentifier.Address];
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TEvaluatorVisitor.VisitIndexer(const Node: IIndexerNode): TDataValue;
|
function TEvaluatorVisitor.VisitIndexer(const Node: IIndexerNode): TDataValue;
|
||||||
@@ -549,7 +549,7 @@ begin
|
|||||||
|
|
||||||
// After binding, all declaration nodes are TVariableDeclarationNode
|
// After binding, all declaration nodes are TVariableDeclarationNode
|
||||||
boundNode := Node as TVariableDeclarationNode;
|
boundNode := Node as TVariableDeclarationNode;
|
||||||
address := boundNode.Identifier.AsBoundIdentifierNode.Address;
|
address := boundNode.Identifier.AsIdentifier.Address;
|
||||||
|
|
||||||
// Check the IsBoxed flag set by the binder.
|
// Check the IsBoxed flag set by the binder.
|
||||||
if boundNode.IsBoxed then
|
if boundNode.IsBoxed then
|
||||||
@@ -641,7 +641,7 @@ var
|
|||||||
seriesValue: TDataValue;
|
seriesValue: TDataValue;
|
||||||
len: Int64;
|
len: Int64;
|
||||||
begin
|
begin
|
||||||
seriesValue := FScope[Node.Series.AsBoundIdentifierNode.Address]; // Changed
|
seriesValue := FScope[Node.Series.AsIdentifier.Address]; // Changed
|
||||||
|
|
||||||
case seriesValue.Kind of
|
case seriesValue.Kind of
|
||||||
vkSeries: len := seriesValue.AsSeries.Count;
|
vkSeries: len := seriesValue.AsSeries.Count;
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ type
|
|||||||
ISeriesLengthNode = interface;
|
ISeriesLengthNode = interface;
|
||||||
IRecurNode = interface;
|
IRecurNode = interface;
|
||||||
INopNode = interface;
|
INopNode = interface;
|
||||||
IBoundIdentifierNode = interface;
|
|
||||||
IAstTypedNode = interface;
|
IAstTypedNode = interface;
|
||||||
|
|
||||||
// Defines the concrete kinds of AST nodes
|
// Defines the concrete kinds of AST nodes
|
||||||
@@ -68,9 +67,7 @@ type
|
|||||||
akAddSeriesItem,
|
akAddSeriesItem,
|
||||||
akSeriesLength,
|
akSeriesLength,
|
||||||
akRecur,
|
akRecur,
|
||||||
akNop,
|
akNop
|
||||||
// Internal node produced by compiler
|
|
||||||
akBoundIdentifier
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Helper for TAstNodeKind providing a string representation
|
// Helper for TAstNodeKind providing a string representation
|
||||||
@@ -162,7 +159,6 @@ type
|
|||||||
function AsRecur: IRecurNode;
|
function AsRecur: IRecurNode;
|
||||||
function AsNop: INopNode;
|
function AsNop: INopNode;
|
||||||
|
|
||||||
function AsBoundIdentifierNode: IBoundIdentifierNode;
|
|
||||||
function AsTypedNode: IAstTypedNode;
|
function AsTypedNode: IAstTypedNode;
|
||||||
|
|
||||||
property IsTyped: Boolean read GetIsTyped;
|
property IsTyped: Boolean read GetIsTyped;
|
||||||
@@ -191,16 +187,11 @@ type
|
|||||||
|
|
||||||
IIdentifierNode = interface(IAstTypedNode)
|
IIdentifierNode = interface(IAstTypedNode)
|
||||||
{$region 'private'}
|
{$region 'private'}
|
||||||
|
function GetAddress: TResolvedAddress;
|
||||||
function GetName: string;
|
function GetName: string;
|
||||||
{$endregion}
|
{$endregion}
|
||||||
property Name: string read GetName;
|
|
||||||
end;
|
|
||||||
|
|
||||||
IBoundIdentifierNode = interface(IIdentifierNode)
|
|
||||||
{$region 'private'}
|
|
||||||
function GetAddress: TResolvedAddress;
|
|
||||||
{$endregion}
|
|
||||||
property Address: TResolvedAddress read GetAddress;
|
property Address: TResolvedAddress read GetAddress;
|
||||||
|
property Name: string read GetName;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Represents a keyword literal in the AST (e.g., :foo)
|
// Represents a keyword literal in the AST (e.g., :foo)
|
||||||
|
|||||||
@@ -111,10 +111,10 @@ begin
|
|||||||
|
|
||||||
// Get the type from the descriptor (which was populated by Binder/RTL)
|
// Get the type from the descriptor (which was populated by Binder/RTL)
|
||||||
symbol := FCurrentDescriptor.FindSymbol(Node.Name);
|
symbol := FCurrentDescriptor.FindSymbol(Node.Name);
|
||||||
adr := Node.AsBoundIdentifierNode.Address;
|
adr := Node.AsIdentifier.Address;
|
||||||
|
|
||||||
// Create a new node, copying the address and assigning the inferred type
|
// Create a new node, copying the address and assigning the inferred type
|
||||||
Result := TAst.BoundIdentifier(Node.Name, adr, symbol.StaticType);
|
Result := TAst.Identifier(Node.Name, adr, symbol.StaticType);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TTypeChecker.VisitRecurNode(const Node: IRecurNode): IAstNode;
|
function TTypeChecker.VisitRecurNode(const Node: IRecurNode): IAstNode;
|
||||||
@@ -153,14 +153,14 @@ begin
|
|||||||
|
|
||||||
// 3. Get the address from the bound identifier (SAFE CAST)
|
// 3. Get the address from the bound identifier (SAFE CAST)
|
||||||
boundIdent := Node.Identifier;
|
boundIdent := Node.Identifier;
|
||||||
adr := boundIdent.AsBoundIdentifierNode.Address;
|
adr := boundIdent.AsIdentifier.Address;
|
||||||
|
|
||||||
// 4. Update the type in the scope descriptor (which was set to Unknown by the binder).
|
// 4. Update the type in the scope descriptor (which was set to Unknown by the binder).
|
||||||
if initType.Kind <> stUnknown then
|
if initType.Kind <> stUnknown then
|
||||||
FCurrentDescriptor.UpdateType(adr.SlotIndex, initType);
|
FCurrentDescriptor.UpdateType(adr.SlotIndex, initType);
|
||||||
|
|
||||||
// 5. Create the new (typed) identifier node
|
// 5. Create the new (typed) identifier node
|
||||||
newIdent := TAst.BoundIdentifier(boundIdent.Name, adr, initType);
|
newIdent := TAst.Identifier(boundIdent.Name, adr, initType);
|
||||||
|
|
||||||
// 6. Create the new VariableDeclaration node
|
// 6. Create the new VariableDeclaration node
|
||||||
Result := TVariableDeclarationNode.Create(newIdent.AsIdentifier, newInitializer, initType);
|
Result := TVariableDeclarationNode.Create(newIdent.AsIdentifier, newInitializer, initType);
|
||||||
@@ -192,11 +192,11 @@ begin
|
|||||||
// with the new, inferred type. This enables recursion.
|
// with the new, inferred type. This enables recursion.
|
||||||
if (targetType.Kind = stUnknown) and (sourceType.Kind <> stUnknown) then
|
if (targetType.Kind = stUnknown) and (sourceType.Kind <> stUnknown) then
|
||||||
begin
|
begin
|
||||||
adr := newIdent.AsBoundIdentifierNode.Address;
|
adr := newIdent.AsIdentifier.Address;
|
||||||
FCurrentDescriptor.UpdateType(adr.SlotIndex, sourceType);
|
FCurrentDescriptor.UpdateType(adr.SlotIndex, sourceType);
|
||||||
|
|
||||||
// Re-create the identifier node *with the new type*
|
// Re-create the identifier node *with the new type*
|
||||||
newIdent := TAst.BoundIdentifier(newIdent.AsIdentifier.Name, adr, sourceType);
|
newIdent := TAst.Identifier(newIdent.AsIdentifier.Name, adr, sourceType);
|
||||||
targetType := sourceType;
|
targetType := sourceType;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@@ -229,8 +229,8 @@ begin
|
|||||||
// Parameters are leaves, but we must *replace* them with typed versions
|
// Parameters are leaves, but we must *replace* them with typed versions
|
||||||
// (even if they are just TTypes.Unknown for now, for type inference placeholders)
|
// (even if they are just TTypes.Unknown for now, for type inference placeholders)
|
||||||
var paramIdent := boundNode.Parameters[i];
|
var paramIdent := boundNode.Parameters[i];
|
||||||
var paramAdr := paramIdent.AsBoundIdentifierNode.Address;
|
var paramAdr := paramIdent.AsIdentifier.Address;
|
||||||
var newParam := TAst.BoundIdentifier(paramIdent.Name, paramAdr);
|
var newParam := TAst.Identifier(paramIdent.Name, paramAdr);
|
||||||
|
|
||||||
newParams[i] := newParam;
|
newParams[i] := newParam;
|
||||||
paramTypes[i] := TTypes.Unknown;
|
paramTypes[i] := TTypes.Unknown;
|
||||||
|
|||||||
+29
-63
@@ -36,7 +36,12 @@ type
|
|||||||
class function Constant(const AValue: TDataValue; const AStaticType: IStaticType = nil): IConstantNode; overload; static;
|
class function Constant(const AValue: TDataValue; const AStaticType: IStaticType = nil): IConstantNode; overload; static;
|
||||||
class function Constant(const AValue: String): IConstantNode; overload; static;
|
class function Constant(const AValue: String): IConstantNode; overload; static;
|
||||||
class function Keyword(const AName: string): IKeywordNode; static;
|
class function Keyword(const AName: string): IKeywordNode; static;
|
||||||
class function Identifier(AName: string; const AStaticType: IStaticType = nil): IIdentifierNode; 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 BinaryExpr(
|
class function BinaryExpr(
|
||||||
ALeft: IAstNode;
|
ALeft: IAstNode;
|
||||||
AOperator: TScalar.TBinaryOp;
|
AOperator: TScalar.TBinaryOp;
|
||||||
@@ -112,11 +117,6 @@ type
|
|||||||
): IAddSeriesItemNode; static;
|
): IAddSeriesItemNode; static;
|
||||||
class function SeriesLength(const ASeries: IIdentifierNode; const AStaticType: IStaticType = nil): ISeriesLengthNode; static;
|
class function SeriesLength(const ASeries: IIdentifierNode; const AStaticType: IStaticType = nil): ISeriesLengthNode; static;
|
||||||
|
|
||||||
class function BoundIdentifier(
|
|
||||||
AName: string;
|
|
||||||
const Address: TResolvedAddress;
|
|
||||||
const AStaticType: IStaticType = nil
|
|
||||||
): IBoundIdentifierNode; static;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Common base class for AST nodes to reduce boilerplate.
|
// Common base class for AST nodes to reduce boilerplate.
|
||||||
@@ -155,7 +155,6 @@ type
|
|||||||
function AsRecur: IRecurNode; virtual;
|
function AsRecur: IRecurNode; virtual;
|
||||||
function AsNop: INopNode; virtual; // Added Nop
|
function AsNop: INopNode; virtual; // Added Nop
|
||||||
|
|
||||||
function AsBoundIdentifierNode: IBoundIdentifierNode; virtual;
|
|
||||||
function AsTypedNode: IAstTypedNode; virtual;
|
function AsTypedNode: IAstTypedNode; virtual;
|
||||||
|
|
||||||
property IsTyped: Boolean read GetIsTyped;
|
property IsTyped: Boolean read GetIsTyped;
|
||||||
@@ -271,25 +270,17 @@ type
|
|||||||
|
|
||||||
TIdentifierNode = class(TAstTypedNode, IIdentifierNode)
|
TIdentifierNode = class(TAstTypedNode, IIdentifierNode)
|
||||||
private
|
private
|
||||||
|
FAddress: TResolvedAddress;
|
||||||
FName: string;
|
FName: string;
|
||||||
|
function GetAddress: TResolvedAddress;
|
||||||
function GetName: string;
|
function GetName: string;
|
||||||
function GetKind: TAstNodeKind; override;
|
function GetKind: TAstNodeKind; override;
|
||||||
public
|
public
|
||||||
constructor Create(const AName: string; const AStaticType: IStaticType);
|
constructor Create(const AName: string; const AAddress: TResolvedAddress; const AStaticType: IStaticType);
|
||||||
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
||||||
function AsIdentifier: IIdentifierNode; override;
|
function AsIdentifier: IIdentifierNode; override;
|
||||||
property Name: string read FName;
|
|
||||||
end;
|
|
||||||
|
|
||||||
TBoundIdentifierNode = class(TIdentifierNode, IBoundIdentifierNode)
|
|
||||||
private
|
|
||||||
FAddress: TResolvedAddress;
|
|
||||||
function GetAddress: TResolvedAddress;
|
|
||||||
function GetKind: TAstNodeKind; override;
|
|
||||||
public
|
|
||||||
constructor Create(const AName: string; const AAddress: TResolvedAddress; const AStaticType: IStaticType);
|
|
||||||
function AsBoundIdentifierNode: IBoundIdentifierNode; override;
|
|
||||||
property Address: TResolvedAddress read GetAddress;
|
property Address: TResolvedAddress read GetAddress;
|
||||||
|
property Name: string read FName;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TKeywordNode = class(TAstTypedNode, IKeywordNode)
|
TKeywordNode = class(TAstTypedNode, IKeywordNode)
|
||||||
@@ -701,21 +692,6 @@ begin
|
|||||||
FLibraries.Free;
|
FLibraries.Free;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
class function TAst.BoundIdentifier(
|
|
||||||
AName: string;
|
|
||||||
const Address: TResolvedAddress;
|
|
||||||
const AStaticType: IStaticType = nil
|
|
||||||
): IBoundIdentifierNode;
|
|
||||||
begin
|
|
||||||
Result :=
|
|
||||||
TBoundIdentifierNode.Create(
|
|
||||||
AName,
|
|
||||||
Address,
|
|
||||||
if AStaticType <> nil then AStaticType
|
|
||||||
else TTypes.Unknown
|
|
||||||
);
|
|
||||||
end;
|
|
||||||
|
|
||||||
class procedure TAst.RegisterLibrary(const AProc: TRegisterLibraryProc);
|
class procedure TAst.RegisterLibrary(const AProc: TRegisterLibraryProc);
|
||||||
begin
|
begin
|
||||||
FLibraries.Add(AProc);
|
FLibraries.Add(AProc);
|
||||||
@@ -741,6 +717,18 @@ begin
|
|||||||
Result :=
|
Result :=
|
||||||
TIdentifierNode.Create(
|
TIdentifierNode.Create(
|
||||||
AName,
|
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
|
if AStaticType <> nil then AStaticType
|
||||||
else TTypes.Unknown
|
else TTypes.Unknown
|
||||||
);
|
);
|
||||||
@@ -971,11 +959,6 @@ begin
|
|||||||
raise ETypeException.Create('Node is not a BlockExpression');
|
raise ETypeException.Create('Node is not a BlockExpression');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TAstNode.AsBoundIdentifierNode: IBoundIdentifierNode;
|
|
||||||
begin
|
|
||||||
raise ETypeException.Create('Node is not a bound identifier');
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TAstNode.AsConstant: IConstantNode;
|
function TAstNode.AsConstant: IConstantNode;
|
||||||
begin
|
begin
|
||||||
raise ETypeException.Create('Node is not a Constant');
|
raise ETypeException.Create('Node is not a Constant');
|
||||||
@@ -1146,10 +1129,11 @@ end;
|
|||||||
|
|
||||||
{ TIdentifierNode }
|
{ TIdentifierNode }
|
||||||
|
|
||||||
constructor TIdentifierNode.Create(const AName: string; const AStaticType: IStaticType);
|
constructor TIdentifierNode.Create(const AName: string; const AAddress: TResolvedAddress; const AStaticType: IStaticType);
|
||||||
begin
|
begin
|
||||||
inherited Create(AStaticType);
|
inherited Create(AStaticType);
|
||||||
FName := AName;
|
FName := AName;
|
||||||
|
FAddress := AAddress;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TIdentifierNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
function TIdentifierNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
||||||
@@ -1162,6 +1146,11 @@ begin
|
|||||||
Result := Self;
|
Result := Self;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TIdentifierNode.GetAddress: TResolvedAddress;
|
||||||
|
begin
|
||||||
|
Result := FAddress;
|
||||||
|
end;
|
||||||
|
|
||||||
function TIdentifierNode.GetName: string;
|
function TIdentifierNode.GetName: string;
|
||||||
begin
|
begin
|
||||||
Result := FName;
|
Result := FName;
|
||||||
@@ -1926,27 +1915,4 @@ begin
|
|||||||
Result := akSeriesLength;
|
Result := akSeriesLength;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TBoundIdentifierNode }
|
|
||||||
|
|
||||||
constructor TBoundIdentifierNode.Create(const AName: string; const AAddress: TResolvedAddress; const AStaticType: IStaticType);
|
|
||||||
begin
|
|
||||||
inherited Create(AName, AStaticType);
|
|
||||||
FAddress := AAddress;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TBoundIdentifierNode.AsBoundIdentifierNode: IBoundIdentifierNode;
|
|
||||||
begin
|
|
||||||
Result := Self;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TBoundIdentifierNode.GetAddress: TResolvedAddress;
|
|
||||||
begin
|
|
||||||
Result := FAddress;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TBoundIdentifierNode.GetKind: TAstNodeKind;
|
|
||||||
begin
|
|
||||||
Result := akBoundIdentifier;
|
|
||||||
end;
|
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|||||||
Reference in New Issue
Block a user