Keywords
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -20,7 +20,8 @@ uses
|
|||||||
Myc.Fmx.AstEditor.Text in 'Myc.Fmx.AstEditor.Text.pas',
|
Myc.Fmx.AstEditor.Text in 'Myc.Fmx.AstEditor.Text.pas',
|
||||||
Myc.Utils in '..\Src\Myc.Utils.pas',
|
Myc.Utils in '..\Src\Myc.Utils.pas',
|
||||||
Myc.Ast.Script in '..\Src\AST\Myc.Ast.Script.pas',
|
Myc.Ast.Script in '..\Src\AST\Myc.Ast.Script.pas',
|
||||||
Myc.Ast.Types in '..\Src\AST\Myc.Ast.Types.pas';
|
Myc.Ast.Types in '..\Src\AST\Myc.Ast.Types.pas',
|
||||||
|
Myc.Data.Keyword in '..\Src\Data\Myc.Data.Keyword.pas';
|
||||||
|
|
||||||
{$R *.res}
|
{$R *.res}
|
||||||
|
|
||||||
|
|||||||
@@ -151,6 +151,7 @@
|
|||||||
<DCCReference Include="..\Src\Myc.Utils.pas"/>
|
<DCCReference Include="..\Src\Myc.Utils.pas"/>
|
||||||
<DCCReference Include="..\Src\AST\Myc.Ast.Script.pas"/>
|
<DCCReference Include="..\Src\AST\Myc.Ast.Script.pas"/>
|
||||||
<DCCReference Include="..\Src\AST\Myc.Ast.Types.pas"/>
|
<DCCReference Include="..\Src\AST\Myc.Ast.Types.pas"/>
|
||||||
|
<DCCReference Include="..\Src\Data\Myc.Data.Keyword.pas"/>
|
||||||
<BuildConfiguration Include="Base">
|
<BuildConfiguration Include="Base">
|
||||||
<Key>Base</Key>
|
<Key>Base</Key>
|
||||||
</BuildConfiguration>
|
</BuildConfiguration>
|
||||||
|
|||||||
@@ -297,7 +297,7 @@ begin
|
|||||||
|
|
||||||
key := argScalar.Value.AsInt64;
|
key := argScalar.Value.AsInt64;
|
||||||
|
|
||||||
var cache := cCache.AsObject as TDictionary<Int64, TDataValue>;
|
var cache := TDictionary<Int64, TDataValue>(cCache.AsObject);
|
||||||
|
|
||||||
if cache.TryGetValue(key, Result) then
|
if cache.TryGetValue(key, Result) then
|
||||||
exit;
|
exit;
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
unit Myc.Data.Keyword;
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
System.SysUtils,
|
||||||
|
System.Classes,
|
||||||
|
System.Generics.Collections,
|
||||||
|
System.SyncObjs;
|
||||||
|
|
||||||
|
type
|
||||||
|
// The runtime representation of an interned keyword
|
||||||
|
IKeyword = interface(IInterface)
|
||||||
|
function GetName: string;
|
||||||
|
property Name: string read GetName;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Factory and registry for all keywords (Flyweight Pattern)
|
||||||
|
TKeywordRegistry = record
|
||||||
|
strict private
|
||||||
|
type
|
||||||
|
TKeyword = class(TInterfacedObject, IKeyword)
|
||||||
|
private
|
||||||
|
FName: string;
|
||||||
|
function GetName: string;
|
||||||
|
public
|
||||||
|
constructor Create(const AName: string);
|
||||||
|
end;
|
||||||
|
strict private
|
||||||
|
class var
|
||||||
|
FLock: TSpinLock;
|
||||||
|
class var
|
||||||
|
FRegistry: TDictionary<string, IKeyword>;
|
||||||
|
class constructor Create;
|
||||||
|
class destructor Destroy;
|
||||||
|
public
|
||||||
|
// Gets or creates the interned keyword for the given name.
|
||||||
|
class function Intern(const AName: string): IKeyword; static;
|
||||||
|
end;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
{ TKeywordRegistry.TKeyword }
|
||||||
|
|
||||||
|
constructor TKeywordRegistry.TKeyword.Create(const AName: string);
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
FName := AName;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TKeywordRegistry.TKeyword.GetName: string;
|
||||||
|
begin
|
||||||
|
Result := FName;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TKeywordRegistry }
|
||||||
|
|
||||||
|
class constructor TKeywordRegistry.Create;
|
||||||
|
begin
|
||||||
|
FLock := TSpinLock.Create(false);
|
||||||
|
FRegistry := TDictionary<string, IKeyword>.Create;
|
||||||
|
end;
|
||||||
|
|
||||||
|
class destructor TKeywordRegistry.Destroy;
|
||||||
|
begin
|
||||||
|
FRegistry.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
class function TKeywordRegistry.Intern(const AName: string): IKeyword;
|
||||||
|
begin
|
||||||
|
FLock.Enter;
|
||||||
|
try
|
||||||
|
if not FRegistry.TryGetValue(AName, Result) then
|
||||||
|
begin
|
||||||
|
Result := TKeyword.Create(AName);
|
||||||
|
FRegistry.Add(AName, Result);
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
FLock.Exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
@@ -7,11 +7,24 @@ uses
|
|||||||
System.SyncObjs,
|
System.SyncObjs,
|
||||||
Myc.Utils,
|
Myc.Utils,
|
||||||
Myc.Data.Scalar,
|
Myc.Data.Scalar,
|
||||||
Myc.Data.Series;
|
Myc.Data.Series,
|
||||||
|
Myc.Data.Keyword;
|
||||||
|
|
||||||
type
|
type
|
||||||
TDataValueKind =
|
TDataValueKind = (
|
||||||
(vkVoid, vkScalar, vkText, vkSeries, vkRecordSeries, vkRecord, vkManagedObject, vkMethod, vkInterface, vkPointer, vkGeneric);
|
vkVoid,
|
||||||
|
vkScalar,
|
||||||
|
vkText,
|
||||||
|
vkKeyword,
|
||||||
|
vkSeries,
|
||||||
|
vkRecordSeries,
|
||||||
|
vkRecord,
|
||||||
|
vkManagedObject,
|
||||||
|
vkMethod,
|
||||||
|
vkInterface,
|
||||||
|
vkPointer,
|
||||||
|
vkGeneric
|
||||||
|
);
|
||||||
|
|
||||||
TDataValue = record
|
TDataValue = record
|
||||||
type
|
type
|
||||||
@@ -47,6 +60,7 @@ type
|
|||||||
class operator Implicit(const AValue: TScalar): TDataValue; overload; inline;
|
class operator Implicit(const AValue: TScalar): TDataValue; overload; inline;
|
||||||
class operator Implicit(const AValue: TDataValue): TScalar; overload; inline;
|
class operator Implicit(const AValue: TDataValue): TScalar; overload; inline;
|
||||||
class operator Implicit(const AValue: String): TDataValue; overload; inline;
|
class operator Implicit(const AValue: String): TDataValue; overload; inline;
|
||||||
|
class operator Implicit(const AValue: IKeyword): TDataValue; overload; inline;
|
||||||
class operator Implicit(const AValue: TDataValue.TFunc): TDataValue; overload; inline;
|
class operator Implicit(const AValue: TDataValue.TFunc): TDataValue; overload; inline;
|
||||||
class operator Implicit(const AValue: TObject): TDataValue; overload; inline;
|
class operator Implicit(const AValue: TObject): TDataValue; overload; inline;
|
||||||
|
|
||||||
@@ -68,10 +82,12 @@ type
|
|||||||
class function FromRecordSeries(const AValue: IRecordSeries): TDataValue; static; inline;
|
class function FromRecordSeries(const AValue: IRecordSeries): TDataValue; static; inline;
|
||||||
class function FromRecord(const [ref] AValue: TScalarRecord): TDataValue; static; inline;
|
class function FromRecord(const [ref] AValue: TScalarRecord): TDataValue; static; inline;
|
||||||
class function FromSeries(const AValue: ISeries): TDataValue; static; inline;
|
class function FromSeries(const AValue: ISeries): TDataValue; static; inline;
|
||||||
|
class function FromKeyword(const AValue: IKeyword): TDataValue; static; inline; // Added
|
||||||
|
|
||||||
function AsScalar: TScalar; inline;
|
function AsScalar: TScalar; inline;
|
||||||
function AsMethod: TFunc; inline;
|
function AsMethod: TFunc; inline;
|
||||||
function AsText: String; inline;
|
function AsText: String; inline;
|
||||||
|
function AsKeyword: IKeyword; inline; // Added
|
||||||
function AsRecordSeries: IRecordSeries; inline;
|
function AsRecordSeries: IRecordSeries; inline;
|
||||||
function AsRecord: TScalarRecord; inline;
|
function AsRecord: TScalarRecord; inline;
|
||||||
function AsSeries: ISeries; inline;
|
function AsSeries: ISeries; inline;
|
||||||
@@ -171,6 +187,13 @@ begin
|
|||||||
Result := Pointer(FScalar.Value.AsInt64);
|
Result := Pointer(FScalar.Value.AsInt64);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TDataValue.AsKeyword: IKeyword;
|
||||||
|
begin
|
||||||
|
if (FKind <> vkKeyword) then
|
||||||
|
raise EInvalidCast.Create('Cannot read value as Keyword.');
|
||||||
|
Result := IKeyword(FInterface);
|
||||||
|
end;
|
||||||
|
|
||||||
function TDataValue.AsRecord: TScalarRecord;
|
function TDataValue.AsRecord: TScalarRecord;
|
||||||
begin
|
begin
|
||||||
if (FKind <> vkRecord) then
|
if (FKind <> vkRecord) then
|
||||||
@@ -241,7 +264,7 @@ begin
|
|||||||
TInterlocked.CompareExchange(FScalar.Value.AsInt64, NewValue.AsScalar.Value.AsInt64, Expected.AsScalar.Value.AsInt64)
|
TInterlocked.CompareExchange(FScalar.Value.AsInt64, NewValue.AsScalar.Value.AsInt64, Expected.AsScalar.Value.AsInt64)
|
||||||
= Expected.AsScalar.Value.AsInt64;
|
= Expected.AsScalar.Value.AsInt64;
|
||||||
|
|
||||||
vkText, vkSeries, vkRecordSeries, vkRecord, vkManagedObject, vkMethod, vkInterface, vkGeneric:
|
vkText, vkKeyword, vkSeries, vkRecordSeries, vkRecord, vkManagedObject, vkMethod, vkInterface, vkGeneric: // Added vkKeyword
|
||||||
Result := IntfCompareExchange(FInterface, NewValue.FInterface, Expected.FInterface) = Expected.FInterface;
|
Result := IntfCompareExchange(FInterface, NewValue.FInterface, Expected.FInterface) = Expected.FInterface;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@@ -258,6 +281,12 @@ begin
|
|||||||
Result.FInterface := TVal<T>.Create(AValue);
|
Result.FInterface := TVal<T>.Create(AValue);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
class function TDataValue.FromKeyword(const AValue: IKeyword): TDataValue;
|
||||||
|
begin
|
||||||
|
Result.FKind := vkKeyword;
|
||||||
|
Result.FInterface := AValue;
|
||||||
|
end;
|
||||||
|
|
||||||
class function TDataValue.FromPtr(const AValue: Pointer): TDataValue;
|
class function TDataValue.FromPtr(const AValue: Pointer): TDataValue;
|
||||||
begin
|
begin
|
||||||
Assert(sizeof(Pointer) <= sizeof(Int64));
|
Assert(sizeof(Pointer) <= sizeof(Int64));
|
||||||
@@ -296,6 +325,12 @@ begin
|
|||||||
Result.FInterface := TVal<String>.Create(AValue);
|
Result.FInterface := TVal<String>.Create(AValue);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
class operator TDataValue.Implicit(const AValue: IKeyword): TDataValue;
|
||||||
|
begin
|
||||||
|
Result.FKind := vkKeyword;
|
||||||
|
Result.FInterface := AValue;
|
||||||
|
end;
|
||||||
|
|
||||||
function TDataValue.GetIsVoid: Boolean;
|
function TDataValue.GetIsVoid: Boolean;
|
||||||
begin
|
begin
|
||||||
Result := FKind = vkVoid;
|
Result := FKind = vkVoid;
|
||||||
@@ -334,7 +369,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
vkPointer: Result := TInterlocked.Exchange(FScalar.Value.AsInt64, NewValue.AsScalar.Value.AsInt64);
|
vkPointer: Result := TInterlocked.Exchange(FScalar.Value.AsInt64, NewValue.AsScalar.Value.AsInt64);
|
||||||
|
|
||||||
vkText, vkSeries, vkRecordSeries, vkRecord, vkManagedObject, vkMethod, vkInterface, vkGeneric:
|
vkText, vkKeyword, vkSeries, vkRecordSeries, vkRecord, vkManagedObject, vkMethod, vkInterface, vkGeneric: // Added vkKeyword
|
||||||
begin
|
begin
|
||||||
Result.FKind := FKind;
|
Result.FKind := FKind;
|
||||||
Result.FInterface := IntfExchange(FInterface, NewValue.FInterface);
|
Result.FInterface := IntfExchange(FInterface, NewValue.FInterface);
|
||||||
@@ -351,6 +386,7 @@ begin
|
|||||||
case FKind of
|
case FKind of
|
||||||
vkScalar: Result := FScalar.ToString;
|
vkScalar: Result := FScalar.ToString;
|
||||||
vkText: Result := '"' + AsText + '"';
|
vkText: Result := '"' + AsText + '"';
|
||||||
|
vkKeyword: Result := ':' + AsKeyword.Name; // Added
|
||||||
vkSeries:
|
vkSeries:
|
||||||
begin
|
begin
|
||||||
var series := AsSeries;
|
var series := AsSeries;
|
||||||
@@ -454,6 +490,7 @@ begin
|
|||||||
vkVoid: Result := 'Void';
|
vkVoid: Result := 'Void';
|
||||||
vkScalar: Result := 'Scalar';
|
vkScalar: Result := 'Scalar';
|
||||||
vkText: Result := 'Text';
|
vkText: Result := 'Text';
|
||||||
|
vkKeyword: Result := 'Keyword'; // Added
|
||||||
vkSeries: Result := 'Series';
|
vkSeries: Result := 'Series';
|
||||||
vkRecordSeries: Result := 'RecordSeries';
|
vkRecordSeries: Result := 'RecordSeries';
|
||||||
vkRecord: Result := 'Record';
|
vkRecord: Result := 'Record';
|
||||||
|
|||||||
Reference in New Issue
Block a user