fix loop in stackful iterator (#1405, #1384)

This commit is contained in:
Mark Thom
2022-04-07 20:48:40 -06:00
parent 4a6ffb6b9e
commit 064bfa5e0d
2 changed files with 57 additions and 61 deletions

View File

@@ -103,11 +103,6 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
None None
} }
#[inline]
pub fn stack_is_empty(&self) -> bool {
self.stack.is_empty()
}
#[inline] #[inline]
pub fn focus(&self) -> usize { pub fn focus(&self) -> usize {
self.h self.h
@@ -165,14 +160,10 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
} }
(HeapCellValueTag::Lis, vh) => { (HeapCellValueTag::Lis, vh) => {
self.push_if_unmarked(vh); self.push_if_unmarked(vh);
self.push_if_unmarked(vh + 1);
self.stack.push(IterStackLoc::iterable_heap_loc(vh + 1)); self.stack.push(IterStackLoc::mark_heap_loc(vh + 1));
if self.heap[vh + 1].get_mark_bit() {
self.heap[vh + 1].set_forwarding_bit(true);
} else {
forward_if_referent_marked(&mut self.heap, vh + 1); forward_if_referent_marked(&mut self.heap, vh + 1);
}
self.stack.push(IterStackLoc::mark_heap_loc(vh)); self.stack.push(IterStackLoc::mark_heap_loc(vh));
forward_if_referent_marked(&mut self.heap, vh); forward_if_referent_marked(&mut self.heap, vh);
@@ -193,19 +184,23 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
(HeapCellValueTag::PStr) => { (HeapCellValueTag::PStr) => {
self.push_if_unmarked(h); self.push_if_unmarked(h);
forward_if_referent_marked(&mut self.heap, h+1);
self.stack.push(IterStackLoc::iterable_heap_loc(h+1)); self.stack.push(IterStackLoc::iterable_heap_loc(h+1));
forward_if_referent_marked(&mut self.heap, h+1);
return Some(self.heap[h]); return Some(self.heap[h]);
} }
(HeapCellValueTag::Atom, (_name, arity)) => { (HeapCellValueTag::Atom, (_name, arity)) => {
if arity > 0 { if arity > 0 {
self.push_if_unmarked(h); self.push_if_unmarked(h);
for h in h + 1 .. h + arity + 1 {
self.push_if_unmarked(h);
}
} }
for h in (h + 1 .. h + arity + 1).rev() { for h in (h + 1 .. h + arity + 1).rev() {
self.stack.push(IterStackLoc::mark_heap_loc(h));
forward_if_referent_marked(&mut self.heap, h); forward_if_referent_marked(&mut self.heap, h);
self.stack.push(IterStackLoc::iterable_heap_loc(h));
} }
return Some(self.heap[h]); return Some(self.heap[h]);
@@ -1716,7 +1711,9 @@ mod tests {
); );
let mut link_back = list_loc_as_cell!(1); let mut link_back = list_loc_as_cell!(1);
link_back.set_forwarding_bit(true); link_back.set_forwarding_bit(true);
link_back.set_mark_bit(true);
assert_eq!(iter.next().unwrap(), link_back); assert_eq!(iter.next().unwrap(), link_back);
@@ -1738,7 +1735,9 @@ mod tests {
); );
let mut cyclic_link = list_loc_as_cell!(1); let mut cyclic_link = list_loc_as_cell!(1);
cyclic_link.set_forwarding_bit(true); cyclic_link.set_forwarding_bit(true);
cyclic_link.set_mark_bit(true);
assert_eq!(iter.next().unwrap(), list_loc_as_cell!(1)); assert_eq!(iter.next().unwrap(), list_loc_as_cell!(1));
assert_eq!( assert_eq!(
@@ -1808,7 +1807,7 @@ mod tests {
); );
assert_eq!( assert_eq!(
iter.next().unwrap(), unmark_cell_bits!(iter.next().unwrap()),
atom_as_cell!(atom!("y")) atom_as_cell!(atom!("y"))
); );
@@ -2204,7 +2203,9 @@ mod tests {
); );
let mut link_back = list_loc_as_cell!(1); let mut link_back = list_loc_as_cell!(1);
link_back.set_forwarding_bit(true); link_back.set_forwarding_bit(true);
link_back.set_mark_bit(true);
assert_eq!(iter.next().unwrap(), link_back); assert_eq!(iter.next().unwrap(), link_back);

View File

@@ -689,8 +689,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
let op = DirectedOp::Left(name, spec); let op = DirectedOp::Left(name, spec);
self.state_stack self.state_stack.push(TokenOrRedirect::CompositeRedirect(max_depth, op));
.push(TokenOrRedirect::CompositeRedirect(max_depth, op));
self.state_stack.push(TokenOrRedirect::Space); self.state_stack.push(TokenOrRedirect::Space);
self.state_stack.push(TokenOrRedirect::Atom(name)); self.state_stack.push(TokenOrRedirect::Atom(name));
} }
@@ -1552,8 +1551,10 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
} }
pub fn print(mut self) -> Outputter { pub fn print(mut self) -> Outputter {
loop { let spec = self.toplevel_spec.take();
if let Some(loc_data) = self.state_stack.pop() { self.handle_heap_term(spec, false, self.max_depth);
while let Some(loc_data) = self.state_stack.pop() {
match loc_data { match loc_data {
TokenOrRedirect::Atom(atom) => self.print_atom(atom), TokenOrRedirect::Atom(atom) => self.print_atom(atom),
TokenOrRedirect::BarAsOp => append_str!(self, " | "), TokenOrRedirect::BarAsOp => append_str!(self, " | "),
@@ -1592,12 +1593,6 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
TokenOrRedirect::LeftCurly => push_char!(self, '{'), TokenOrRedirect::LeftCurly => push_char!(self, '{'),
TokenOrRedirect::RightCurly => push_char!(self, '}'), TokenOrRedirect::RightCurly => push_char!(self, '}'),
} }
} else if !self.iter.stack_is_empty() {
let spec = self.toplevel_spec.take();
self.handle_heap_term(spec, false, self.max_depth);
} else {
break;
}
} }
self.outputter self.outputter