Scope Index optimized

This commit is contained in:
Michael Schimmel
2025-09-15 10:39:39 +02:00
parent d731048b41
commit c913f9dbc5
4 changed files with 35 additions and 69 deletions
+32 -9
View File
@@ -13,13 +13,16 @@ type
TExecutionScope = class(TInterfacedObject, IExecutionScope)
private
FParent: IExecutionScope;
FDescriptor: IScopeDescriptor;
FValues: TArray<IValueCell>;
// Stores references to the value cells captured by a closure.
FCapturedUpvalues: TArray<IValueCell>;
FNameToIndex: TDictionary<string, Integer>;
procedure DumpScope(const ABuilder: TStringBuilder; AIndent: Integer);
procedure NeedNameToIndex;
function GetParent: IExecutionScope;
function GetCell(const Address: TResolvedAddress): IValueCell;
function GetNameToIndex: TDictionary<string, Integer>;
public
constructor Create(
AParent: IExecutionScope = nil;
@@ -30,7 +33,7 @@ type
procedure Clear;
function Dump: string;
procedure Define(const Name: string; const Value: TDataValue);
property NameToIndex: TDictionary<string, Integer> read FNameToIndex;
property NameToIndex: TDictionary<string, Integer> read GetNameToIndex;
property Parent: IExecutionScope read FParent;
property Values: TArray<IValueCell> read FValues;
end;
@@ -73,15 +76,12 @@ var
begin
inherited Create;
FParent := AParent;
FDescriptor := ADescriptor;
FValues := [];
FNameToIndex := TDictionary<string, Integer>.Create;
FCapturedUpvalues := ACapturedUpvalues; // Store upvalues
if ADescriptor <> nil then
begin
for var item in ADescriptor.Symbols do
FNameToIndex.AddOrSetValue(item.Key, item.Value);
slotCount := ADescriptor.SlotCount;
SetLength(FValues, slotCount);
for i := 0 to slotCount - 1 do
@@ -91,7 +91,7 @@ end;
destructor TExecutionScope.Destroy;
begin
FNameToIndex.Free;
Clear;
inherited Destroy;
end;
@@ -134,13 +134,15 @@ end;
procedure TExecutionScope.Clear;
begin
FValues := [];
FNameToIndex.Clear;
FreeAndNil(FNameToIndex);
end;
procedure TExecutionScope.Define(const Name: string; const Value: TDataValue); // <-- Changed from TAstValue
procedure TExecutionScope.Define(const Name: string; const Value: TDataValue);
var
index: Integer;
begin
NeedNameToIndex;
if FNameToIndex.ContainsKey(Name) then
raise Exception.CreateFmt('Variable "%s" is already defined in this scope.', [Name]);
@@ -157,8 +159,10 @@ var
indentStr: string;
sortedPairs: TArray<TPair<string, Integer>>;
begin
NeedNameToIndex;
indentStr := ''.PadLeft(AIndent);
if (FNameToIndex.Count > 0) then
if FNameToIndex.Count > 0 then
begin
sortedPairs := FNameToIndex.ToArray;
TArray.Sort<TPair<string, Integer>>(
@@ -197,4 +201,23 @@ begin
end;
end;
function TExecutionScope.GetNameToIndex: TDictionary<string, Integer>;
begin
NeedNameToIndex;
Result := FNameToIndex;
end;
procedure TExecutionScope.NeedNameToIndex;
begin
if FNameToIndex = nil then
begin
FNameToIndex := TDictionary<string, Integer>.Create;
if FDescriptor <> nil then
begin
for var item in FDescriptor.Symbols do
FNameToIndex.AddOrSetValue(item.Key, item.Value);
end;
end;
end;
end.