From b065e1cd53752248e326ec358983d0e48d69fca6 Mon Sep 17 00:00:00 2001 From: Mark Date: Sat, 30 Sep 2023 17:15:20 -0600 Subject: [PATCH] correct depth calculation for lists that are their own car (#1876) --- src/heap_print.rs | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/heap_print.rs b/src/heap_print.rs index daf339c8a..1ad88f29e 100644 --- a/src/heap_print.rs +++ b/src/heap_print.rs @@ -861,7 +861,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { ) } - fn check_for_seen(&mut self, max_depth: usize) -> Option { + fn check_for_seen(&mut self, max_depth: &mut usize) -> Option { if let Some(mut orig_cell) = self.iter.next() { loop { let is_cyclic = orig_cell.get_forwarding_bit(); @@ -899,7 +899,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { }); } None => { - if self.max_depth == 0 || max_depth == 0 { + if self.max_depth == 0 || *max_depth == 0 { // otherwise, contract it to an ellipsis. push_space_if_amb!(self, "...", { append_str!(self, "..."); @@ -907,6 +907,18 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { } else { debug_assert!(cell.is_ref()); + // 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 { + *max_depth -= 1; + } + let h = cell.get_value() as usize; self.iter.push_stack(IterStackLoc::iterable_loc(h, HeapOrStackTag::Heap)); @@ -1363,7 +1375,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth)); self.state_stack.push(TokenOrRedirect::HeadTailSeparator); // bar - self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth)); + self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth + 1)); self.open_list(switch); } @@ -1563,10 +1575,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { &mut self, op: Option, is_functor_redirect: bool, - max_depth: usize, + mut max_depth: usize, ) { let negated_operand = negated_op_needs_bracketing(&self.iter, self.op_dir, &op); + let addr = match self.check_for_seen(&mut max_depth) { + Some(addr) => addr, + None => return, + }; + let print_struct = |printer: &mut Self, name: Atom, arity: usize| { if name == atom!("[]") && arity == 0 { match printer.state_stack.last() { @@ -1628,11 +1645,6 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { } }; - let addr = match self.check_for_seen(max_depth) { - Some(addr) => addr, - None => return, - }; - if !addr.is_var() && !addr.is_compound(&self.iter.heap) && self.max_depth_exhausted(max_depth)