AST refactoring
This commit is contained in:
+58
-22
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user