]> Repositorios git - scryer-prolog.git/commitdiff
correct depth calculation for lists that are their own car (#1876)
authorMark <[email protected]>
Sat, 30 Sep 2023 23:15:20 +0000 (17:15 -0600)
committerMark <[email protected]>
Sat, 30 Sep 2023 23:15:20 +0000 (17:15 -0600)
src/heap_print.rs

index daf339c8a852ee5eda1bbc0476859f49790be5f5..1ad88f29e53c3f73ca28b25f3269bb4df6407dbe 100644 (file)
@@ -861,7 +861,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
         )
     }
 
-    fn check_for_seen(&mut self, max_depth: usize) -> Option<HeapCellValue> {
+    fn check_for_seen(&mut self, max_depth: &mut usize) -> Option<HeapCellValue> {
         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<DirectedOp>,
         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)