]> Repositorios git - scryer-prolog.git/commitdiff
improve printer's handling of cyclic lists (#2111, #2635)
authorMark Thom <[email protected]>
Sat, 23 Aug 2025 01:55:32 +0000 (18:55 -0700)
committerMark Thom <[email protected]>
Sat, 23 Aug 2025 20:23:39 +0000 (13:23 -0700)
src/heap_iter.rs
src/heap_print.rs

index 583d297d3a2ab2323b2bfb1e7406f704b07e3820..7726b49b7798f2d397553766039b9f09f269a2f6 100644 (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);
         }
 
index 53dbbe63638bbeb17b8cf716c5b6c2f86b741f87..d1d7bdb4e6b25b258fb57f49658cb0773e98562c 100644 (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;
-
-                                        // 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(