Scope cells refactoring

This commit is contained in:
Michael Schimmel
2025-09-05 12:46:24 +02:00
parent edf8329b28
commit 100646c7d8
5 changed files with 61 additions and 117 deletions
+26 -88
View File
@@ -17,8 +17,6 @@ type
FCapturedUpvalues: TArray<IValueCell>;
FNameToIndex: TDictionary<string, Integer>;
procedure DumpScope(const ABuilder: TStringBuilder; AIndent: Integer);
function GetValues(const Address: TResolvedAddress): TAstValue;
procedure SetValues(const Address: TResolvedAddress; const Value: TAstValue);
function GetParent: IExecutionScope;
function GetCell(const Address: TResolvedAddress): IValueCell;
public
@@ -63,8 +61,6 @@ end;
{ TExecutionScope }
{ TExecutionScope }
constructor TExecutionScope.Create(
AParent: IExecutionScope;
const ADescriptor: IScopeDescriptor;
@@ -99,23 +95,34 @@ begin
end;
function TExecutionScope.GetCell(const Address: TResolvedAddress): IValueCell;
var
targetScope: TExecutionScope;
i: Integer;
begin
// Cells can only be retrieved from local/parent scopes.
if Address.Kind <> akLocalOrParent then
raise EInvalidOpException.Create('Cannot get a cell for a non-local address.');
targetScope := Self;
for i := 1 to Address.ScopeDepth do
begin
targetScope := targetScope.Parent as TExecutionScope;
Assert(Assigned(targetScope), 'Invalid scope depth during cell retrieval.');
case Address.Kind of
akUpvalue:
begin
Assert(Assigned(FCapturedUpvalues), 'Attempt to access an upvalue in a scope with no closure context.');
Assert(
(Address.SlotIndex >= 0) and (Address.SlotIndex < Length(FCapturedUpvalues)),
'Invalid upvalue index during value retrieval.'
);
Result := FCapturedUpvalues[Address.SlotIndex];
end;
akLocalOrParent:
begin
var targetScope := Self;
for var i := 1 to Address.ScopeDepth do
begin
targetScope := targetScope.Parent as TExecutionScope;
Assert(Assigned(targetScope), 'Invalid scope depth during value retrieval.');
end;
Assert(
(Address.SlotIndex >= 0) and (Address.SlotIndex < Length(targetScope.Values)),
'Invalid scope index during value retrieval.'
);
Result := targetScope.Values[Address.SlotIndex];
end;
else
raise EInvalidOpException.Create('Cannot get value for an unresolved address.');
end;
Assert((Address.SlotIndex >= 0) and (Address.SlotIndex < Length(targetScope.FValues)), 'Invalid scope index during cell retrieval.');
Result := targetScope.FValues[Address.SlotIndex];
end;
function TExecutionScope.GetParent: IExecutionScope;
@@ -189,73 +196,4 @@ begin
end;
end;
function TExecutionScope.GetValues(const Address: TResolvedAddress): TAstValue;
var
targetScope: TExecutionScope;
i: Integer;
begin
case Address.Kind of
akUpvalue:
begin
Assert(Assigned(FCapturedUpvalues), 'Attempt to access an upvalue in a scope with no closure context.');
Assert(
(Address.SlotIndex >= 0) and (Address.SlotIndex < Length(FCapturedUpvalues)),
'Invalid upvalue index during value retrieval.'
);
Result := FCapturedUpvalues[Address.SlotIndex].Value;
end;
akLocalOrParent:
begin
targetScope := Self;
for i := 1 to Address.ScopeDepth do
begin
targetScope := targetScope.Parent as TExecutionScope;
Assert(Assigned(targetScope), 'Invalid scope depth during value retrieval.');
end;
Assert(
(Address.SlotIndex >= 0) and (Address.SlotIndex < Length(targetScope.Values)),
'Invalid scope index during value retrieval.'
);
Result := targetScope.Values[Address.SlotIndex].Value;
end;
else
raise EInvalidOpException.Create('Cannot get value for an unresolved address.');
end;
end;
procedure TExecutionScope.SetValues(const Address: TResolvedAddress; const Value: TAstValue);
var
targetScope: IExecutionScope;
i: Integer;
begin
case Address.Kind of
akUpvalue:
begin
Assert(Assigned(FCapturedUpvalues), 'Attempt to access an upvalue in a scope with no closure context.');
Assert(
(Address.SlotIndex >= 0) and (Address.SlotIndex < Length(FCapturedUpvalues)),
'Invalid upvalue index during value assignment.'
);
FCapturedUpvalues[Address.SlotIndex].Value := Value;
end;
akLocalOrParent:
begin
targetScope := Self;
for i := 0 to Address.ScopeDepth - 1 do
begin
if Assigned(targetScope) then
targetScope := targetScope.Parent
else
raise EInvalidOpException.Create('Invalid scope depth during assignment.');
end;
if Address.SlotIndex >= Length((targetScope as TExecutionScope).Values) then
raise EInvalidOpException.Create('Invalid scope index during assignment.');
(targetScope as TExecutionScope).Values[Address.SlotIndex].Value := Value;
end;
else
raise EInvalidOpException.Create('Cannot set value for an unresolved address.');
end;
end;
end.