Scope cells refactoring
This commit is contained in:
+26
-88
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user