improve printer's handling of cyclic lists (#2111, #2635)

This commit is contained in:
Mark Thom
2025-08-22 18:55:32 -07:00
parent 02b8a6010c
commit b14bda310f
2 changed files with 17 additions and 35 deletions

View File

@@ -420,6 +420,12 @@ impl<'a, ElideLists: ListElisionPolicy> StackfulPreOrderHeapIter<'a, ElideLists>
let loc = IterStackLoc::iterable_loc(vh, HeapOrStackTag::Heap);
self.forward_if_referent_marked(loc);
if self.read_cell(h).get_forwarding_bit() {
self.stack.push(h);
continue;
}
self.push_if_unmarked(loc);
self.stack.push(IterStackLoc::pending_mark_loc(vh + 1, HeapOrStackTag::Heap));
@@ -2138,9 +2144,6 @@ mod tests {
list_loc_as_cell!(1)
);
assert_eq!(iter.next().unwrap(), cyclic_link);
assert_eq!(iter.next().unwrap(), cyclic_link);
assert_eq!(iter.next().unwrap(), cyclic_link);
assert_eq!(iter.next(), None);
}

View File

@@ -873,18 +873,6 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
var_opt => {
if is_cyclic && cell.is_compound(self.iter.heap) {
// self-referential variables are marked "cyclic".
read_heap_cell!(cell,
(HeapCellValueTag::Lis, vh) => {
if self.iter.heap[vh].get_forwarding_bit() {
self.iter.pop_stack();
}
if self.iter.heap[vh+1].get_forwarding_bit() {
self.iter.pop_stack();
}
}
_ => {}
);
match var_opt {
Some(var) => {
@@ -903,32 +891,23 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
} else {
debug_assert!(cell.is_ref());
let h = if cell.get_tag() == HeapCellValueTag::PStrLoc {
self.state_stack
.push(TokenOrRedirect::Atom(atom!("...")));
return None;
} else {
cell.get_value()
} as usize;
let h = match cell.get_tag() {
HeapCellValueTag::Lis | HeapCellValueTag::PStrLoc => {
self.iter.focus().value() as usize
}
_ => cell.get_value() as usize,
};
// as usual, the WAM's
// optimization of the Lis tag
// (conflating the location of
// the list and that of its
// first element) needs
// special consideration here
// lest we find ourselves in
// an infinite loop.
if cell.get_tag() == HeapCellValueTag::Lis {
if self.iter.heap[cell.get_value() as usize]
.get_forwarding_bit()
{
match cell.get_tag() {
HeapCellValueTag::Lis => {
self.state_stack
.push(TokenOrRedirect::Atom(atom!("...")));
return None;
} else {
}
HeapCellValueTag::PStrLoc => {
*max_depth -= 1;
}
_ => {}
}
self.iter.push_stack(IterStackLoc::iterable_loc(