Keywords as basic scalar type
Script enhancements
This commit is contained in:
@@ -34,7 +34,7 @@ type
|
||||
class var
|
||||
FLock: TSpinLock;
|
||||
class var
|
||||
FRegistry: TDictionary<string, IKeyword>;
|
||||
FRegistry: TDictionary<string, Integer>;
|
||||
class var
|
||||
FReverseMap: TList<IKeyword>; // Use TList
|
||||
class constructor Create;
|
||||
@@ -116,7 +116,7 @@ end;
|
||||
class constructor TKeywordRegistry.Create;
|
||||
begin
|
||||
FLock := TSpinLock.Create(false);
|
||||
FRegistry := TDictionary<string, IKeyword>.Create;
|
||||
FRegistry := TDictionary<string, Integer>.Create;
|
||||
FReverseMap := TList<IKeyword>.Create;
|
||||
|
||||
Intern('false');
|
||||
@@ -135,24 +135,25 @@ begin
|
||||
try
|
||||
// Check bounds
|
||||
if (AIdx >= 0) and (AIdx < FReverseMap.Count) then
|
||||
Result := FReverseMap[AIdx].Name
|
||||
else
|
||||
Result := ''; // Return empty for safety
|
||||
Result := FReverseMap[AIdx].Name;
|
||||
finally
|
||||
FLock.Exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
class function TKeywordRegistry.Intern(const AName: string): IKeyword;
|
||||
var
|
||||
idx: Integer;
|
||||
begin
|
||||
FLock.Enter;
|
||||
try
|
||||
if not FRegistry.TryGetValue(AName, Result) then
|
||||
if not FRegistry.TryGetValue(AName, idx) then
|
||||
begin
|
||||
Result := TKeyword.Create(AName, FRegistry.Count);
|
||||
FReverseMap.Add(Result); // Add to reverse map (Idx -> Interface)
|
||||
FRegistry.Add(AName, Result); // Add to forward map (Name -> Interface)
|
||||
end;
|
||||
FRegistry.Add(AName, FReverseMap.Add(Result));
|
||||
end
|
||||
else
|
||||
Result := FReverseMap[idx];
|
||||
finally
|
||||
FLock.Exit;
|
||||
end;
|
||||
|
||||
@@ -319,7 +319,7 @@ begin
|
||||
case Kind of
|
||||
TKind.Ordinal: Result := IntToStr(Value.AsInt64);
|
||||
TKind.Float: Result := FloatToStr(Value.AsDouble);
|
||||
TKind.Keyword: Result := TKeywordRegistry.GetName(Value.AsInt64);
|
||||
TKind.Keyword: Result := ':' + TKeywordRegistry.GetName(Value.AsInt64);
|
||||
else
|
||||
Result := '[Unknown Scalar]';
|
||||
end;
|
||||
|
||||
@@ -5,14 +5,27 @@ interface
|
||||
uses
|
||||
System.SysUtils,
|
||||
System.SyncObjs,
|
||||
System.Generics.Collections, // Added for TDictionary
|
||||
Myc.Utils,
|
||||
Myc.Data.Scalar,
|
||||
Myc.Data.Series,
|
||||
Myc.Data.Keyword;
|
||||
|
||||
type
|
||||
TDataValueKind =
|
||||
(vkVoid, vkScalar, vkText, vkSeries, vkRecordSeries, vkRecord, vkManagedObject, vkMethod, vkInterface, vkPointer, vkGeneric);
|
||||
TDataValueKind = (
|
||||
vkVoid,
|
||||
vkScalar,
|
||||
vkText,
|
||||
vkSeries,
|
||||
vkRecordSeries,
|
||||
vkRecord,
|
||||
vkGenericRecord, // Added
|
||||
vkManagedObject,
|
||||
vkMethod,
|
||||
vkInterface,
|
||||
vkPointer,
|
||||
vkGeneric
|
||||
);
|
||||
|
||||
TDataValue = record
|
||||
type
|
||||
@@ -68,6 +81,7 @@ type
|
||||
|
||||
class function FromRecordSeries(const AValue: IRecordSeries): TDataValue; static; inline;
|
||||
class function FromRecord(const [ref] AValue: TScalarRecord): TDataValue; static; inline;
|
||||
class function FromGenericRecord(const AValue: IKeywordMapping<TDataValue>): TDataValue; static; inline;
|
||||
class function FromSeries(const AValue: ISeries): TDataValue; static; inline;
|
||||
|
||||
function AsScalar: TScalar; inline;
|
||||
@@ -75,6 +89,7 @@ type
|
||||
function AsText: String; inline;
|
||||
function AsRecordSeries: IRecordSeries; inline;
|
||||
function AsRecord: TScalarRecord; inline;
|
||||
function AsGenericRecord: IKeywordMapping<TDataValue>; inline;
|
||||
function AsSeries: ISeries; inline;
|
||||
function AsObject: TObject; overload; inline;
|
||||
|
||||
@@ -179,6 +194,14 @@ begin
|
||||
Result := (FInterface as TVal<TScalarRecord>).Value;
|
||||
end;
|
||||
|
||||
// Added
|
||||
function TDataValue.AsGenericRecord: IKeywordMapping<TDataValue>;
|
||||
begin
|
||||
if (FKind <> vkGenericRecord) then
|
||||
raise EInvalidCast.Create('Cannot read value as GenericRecord.');
|
||||
Result := IKeywordMapping<TDataValue>(FInterface);
|
||||
end;
|
||||
|
||||
function TDataValue.AsRecordSeries: IRecordSeries;
|
||||
begin
|
||||
if (FKind <> vkRecordSeries) then
|
||||
@@ -242,7 +265,8 @@ begin
|
||||
TInterlocked.CompareExchange(FScalar.Value.AsInt64, NewValue.AsScalar.Value.AsInt64, Expected.AsScalar.Value.AsInt64)
|
||||
= Expected.AsScalar.Value.AsInt64;
|
||||
|
||||
vkText, vkSeries, vkRecordSeries, vkRecord, vkManagedObject, vkMethod, vkInterface, vkGeneric:
|
||||
// Added vkGenericRecord
|
||||
vkText, vkSeries, vkRecordSeries, vkRecord, vkGenericRecord, vkManagedObject, vkMethod, vkInterface, vkGeneric:
|
||||
Result := IntfCompareExchange(FInterface, NewValue.FInterface, Expected.FInterface) = Expected.FInterface;
|
||||
end;
|
||||
end;
|
||||
@@ -278,6 +302,13 @@ begin
|
||||
Result.FInterface := TVal<TScalarRecord>.Create(AValue);
|
||||
end;
|
||||
|
||||
// Added
|
||||
class function TDataValue.FromGenericRecord(const AValue: IKeywordMapping<TDataValue>): TDataValue;
|
||||
begin
|
||||
Result.FKind := vkGenericRecord;
|
||||
Result.FInterface := AValue;
|
||||
end;
|
||||
|
||||
class function TDataValue.FromRecordSeries(const AValue: IRecordSeries): TDataValue;
|
||||
begin
|
||||
Result.FKind := vkRecordSeries;
|
||||
@@ -336,7 +367,8 @@ begin
|
||||
end;
|
||||
vkPointer: Result := TInterlocked.Exchange(FScalar.Value.AsInt64, NewValue.AsScalar.Value.AsInt64);
|
||||
|
||||
vkText, vkSeries, vkRecordSeries, vkRecord, vkManagedObject, vkMethod, vkInterface, vkGeneric:
|
||||
// Added vkGenericRecord
|
||||
vkText, vkSeries, vkRecordSeries, vkRecord, vkGenericRecord, vkManagedObject, vkMethod, vkInterface, vkGeneric:
|
||||
begin
|
||||
Result.FKind := FKind;
|
||||
Result.FInterface := IntfExchange(FInterface, NewValue.FInterface);
|
||||
@@ -348,6 +380,7 @@ function TDataValue.ToString: String;
|
||||
var
|
||||
sb: TStringBuilder;
|
||||
field: TScalarRecordField;
|
||||
genField: TPair<IKeyword, TDataValue>; // Added
|
||||
first: Boolean;
|
||||
begin
|
||||
case FKind of
|
||||
@@ -401,6 +434,27 @@ begin
|
||||
sb.Free;
|
||||
end;
|
||||
end;
|
||||
// Added
|
||||
vkGenericRecord:
|
||||
begin
|
||||
var rec := AsGenericRecord;
|
||||
sb := TStringBuilder.Create;
|
||||
try
|
||||
sb.Append('{');
|
||||
first := True;
|
||||
for genField in rec.Fields do
|
||||
begin
|
||||
if not first then
|
||||
sb.Append(',');
|
||||
sb.Append(genField.Key.Name);
|
||||
first := False;
|
||||
end;
|
||||
sb.Append('}');
|
||||
Result := Format('<generic_record%s>', [sb.ToString]);
|
||||
finally
|
||||
sb.Free;
|
||||
end;
|
||||
end;
|
||||
vkVoid: Result := '<void>';
|
||||
vkMethod: Result := '<method>';
|
||||
vkGeneric:
|
||||
@@ -459,7 +513,12 @@ begin
|
||||
vkSeries: Result := 'Series';
|
||||
vkRecordSeries: Result := 'RecordSeries';
|
||||
vkRecord: Result := 'Record';
|
||||
vkGenericRecord: Result := 'GenericRecord'; // Added
|
||||
vkMethod: Result := 'Method';
|
||||
vkInterface: Result := 'Interface';
|
||||
vkPointer: Result := 'Pointer';
|
||||
vkGeneric: Result := 'Generic';
|
||||
vkManagedObject: Result := 'ManagedObject';
|
||||
else
|
||||
Result := 'unknown';
|
||||
end;
|
||||
|
||||
Reference in New Issue
Block a user