From b14bda310f765b22763dbd3a83eccea9132f1e50 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Fri, 22 Aug 2025 18:55:32 -0700 Subject: [PATCH] improve printer's handling of cyclic lists (#2111, #2635) --- src/heap_iter.rs | 9 ++++++--- src/heap_print.rs | 45 ++++++++++++--------------------------------- 2 files changed, 18 insertions(+), 36 deletions(-) diff --git a/src/heap_iter.rs b/src/heap_iter.rs index 583d297d..7726b49b 100644 --- a/src/heap_iter.rs +++ b/src/heap_iter.rs @@ -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); } diff --git a/src/heap_print.rs b/src/heap_print.rs index 53dbbe63..d1d7bdb4 100644 --- a/src/heap_print.rs +++ b/src/heap_print.rs @@ -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; - - // 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() - { + let h = match cell.get_tag() { + HeapCellValueTag::Lis | HeapCellValueTag::PStrLoc => { + self.iter.focus().value() as usize + } + _ => cell.get_value() as usize, + }; + + 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( -- 2.54.0