AST refactoring

This commit is contained in:
Michael Schimmel
2025-08-29 10:01:03 +02:00
parent fa9328a183
commit d2c00c6033
4 changed files with 79 additions and 45 deletions
+58 -22
View File
@@ -20,7 +20,8 @@ type
function ToString: string;
end;
TAstValueKind = (avkUndefined, avkScalar, avkClosure);
// Added avkText to represent a string value.
TAstValueKind = (avkUndefined, avkScalar, avkClosure, avkText);
// --- Forward Declarations to break cycles ---
IExecutionScope = interface;
@@ -56,23 +57,21 @@ type
private
FKind: TAstValueKind;
FScalar: TScalar;
FClosure: IEvaluatorClosure;
FInterface: IInterface;
function GetKind: TAstValueKind; inline;
function GetIsScalar: Boolean; inline;
function GetIsClosure: Boolean; inline;
function GetIsUndefined: Boolean; inline;
function GetIsVoid: Boolean; inline;
public
class operator Initialize(out Dest: TAstValue);
class function Undefined: TAstValue; static;
class function Void: TAstValue; static;
class function FromScalar(const AValue: TScalar): TAstValue; static;
class function FromClosure(const AValue: IEvaluatorClosure): TAstValue; static;
class function FromText(const AValue: String): TAstValue; static;
function AsScalar: TScalar;
function AsClosure: IEvaluatorClosure;
function AsText: String;
function ToString: String;
property IsVoid: Boolean read GetIsVoid;
property Kind: TAstValueKind read GetKind;
property IsScalar: Boolean read GetIsScalar;
property IsClosure: Boolean read GetIsClosure;
property IsUndefined: Boolean read GetIsUndefined;
end;
IExecutionScope = interface(IInterface)
@@ -198,19 +197,51 @@ type
implementation
uses
System.Classes;
type
// Private interface to encapsulate a string value for reference counting.
IAstTextValue = interface(IInterface)
function GetValue: string;
property Value: string read GetValue;
end;
// Implementation of the text value interface.
TAstTextValue = class(TInterfacedObject, IAstTextValue)
private
FValue: string;
function GetValue: string;
public
constructor Create(const AValue: string);
end;
{ TAstTextValue }
constructor TAstTextValue.Create(const AValue: string);
begin
inherited Create;
FValue := AValue;
end;
function TAstTextValue.GetValue: string;
begin
Result := FValue;
end;
{ TAstValue }
class operator TAstValue.Initialize(out Dest: TAstValue);
begin
Dest.FKind := avkUndefined;
Dest.FClosure := nil;
Dest.FInterface := nil;
end;
function TAstValue.AsClosure: IEvaluatorClosure;
begin
if (FKind <> avkClosure) then
raise EInvalidCast.Create('Cannot read value as a Closure.');
Result := FClosure;
Result := IEvaluatorClosure(FInterface);
end;
function TAstValue.AsScalar: TScalar;
@@ -220,10 +251,17 @@ begin
Result := FScalar;
end;
function TAstValue.AsText: String;
begin
if (FKind <> avkText) then
raise EInvalidCast.Create('Cannot read value as Text.');
Result := IAstTextValue(FInterface).Value;
end;
class function TAstValue.FromClosure(const AValue: IEvaluatorClosure): TAstValue;
begin
Result.FKind := avkClosure;
Result.FClosure := AValue;
Result.FInterface := AValue;
Result.FScalar := Default(TScalar);
end;
@@ -231,20 +269,17 @@ class function TAstValue.FromScalar(const AValue: TScalar): TAstValue;
begin
Result.FKind := avkScalar;
Result.FScalar := AValue;
Result.FClosure := nil;
Result.FInterface := nil;
end;
function TAstValue.GetIsClosure: Boolean;
class function TAstValue.FromText(const AValue: String): TAstValue;
begin
Result := FKind = avkClosure;
Result.FKind := avkText;
Result.FInterface := TAstTextValue.Create(AValue);
Result.FScalar := Default(TScalar);
end;
function TAstValue.GetIsScalar: Boolean;
begin
Result := FKind = avkScalar;
end;
function TAstValue.GetIsUndefined: Boolean;
function TAstValue.GetIsVoid: Boolean;
begin
Result := FKind = avkUndefined;
end;
@@ -259,13 +294,14 @@ begin
case FKind of
avkScalar: Result := FScalar.ToString;
avkClosure: Result := '<closure>';
avkText: Result := AsText;
avkUndefined: Result := '<void>';
else
Result := '[Unknown AstValue]';
end;
end;
class function TAstValue.Undefined: TAstValue;
class function TAstValue.Void: TAstValue;
begin
Result := Default(TAstValue);
end;