Refactoring node to be immutable

This commit is contained in:
Michael Schimmel
2025-11-05 15:24:54 +01:00
parent 25984fe61a
commit b98e7d98e6
6 changed files with 50 additions and 94 deletions
+29 -63
View File
@@ -36,7 +36,12 @@ type
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; 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(
ALeft: IAstNode;
AOperator: TScalar.TBinaryOp;
@@ -112,11 +117,6 @@ type
): IAddSeriesItemNode; 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;
// Common base class for AST nodes to reduce boilerplate.
@@ -155,7 +155,6 @@ type
function AsRecur: IRecurNode; virtual;
function AsNop: INopNode; virtual; // Added Nop
function AsBoundIdentifierNode: IBoundIdentifierNode; virtual;
function AsTypedNode: IAstTypedNode; virtual;
property IsTyped: Boolean read GetIsTyped;
@@ -271,25 +270,17 @@ type
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 AStaticType: IStaticType);
constructor Create(const AName: string; const AAddress: TResolvedAddress; const AStaticType: IStaticType);
function Accept(const Visitor: IAstVisitor): TDataValue; 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 Name: string read FName;
end;
TKeywordNode = class(TAstTypedNode, IKeywordNode)
@@ -701,21 +692,6 @@ begin
FLibraries.Free;
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);
begin
FLibraries.Add(AProc);
@@ -741,6 +717,18 @@ 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
);
@@ -971,11 +959,6 @@ begin
raise ETypeException.Create('Node is not a BlockExpression');
end;
function TAstNode.AsBoundIdentifierNode: IBoundIdentifierNode;
begin
raise ETypeException.Create('Node is not a bound identifier');
end;
function TAstNode.AsConstant: IConstantNode;
begin
raise ETypeException.Create('Node is not a Constant');
@@ -1146,10 +1129,11 @@ end;
{ TIdentifierNode }
constructor TIdentifierNode.Create(const AName: string; const AStaticType: IStaticType);
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;
@@ -1162,6 +1146,11 @@ begin
Result := Self;
end;
function TIdentifierNode.GetAddress: TResolvedAddress;
begin
Result := FAddress;
end;
function TIdentifierNode.GetName: string;
begin
Result := FName;
@@ -1926,27 +1915,4 @@ begin
Result := akSeriesLength;
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.