read from machine stack in stackful pre-order iterator (#1812)
This commit is contained in:
454
src/heap_iter.rs
454
src/heap_iter.rs
@@ -19,28 +19,45 @@ enum IterStackLocTag {
|
||||
PendingMark,
|
||||
}
|
||||
|
||||
#[derive(BitfieldSpecifier, Clone, Copy, Debug, PartialEq, Eq)]
|
||||
#[bits = 1]
|
||||
pub enum HeapOrStackTag {
|
||||
Heap,
|
||||
Stack,
|
||||
}
|
||||
|
||||
#[bitfield]
|
||||
#[repr(u64)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct IterStackLoc {
|
||||
value: B62,
|
||||
pub value: B61,
|
||||
tag: IterStackLocTag,
|
||||
heap_or_stack: HeapOrStackTag,
|
||||
}
|
||||
|
||||
impl IterStackLoc {
|
||||
#[inline]
|
||||
pub fn iterable_heap_loc(h: usize) -> Self {
|
||||
IterStackLoc::new().with_tag(IterStackLocTag::Iterable).with_value(h as u64)
|
||||
pub fn iterable_loc(h: usize, heap_or_stack: HeapOrStackTag) -> Self {
|
||||
IterStackLoc::new()
|
||||
.with_tag(IterStackLocTag::Iterable)
|
||||
.with_heap_or_stack(heap_or_stack)
|
||||
.with_value(h as u64)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn mark_heap_loc(h: usize) -> Self {
|
||||
IterStackLoc::new().with_tag(IterStackLocTag::Marked).with_value(h as u64)
|
||||
fn mark_loc(h: usize, heap_or_stack: HeapOrStackTag) -> Self {
|
||||
IterStackLoc::new()
|
||||
.with_tag(IterStackLocTag::Marked)
|
||||
.with_heap_or_stack(heap_or_stack)
|
||||
.with_value(h as u64)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn pending_mark_heap_loc(h: usize) -> Self {
|
||||
IterStackLoc::new().with_tag(IterStackLocTag::PendingMark).with_value(h as u64)
|
||||
fn pending_mark_loc(h: usize, heap_or_stack: HeapOrStackTag) -> Self {
|
||||
IterStackLoc::new()
|
||||
.with_tag(IterStackLocTag::PendingMark)
|
||||
.with_heap_or_stack(heap_or_stack)
|
||||
.with_value(h as u64)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -52,39 +69,35 @@ impl IterStackLoc {
|
||||
pub fn is_pending_mark(self) -> bool {
|
||||
self.tag() == IterStackLocTag::PendingMark
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn forward_if_referent_marked(heap: &mut [HeapCellValue], h: usize) {
|
||||
read_heap_cell!(heap[h],
|
||||
(HeapCellValueTag::Str
|
||||
| HeapCellValueTag::Lis
|
||||
| HeapCellValueTag::AttrVar
|
||||
| HeapCellValueTag::Var
|
||||
| HeapCellValueTag::PStrLoc, vh) => {
|
||||
if heap[vh].get_mark_bit() {
|
||||
heap[h].set_forwarding_bit(true);
|
||||
#[inline]
|
||||
pub fn as_ref(self) -> Ref {
|
||||
match self.heap_or_stack() {
|
||||
HeapOrStackTag::Heap => {
|
||||
Ref::heap_cell(self.value() as usize)
|
||||
}
|
||||
HeapOrStackTag::Stack => {
|
||||
Ref::stack_cell(self.value() as usize)
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct StackfulPreOrderHeapIter<'a> {
|
||||
pub heap: &'a mut Vec<HeapCellValue>,
|
||||
machine_stack: Option<&'a Stack>,
|
||||
pub machine_stack: &'a mut Stack,
|
||||
stack: Vec<IterStackLoc>,
|
||||
h: usize,
|
||||
h: IterStackLoc,
|
||||
}
|
||||
|
||||
impl<'a> Drop for StackfulPreOrderHeapIter<'a> {
|
||||
fn drop(&mut self) {
|
||||
while let Some(h) = self.stack.pop() {
|
||||
let h = h.value() as usize;
|
||||
let cell = self.read_cell_mut(h);
|
||||
|
||||
self.heap[h].set_forwarding_bit(false);
|
||||
self.heap[h].set_mark_bit(false);
|
||||
cell.set_forwarding_bit(false);
|
||||
cell.set_mark_bit(false);
|
||||
}
|
||||
|
||||
self.heap.pop();
|
||||
@@ -92,53 +105,93 @@ impl<'a> Drop for StackfulPreOrderHeapIter<'a> {
|
||||
}
|
||||
|
||||
pub trait FocusedHeapIter: Iterator<Item = HeapCellValue> {
|
||||
fn focus(&self) -> usize;
|
||||
fn focus(&self) -> IterStackLoc;
|
||||
}
|
||||
|
||||
impl<'a> FocusedHeapIter for StackfulPreOrderHeapIter<'a> {
|
||||
#[inline]
|
||||
fn focus(&self) -> usize {
|
||||
fn focus(&self) -> IterStackLoc {
|
||||
self.h
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> StackfulPreOrderHeapIter<'a> {
|
||||
#[inline]
|
||||
fn new(heap: &'a mut Vec<HeapCellValue>, cell: HeapCellValue) -> Self {
|
||||
let h = heap.len();
|
||||
fn new(heap: &'a mut Vec<HeapCellValue>, stack: &'a mut Stack, cell: HeapCellValue) -> Self {
|
||||
let h = IterStackLoc::iterable_loc(heap.len(), HeapOrStackTag::Heap);
|
||||
heap.push(cell);
|
||||
|
||||
Self {
|
||||
heap,
|
||||
h,
|
||||
machine_stack: None,
|
||||
stack: vec![IterStackLoc::iterable_heap_loc(h)],
|
||||
machine_stack: stack,
|
||||
stack: vec![h],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn iterate_over_machine_stack(&mut self, stack: &'a Stack) {
|
||||
self.machine_stack = Some(stack);
|
||||
#[inline]
|
||||
fn forward_if_referent_marked(&mut self, loc: IterStackLoc) {
|
||||
read_heap_cell!(self.read_cell(loc),
|
||||
(HeapCellValueTag::Str |
|
||||
HeapCellValueTag::Lis |
|
||||
HeapCellValueTag::AttrVar |
|
||||
HeapCellValueTag::Var |
|
||||
HeapCellValueTag::PStrLoc, vh) => {
|
||||
if self.heap[vh].get_mark_bit() {
|
||||
self.read_cell_mut(loc).set_forwarding_bit(true);
|
||||
}
|
||||
}
|
||||
(HeapCellValueTag::StackVar, vs) => {
|
||||
if self.machine_stack[vs].get_mark_bit() {
|
||||
self.read_cell_mut(loc).set_forwarding_bit(true);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn push_stack(&mut self, h: usize) {
|
||||
self.stack.push(IterStackLoc::iterable_heap_loc(h));
|
||||
pub fn push_stack(&mut self, h: IterStackLoc) {
|
||||
self.stack.push(h);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn stack_last(&self) -> Option<usize> {
|
||||
pub fn read_cell_mut(&mut self, loc: IterStackLoc) -> &mut HeapCellValue {
|
||||
match loc.heap_or_stack() {
|
||||
HeapOrStackTag::Heap => {
|
||||
&mut self.heap[loc.value() as usize]
|
||||
}
|
||||
HeapOrStackTag::Stack => {
|
||||
&mut self.machine_stack[loc.value() as usize]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn read_cell(&self, loc: IterStackLoc) -> HeapCellValue {
|
||||
match loc.heap_or_stack() {
|
||||
HeapOrStackTag::Heap => {
|
||||
self.heap[loc.value() as usize]
|
||||
}
|
||||
HeapOrStackTag::Stack => {
|
||||
self.machine_stack[loc.value() as usize]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn stack_last(&self) -> Option<IterStackLoc> {
|
||||
for h in self.stack.iter().rev() {
|
||||
let is_readable_marked = h.is_marked();
|
||||
let h = h.value() as usize;
|
||||
let cell = self.heap[h];
|
||||
let cell = self.read_cell(*h);
|
||||
|
||||
if cell.get_forwarding_bit() {
|
||||
return Some(h);
|
||||
return Some(*h);
|
||||
} else if cell.get_mark_bit() && !is_readable_marked {
|
||||
continue;
|
||||
}
|
||||
|
||||
return Some(h);
|
||||
return Some(*h);
|
||||
}
|
||||
|
||||
None
|
||||
@@ -148,10 +201,9 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
|
||||
pub fn pop_stack(&mut self) -> Option<HeapCellValue> {
|
||||
while let Some(h) = self.stack.pop() {
|
||||
let is_readable_marked = h.is_marked();
|
||||
let h = h.value() as usize;
|
||||
self.h = h;
|
||||
|
||||
let cell = &mut self.heap[h];
|
||||
self.h = h;
|
||||
let cell = self.read_cell_mut(h);
|
||||
|
||||
if cell.get_forwarding_bit() {
|
||||
cell.set_forwarding_bit(false);
|
||||
@@ -166,50 +218,29 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
|
||||
None
|
||||
}
|
||||
|
||||
fn push_if_unmarked(&mut self, h: usize) {
|
||||
if !self.heap[h].get_mark_bit() {
|
||||
self.heap[h].set_mark_bit(true);
|
||||
self.stack.push(IterStackLoc::iterable_heap_loc(h));
|
||||
fn push_if_unmarked(&mut self, loc: IterStackLoc) {
|
||||
let cell = self.read_cell_mut(loc);
|
||||
|
||||
if !cell.get_mark_bit() {
|
||||
cell.set_mark_bit(true);
|
||||
self.stack.push(IterStackLoc::iterable_loc(loc.value() as usize, loc.heap_or_stack()));
|
||||
}
|
||||
}
|
||||
|
||||
fn stack_deref(&self, s: usize) -> Option<HeapCellValue> {
|
||||
if let Some(stack) = &self.machine_stack {
|
||||
let mut cell = stack[s];
|
||||
|
||||
while cell.is_stack_var() {
|
||||
let s = cell.get_value();
|
||||
|
||||
if cell == stack[s] {
|
||||
break;
|
||||
}
|
||||
|
||||
cell = stack[s];
|
||||
}
|
||||
|
||||
return Some(cell);
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn follow(&mut self) -> Option<HeapCellValue> {
|
||||
while let Some(h) = self.stack.pop() {
|
||||
if h.is_pending_mark() {
|
||||
let h = h.value() as usize;
|
||||
|
||||
self.push_if_unmarked(h);
|
||||
self.stack.push(IterStackLoc::mark_heap_loc(h));
|
||||
self.stack.push(IterStackLoc::mark_loc(h.value() as usize, h.heap_or_stack()));
|
||||
|
||||
forward_if_referent_marked(&mut self.heap, h);
|
||||
self.forward_if_referent_marked(h);
|
||||
continue;
|
||||
}
|
||||
|
||||
let is_readable_marked = h.is_marked();
|
||||
let h = h.value() as usize;
|
||||
|
||||
self.h = h;
|
||||
let cell = &mut self.heap[h];
|
||||
|
||||
let is_readable_marked = h.is_marked();
|
||||
let cell = self.read_cell_mut(h);
|
||||
|
||||
if cell.get_forwarding_bit() {
|
||||
let copy = *cell;
|
||||
@@ -220,62 +251,73 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
|
||||
continue;
|
||||
}
|
||||
|
||||
let cell = if cell.get_tag() == HeapCellValueTag::StackVar {
|
||||
let cell = *cell;
|
||||
self.stack_deref(cell.get_value()).unwrap_or(cell)
|
||||
} else {
|
||||
*cell
|
||||
};
|
||||
|
||||
read_heap_cell!(cell,
|
||||
read_heap_cell!(*cell,
|
||||
(HeapCellValueTag::Str | HeapCellValueTag::PStrLoc, vh) => {
|
||||
self.push_if_unmarked(vh);
|
||||
self.stack.push(IterStackLoc::mark_heap_loc(vh));
|
||||
let loc = IterStackLoc::iterable_loc(vh, HeapOrStackTag::Heap);
|
||||
|
||||
self.push_if_unmarked(loc);
|
||||
self.stack.push(IterStackLoc::mark_loc(vh, HeapOrStackTag::Heap));
|
||||
}
|
||||
(HeapCellValueTag::Lis, vh) => {
|
||||
self.push_if_unmarked(vh);
|
||||
let loc = IterStackLoc::iterable_loc(vh, HeapOrStackTag::Heap);
|
||||
|
||||
self.stack.push(IterStackLoc::pending_mark_heap_loc(vh + 1));
|
||||
self.stack.push(IterStackLoc::mark_heap_loc(vh));
|
||||
self.push_if_unmarked(loc);
|
||||
|
||||
forward_if_referent_marked(&mut self.heap, vh);
|
||||
self.stack.push(IterStackLoc::pending_mark_loc(vh + 1, HeapOrStackTag::Heap));
|
||||
self.stack.push(IterStackLoc::mark_loc(vh, HeapOrStackTag::Heap));
|
||||
|
||||
return Some(self.heap[h]);
|
||||
self.forward_if_referent_marked(loc);
|
||||
|
||||
return Some(self.read_cell(h));
|
||||
}
|
||||
(HeapCellValueTag::AttrVar | HeapCellValueTag::Var, vh) => {
|
||||
self.push_if_unmarked(vh);
|
||||
self.stack.push(IterStackLoc::mark_heap_loc(vh));
|
||||
forward_if_referent_marked(&mut self.heap, vh);
|
||||
let loc = IterStackLoc::iterable_loc(vh, HeapOrStackTag::Heap);
|
||||
|
||||
self.push_if_unmarked(loc);
|
||||
self.stack.push(IterStackLoc::mark_loc(vh, HeapOrStackTag::Heap));
|
||||
self.forward_if_referent_marked(loc);
|
||||
}
|
||||
(HeapCellValueTag::StackVar, vs) => {
|
||||
let loc = IterStackLoc::iterable_loc(vs, HeapOrStackTag::Stack);
|
||||
|
||||
self.push_if_unmarked(loc);
|
||||
self.stack.push(IterStackLoc::mark_loc(vs, HeapOrStackTag::Stack));
|
||||
self.forward_if_referent_marked(loc);
|
||||
}
|
||||
(HeapCellValueTag::PStrOffset, offset) => {
|
||||
self.push_if_unmarked(offset);
|
||||
self.stack.push(IterStackLoc::iterable_heap_loc(h+1));
|
||||
self.push_if_unmarked(IterStackLoc::iterable_loc(offset, HeapOrStackTag::Heap));
|
||||
self.stack.push(IterStackLoc::iterable_loc((h.value()+1) as usize, HeapOrStackTag::Heap));
|
||||
|
||||
return Some(self.heap[h]);
|
||||
return Some(self.read_cell(h));
|
||||
}
|
||||
(HeapCellValueTag::PStr) => {
|
||||
self.push_if_unmarked(h);
|
||||
let tail_loc = IterStackLoc::iterable_loc((h.value()+1) as usize, HeapOrStackTag::Heap);
|
||||
|
||||
self.stack.push(IterStackLoc::iterable_heap_loc(h+1));
|
||||
forward_if_referent_marked(&mut self.heap, h+1);
|
||||
self.push_if_unmarked(IterStackLoc::iterable_loc(h.value() as usize, HeapOrStackTag::Heap));
|
||||
self.stack.push(tail_loc);
|
||||
self.forward_if_referent_marked(tail_loc);
|
||||
|
||||
return Some(self.heap[h]);
|
||||
return Some(self.read_cell(h));
|
||||
}
|
||||
(HeapCellValueTag::Atom, (_name, arity)) => {
|
||||
for h in (h + 2 .. h + arity + 1).rev() {
|
||||
self.stack.push(IterStackLoc::pending_mark_heap_loc(h));
|
||||
let l = h.value() as usize;
|
||||
|
||||
for l in (l + 2 .. l + arity + 1).rev() {
|
||||
self.stack.push(IterStackLoc::pending_mark_loc(l, HeapOrStackTag::Heap));
|
||||
}
|
||||
|
||||
if arity > 0 {
|
||||
self.push_if_unmarked(h+1);
|
||||
self.stack.push(IterStackLoc::mark_heap_loc(h+1));
|
||||
forward_if_referent_marked(&mut self.heap, h+1);
|
||||
let first_arg_loc = IterStackLoc::iterable_loc(l+1, HeapOrStackTag::Heap);
|
||||
|
||||
self.push_if_unmarked(first_arg_loc);
|
||||
self.stack.push(IterStackLoc::mark_loc(l+1, HeapOrStackTag::Heap));
|
||||
self.forward_if_referent_marked(first_arg_loc);
|
||||
}
|
||||
|
||||
return Some(self.heap[h]);
|
||||
return Some(self.read_cell(h));
|
||||
}
|
||||
_ => {
|
||||
return Some(cell);
|
||||
return Some(*cell);
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -303,19 +345,20 @@ pub(crate) fn stackless_preorder_iter(
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn stackful_preorder_iter(
|
||||
heap: &mut Vec<HeapCellValue>,
|
||||
pub(crate) fn stackful_preorder_iter<'a>(
|
||||
heap: &'a mut Vec<HeapCellValue>,
|
||||
stack: &'a mut Stack,
|
||||
cell: HeapCellValue,
|
||||
) -> StackfulPreOrderHeapIter {
|
||||
StackfulPreOrderHeapIter::new(heap, cell)
|
||||
) -> StackfulPreOrderHeapIter<'a> {
|
||||
StackfulPreOrderHeapIter::new(heap, stack, cell)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct PostOrderIterator<Iter: FocusedHeapIter> {
|
||||
focus: usize,
|
||||
focus: IterStackLoc,
|
||||
base_iter: Iter,
|
||||
base_iter_valid: bool,
|
||||
parent_stack: Vec<(usize, HeapCellValue, usize)>, // number of children, parent node, focus.
|
||||
parent_stack: Vec<(usize, HeapCellValue, IterStackLoc)>, // number of children, parent node, focus.
|
||||
}
|
||||
|
||||
impl<Iter: FocusedHeapIter> Deref for PostOrderIterator<Iter> {
|
||||
@@ -329,7 +372,7 @@ impl<Iter: FocusedHeapIter> Deref for PostOrderIterator<Iter> {
|
||||
impl<Iter: FocusedHeapIter> PostOrderIterator<Iter> {
|
||||
pub(crate) fn new(base_iter: Iter) -> Self {
|
||||
PostOrderIterator {
|
||||
focus: 0,
|
||||
focus: IterStackLoc::iterable_loc(0, HeapOrStackTag::Heap),
|
||||
base_iter,
|
||||
base_iter_valid: true,
|
||||
parent_stack: vec![],
|
||||
@@ -386,7 +429,7 @@ impl<Iter: FocusedHeapIter> Iterator for PostOrderIterator<Iter> {
|
||||
|
||||
impl<Iter: FocusedHeapIter> FocusedHeapIter for PostOrderIterator<Iter> {
|
||||
#[inline(always)]
|
||||
fn focus(&self) -> usize {
|
||||
fn focus(&self) -> IterStackLoc {
|
||||
self.focus
|
||||
}
|
||||
}
|
||||
@@ -402,7 +445,8 @@ impl<Iter: FocusedHeapIter> PostOrderIterator<Iter> {
|
||||
if let Some((_child_count, item, focus)) = self.parent_stack.last() {
|
||||
read_heap_cell!(item,
|
||||
(HeapCellValueTag::Atom, (_name, arity)) => {
|
||||
return focus + arity >= idx_loc && *focus < idx_loc;
|
||||
let focus = focus.value() as usize;
|
||||
return focus + arity >= idx_loc && focus < idx_loc;
|
||||
}
|
||||
_ => {}
|
||||
);
|
||||
@@ -435,9 +479,10 @@ impl<'a> LeftistPostOrderHeapIter<'a> {
|
||||
#[inline]
|
||||
pub(crate) fn stackful_post_order_iter<'a>(
|
||||
heap: &'a mut Heap,
|
||||
stack: &'a mut Stack,
|
||||
cell: HeapCellValue,
|
||||
) -> LeftistPostOrderHeapIter<'a> {
|
||||
PostOrderIterator::new(StackfulPreOrderHeapIter::new(heap, cell))
|
||||
PostOrderIterator::new(StackfulPreOrderHeapIter::new(heap, stack, cell))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -1416,7 +1461,11 @@ mod tests {
|
||||
.extend(functor!(f_atom, [atom(a_atom), atom(b_atom)]));
|
||||
|
||||
{
|
||||
let mut iter = StackfulPreOrderHeapIter::new(&mut wam.machine_st.heap, str_loc_as_cell!(0));
|
||||
let mut iter = StackfulPreOrderHeapIter::new(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
str_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
unmark_cell_bits!(iter.next().unwrap()),
|
||||
@@ -1447,7 +1496,11 @@ mod tests {
|
||||
));
|
||||
|
||||
for _ in 0..20 {
|
||||
let mut iter = StackfulPreOrderHeapIter::new(&mut wam.machine_st.heap, str_loc_as_cell!(0));
|
||||
let mut iter = StackfulPreOrderHeapIter::new(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
str_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
unmark_cell_bits!(iter.next().unwrap()),
|
||||
@@ -1475,7 +1528,12 @@ mod tests {
|
||||
{
|
||||
wam.machine_st.heap.push(heap_loc_as_cell!(0));
|
||||
|
||||
let mut iter = StackfulPreOrderHeapIter::new(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
|
||||
let mut iter = StackfulPreOrderHeapIter::new(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
heap_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
let mut var = heap_loc_as_cell!(0);
|
||||
|
||||
// self-referencing variables are copied with their forwarding
|
||||
@@ -1497,7 +1555,11 @@ mod tests {
|
||||
wam.machine_st.heap.push(heap_loc_as_cell!(1));
|
||||
wam.machine_st.heap.push(heap_loc_as_cell!(0));
|
||||
|
||||
let mut iter = StackfulPreOrderHeapIter::new(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
|
||||
let mut iter = StackfulPreOrderHeapIter::new(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
heap_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
unmark_cell_bits!(iter.next().unwrap()),
|
||||
@@ -1517,7 +1579,11 @@ mod tests {
|
||||
wam.machine_st.heap.push(empty_list_as_cell!());
|
||||
|
||||
{
|
||||
let mut iter = StackfulPreOrderHeapIter::new(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
|
||||
let mut iter = StackfulPreOrderHeapIter::new(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
heap_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
unmark_cell_bits!(iter.next().unwrap()),
|
||||
@@ -1549,7 +1615,11 @@ mod tests {
|
||||
wam.machine_st.heap.push(heap_loc_as_cell!(0));
|
||||
|
||||
{
|
||||
let mut iter = StackfulPreOrderHeapIter::new(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
|
||||
let mut iter = StackfulPreOrderHeapIter::new(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
heap_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
// the cycle will be iterated twice before being detected.
|
||||
assert_eq!(
|
||||
@@ -1577,7 +1647,11 @@ mod tests {
|
||||
}
|
||||
|
||||
{
|
||||
let mut iter = StackfulPreOrderHeapIter::new(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
|
||||
let mut iter = StackfulPreOrderHeapIter::new(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
heap_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
// cut the iteration short to check that all cells are
|
||||
// unmarked and unforwarded by the Drop instance of
|
||||
@@ -1611,7 +1685,11 @@ mod tests {
|
||||
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
|
||||
|
||||
{
|
||||
let mut iter = StackfulPreOrderHeapIter::new(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
|
||||
let mut iter = StackfulPreOrderHeapIter::new(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
heap_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_cell);
|
||||
assert_eq!(
|
||||
@@ -1631,7 +1709,11 @@ mod tests {
|
||||
let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize];
|
||||
|
||||
{
|
||||
let mut iter = stackful_preorder_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
|
||||
let mut iter = stackful_preorder_iter(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
heap_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_cell);
|
||||
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_second_cell);
|
||||
@@ -1650,7 +1732,12 @@ mod tests {
|
||||
wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(0i64)));
|
||||
|
||||
{
|
||||
let mut iter = stackful_preorder_iter(&mut wam.machine_st.heap, pstr_loc_as_cell!(0));
|
||||
let mut iter = stackful_preorder_iter(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
pstr_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
let pstr_offset_cell = pstr_offset_as_cell!(0);
|
||||
|
||||
// pstr_offset_cell.set_forwarding_bit(true);
|
||||
@@ -1675,7 +1762,12 @@ mod tests {
|
||||
wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(1i64)));
|
||||
|
||||
{
|
||||
let mut iter = stackful_preorder_iter(&mut wam.machine_st.heap, pstr_loc_as_cell!(0));
|
||||
let mut iter = stackful_preorder_iter(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
pstr_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
let pstr_offset_cell = pstr_offset_as_cell!(0);
|
||||
|
||||
// pstr_offset_cell.set_forwarding_bit(true);
|
||||
@@ -1688,7 +1780,7 @@ mod tests {
|
||||
|
||||
let h = iter.focus();
|
||||
|
||||
assert_eq!(h, 5);
|
||||
assert_eq!(h.value(), 5);
|
||||
assert_eq!(unmark_cell_bits!(iter.heap[4]), pstr_offset_as_cell!(0));
|
||||
assert_eq!(unmark_cell_bits!(iter.heap[5]), fixnum_as_cell!(Fixnum::build_with(1i64)));
|
||||
|
||||
@@ -1708,7 +1800,11 @@ mod tests {
|
||||
wam.machine_st.heap.extend(functor);
|
||||
|
||||
{
|
||||
let mut iter = StackfulPreOrderHeapIter::new(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
|
||||
let mut iter = StackfulPreOrderHeapIter::new(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
heap_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
unmark_cell_bits!(iter.next().unwrap()),
|
||||
@@ -1767,7 +1863,11 @@ mod tests {
|
||||
wam.machine_st.heap[4] = list_loc_as_cell!(1);
|
||||
|
||||
{
|
||||
let mut iter = stackful_preorder_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
|
||||
let mut iter = stackful_preorder_iter(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
heap_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
unmark_cell_bits!(iter.next().unwrap()),
|
||||
@@ -1834,6 +1934,7 @@ mod tests {
|
||||
{
|
||||
let mut iter = StackfulPreOrderHeapIter::new(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
heap_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
@@ -1865,6 +1966,7 @@ mod tests {
|
||||
{
|
||||
let mut iter = stackful_preorder_iter(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
heap_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
@@ -1899,6 +2001,7 @@ mod tests {
|
||||
{
|
||||
let mut iter = stackful_preorder_iter(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
heap_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
@@ -1933,7 +2036,11 @@ mod tests {
|
||||
.extend(functor!(f_atom, [atom(a_atom), atom(b_atom)]));
|
||||
|
||||
{
|
||||
let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, str_loc_as_cell!(0));
|
||||
let mut iter = stackful_post_order_iter(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
str_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
unmark_cell_bits!(iter.next().unwrap()),
|
||||
@@ -1964,7 +2071,11 @@ mod tests {
|
||||
));
|
||||
|
||||
for _ in 0..20 { // 0000 {
|
||||
let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, str_loc_as_cell!(0));
|
||||
let mut iter = stackful_post_order_iter(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
str_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
unmark_cell_bits!(iter.next().unwrap()),
|
||||
@@ -1994,7 +2105,12 @@ mod tests {
|
||||
{
|
||||
wam.machine_st.heap.push(heap_loc_as_cell!(0));
|
||||
|
||||
let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
|
||||
let mut iter = stackful_post_order_iter(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
heap_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
let mut var = heap_loc_as_cell!(0);
|
||||
|
||||
// self-referencing variables are copied with their forwarding
|
||||
@@ -2016,7 +2132,11 @@ mod tests {
|
||||
wam.machine_st.heap.push(heap_loc_as_cell!(1));
|
||||
wam.machine_st.heap.push(heap_loc_as_cell!(0));
|
||||
|
||||
let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
|
||||
let mut iter = stackful_post_order_iter(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
heap_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
unmark_cell_bits!(iter.next().unwrap()),
|
||||
@@ -2036,7 +2156,11 @@ mod tests {
|
||||
wam.machine_st.heap.push(empty_list_as_cell!());
|
||||
|
||||
{
|
||||
let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
|
||||
let mut iter = stackful_post_order_iter(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
heap_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
unmark_cell_bits!(iter.next().unwrap()),
|
||||
@@ -2068,7 +2192,11 @@ mod tests {
|
||||
wam.machine_st.heap.push(heap_loc_as_cell!(0));
|
||||
|
||||
{
|
||||
let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
|
||||
let mut iter = stackful_post_order_iter(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
heap_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
// the cycle will be iterated twice before being detected.
|
||||
assert_eq!(
|
||||
@@ -2098,6 +2226,7 @@ mod tests {
|
||||
{
|
||||
let mut iter = stackful_post_order_iter(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
heap_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
@@ -2133,7 +2262,11 @@ mod tests {
|
||||
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
|
||||
|
||||
{
|
||||
let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, pstr_loc_as_cell!(0));
|
||||
let mut iter = stackful_post_order_iter(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
pstr_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
unmark_cell_bits!(iter.next().unwrap()),
|
||||
@@ -2152,7 +2285,11 @@ mod tests {
|
||||
let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize];
|
||||
|
||||
{
|
||||
let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, pstr_loc_as_cell!(0));
|
||||
let mut iter = stackful_post_order_iter(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
pstr_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
unmark_cell_bits!(iter.next().unwrap()),
|
||||
@@ -2171,7 +2308,11 @@ mod tests {
|
||||
wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(0i64)));
|
||||
|
||||
{
|
||||
let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, pstr_loc_as_cell!(0));
|
||||
let mut iter = stackful_post_order_iter(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
pstr_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
assert_eq!(iter.next().unwrap(), fixnum_as_cell!(Fixnum::build_with(0i64)));
|
||||
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_offset_as_cell!(0));
|
||||
@@ -2186,7 +2327,11 @@ mod tests {
|
||||
wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(1i64)));
|
||||
|
||||
{
|
||||
let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, pstr_loc_as_cell!(0));
|
||||
let mut iter = stackful_post_order_iter(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
pstr_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
assert_eq!(iter.next().unwrap(), fixnum_as_cell!(Fixnum::build_with(1i64)));
|
||||
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_offset_as_cell!(0));
|
||||
@@ -2210,7 +2355,11 @@ mod tests {
|
||||
wam.machine_st.heap.extend(functor);
|
||||
|
||||
{
|
||||
let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
|
||||
let mut iter = stackful_post_order_iter(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
heap_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
unmark_cell_bits!(iter.next().unwrap()),
|
||||
@@ -2270,7 +2419,11 @@ mod tests {
|
||||
wam.machine_st.heap[4] = list_loc_as_cell!(1);
|
||||
|
||||
{
|
||||
let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
|
||||
let mut iter = stackful_post_order_iter(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.stack,
|
||||
heap_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
unmark_cell_bits!(iter.next().unwrap()),
|
||||
@@ -2377,7 +2530,10 @@ mod tests {
|
||||
));
|
||||
|
||||
for _ in 0..20 {
|
||||
let mut iter = stackless_post_order_iter(&mut wam.machine_st.heap, str_loc_as_cell!(0));
|
||||
let mut iter = stackless_post_order_iter(
|
||||
&mut wam.machine_st.heap,
|
||||
str_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), str_loc_as_cell!(0));
|
||||
|
||||
@@ -2407,7 +2563,10 @@ mod tests {
|
||||
{
|
||||
wam.machine_st.heap.push(heap_loc_as_cell!(0));
|
||||
|
||||
let mut iter = stackless_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
|
||||
let mut iter = stackless_post_order_iter(
|
||||
&mut wam.machine_st.heap,
|
||||
heap_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
unmark_cell_bits!(iter.next().unwrap()),
|
||||
@@ -2423,7 +2582,10 @@ mod tests {
|
||||
wam.machine_st.heap.push(heap_loc_as_cell!(1));
|
||||
wam.machine_st.heap.push(heap_loc_as_cell!(0));
|
||||
|
||||
let mut iter = stackless_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
|
||||
let mut iter = stackless_post_order_iter(
|
||||
&mut wam.machine_st.heap,
|
||||
heap_loc_as_cell!(0),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
unmark_cell_bits!(iter.next().unwrap()),
|
||||
|
||||
@@ -116,7 +116,9 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
|
||||
let mut parent_spec = DirectedOp::Left(atom!("-"), OpDesc::build_with(200, FY as u8));
|
||||
|
||||
loop {
|
||||
read_heap_cell!(self.heap[h],
|
||||
let cell = self.read_cell(h);
|
||||
|
||||
read_heap_cell!(cell,
|
||||
(HeapCellValueTag::Str, s) => {
|
||||
read_heap_cell!(self.heap[s],
|
||||
(HeapCellValueTag::Atom, (name, _arity)) => {
|
||||
@@ -125,7 +127,7 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
|
||||
if needs_bracketing(spec, &parent_spec) {
|
||||
return false;
|
||||
} else {
|
||||
h = s + 1;
|
||||
h = IterStackLoc::iterable_loc(s + 1, HeapOrStackTag::Heap);
|
||||
parent_spec = DirectedOp::Right(name, spec);
|
||||
continue;
|
||||
}
|
||||
@@ -140,7 +142,7 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
return property_check(self.heap[h]);
|
||||
return property_check(cell);
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -150,12 +152,12 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
|
||||
where
|
||||
P: Fn(HeapCellValue) -> bool,
|
||||
{
|
||||
let addr = match self.stack_last() {
|
||||
Some(h) => self.heap[h],
|
||||
let cell = match self.stack_last() {
|
||||
Some(h) => self.read_cell(h),
|
||||
None => return false,
|
||||
};
|
||||
|
||||
property_check(addr)
|
||||
property_check(cell)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -475,7 +477,6 @@ pub struct HCPrinter<'a, Outputter> {
|
||||
outputter: Outputter,
|
||||
iter: StackfulPreOrderHeapIter<'a>,
|
||||
atom_tbl: &'a mut AtomTable,
|
||||
stack: &'a Stack,
|
||||
op_dir: &'a OpDir,
|
||||
state_stack: Vec<TokenOrRedirect>,
|
||||
toplevel_spec: Option<DirectedOp>,
|
||||
@@ -541,16 +542,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
pub fn new(
|
||||
heap: &'a mut Heap,
|
||||
atom_tbl: &'a mut AtomTable,
|
||||
stack: &'a Stack,
|
||||
stack: &'a mut Stack,
|
||||
op_dir: &'a OpDir,
|
||||
output: Outputter,
|
||||
cell: HeapCellValue,
|
||||
) -> Self {
|
||||
HCPrinter {
|
||||
outputter: output,
|
||||
iter: stackful_preorder_iter(heap, cell),
|
||||
iter: stackful_preorder_iter(heap, stack, cell),
|
||||
atom_tbl,
|
||||
stack,
|
||||
op_dir,
|
||||
state_stack: vec![],
|
||||
toplevel_spec: None,
|
||||
@@ -758,14 +758,14 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
fn format_numbered_vars(&mut self) -> bool {
|
||||
let h = self.iter.stack_last().unwrap();
|
||||
|
||||
let addr = self.iter.heap[h];
|
||||
let addr = heap_bound_store(
|
||||
let cell = self.iter.read_cell(h);
|
||||
let cell = heap_bound_store(
|
||||
&self.iter.heap,
|
||||
heap_bound_deref(&self.iter.heap, addr),
|
||||
heap_bound_deref(&self.iter.heap, cell),
|
||||
);
|
||||
|
||||
// 7.10.4
|
||||
if let Some(var) = numbervar(&self.numbervars_offset, addr) {
|
||||
if let Some(var) = numbervar(&self.numbervars_offset, cell) {
|
||||
self.iter.pop_stack();
|
||||
self.state_stack.push(TokenOrRedirect::NumberedVar(var));
|
||||
return true;
|
||||
@@ -809,11 +809,11 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
};
|
||||
}
|
||||
|
||||
fn offset_as_string(&mut self, h: usize) -> Option<String> {
|
||||
let addr = self.iter.heap[h];
|
||||
fn offset_as_string(&mut self, h: IterStackLoc) -> Option<String> {
|
||||
let cell = self.iter.read_cell(h);
|
||||
|
||||
if let Some(var) = self.var_names.get(&addr) {
|
||||
read_heap_cell!(addr,
|
||||
if let Some(var) = self.var_names.get(&cell) {
|
||||
read_heap_cell!(cell,
|
||||
(HeapCellValueTag::Var | HeapCellValueTag::AttrVar | HeapCellValueTag::StackVar) => {
|
||||
return Some(format!("{}", var.as_str()));
|
||||
}
|
||||
@@ -824,7 +824,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
);
|
||||
}
|
||||
|
||||
read_heap_cell!(addr,
|
||||
read_heap_cell!(cell,
|
||||
(HeapCellValueTag::Lis | HeapCellValueTag::Str, h) => {
|
||||
Some(format!("{}", h))
|
||||
}
|
||||
@@ -1167,7 +1167,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
|
||||
fn print_list_like(&mut self, mut max_depth: usize) {
|
||||
let focus = self.iter.focus();
|
||||
let mut heap_pstr_iter = HeapPStrIter::new(self.iter.heap, focus);
|
||||
let mut heap_pstr_iter = HeapPStrIter::new(self.iter.heap, focus.value() as usize);
|
||||
|
||||
if heap_pstr_iter.next().is_some() {
|
||||
while let Some(_) = heap_pstr_iter.next() {}
|
||||
@@ -1179,7 +1179,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
let end_cell = heap_pstr_iter.focus;
|
||||
|
||||
if self.check_max_depth(&mut max_depth) {
|
||||
self.remove_list_children(focus);
|
||||
self.remove_list_children(focus.value() as usize);
|
||||
self.state_stack.push(TokenOrRedirect::Atom(atom!("...")));
|
||||
return;
|
||||
}
|
||||
@@ -1187,26 +1187,26 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
let at_cdr = self.outputter.ends_with("|");
|
||||
|
||||
if !at_cdr && !self.ignore_ops && end_cell.is_string_terminator(&self.iter.heap) {
|
||||
self.remove_list_children(focus);
|
||||
return self.print_proper_string(focus, max_depth);
|
||||
self.remove_list_children(focus.value() as usize);
|
||||
return self.print_proper_string(focus.value() as usize, max_depth);
|
||||
}
|
||||
|
||||
if self.ignore_ops {
|
||||
self.at_cdr(",");
|
||||
self.remove_list_children(focus);
|
||||
self.remove_list_children(focus.value() as usize);
|
||||
|
||||
if !self.print_string_as_functor(focus, max_depth) {
|
||||
if !self.print_string_as_functor(focus.value() as usize, max_depth) {
|
||||
if end_cell == empty_list_as_cell!() {
|
||||
append_str!(self, "[]");
|
||||
} else {
|
||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||
self.iter.push_stack(end_h);
|
||||
self.iter.push_stack(IterStackLoc::iterable_loc(end_h, HeapOrStackTag::Heap));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let value = heap_bound_store(
|
||||
self.iter.heap,
|
||||
heap_bound_deref(self.iter.heap, self.iter.heap[focus]),
|
||||
heap_bound_deref(self.iter.heap, self.iter.read_cell(focus)),
|
||||
);
|
||||
|
||||
read_heap_cell!(value,
|
||||
@@ -1217,7 +1217,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
let switch = Rc::new(Cell::new((!at_cdr, 0)));
|
||||
self.state_stack.push(TokenOrRedirect::CloseList(switch.clone()));
|
||||
|
||||
let (h, offset) = pstr_loc_and_offset(self.iter.heap, focus);
|
||||
let (h, offset) = pstr_loc_and_offset(self.iter.heap, focus.value() as usize);
|
||||
let pstr = cell_as_string!(self.iter.heap[h]);
|
||||
|
||||
let pstr = pstr.as_str_from(offset.get_num() as usize);
|
||||
@@ -1239,7 +1239,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
self.state_stack.push(TokenOrRedirect::HeadTailSeparator);
|
||||
} else if end_cell != empty_list_as_cell!() {
|
||||
if tag == HeapCellValueTag::PStrOffset {
|
||||
self.iter.push_stack(end_h);
|
||||
self.iter.push_stack(IterStackLoc::iterable_loc(end_h, HeapOrStackTag::Heap));
|
||||
}
|
||||
|
||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||
@@ -1597,8 +1597,6 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
|
||||
pub fn print(mut self) -> Outputter {
|
||||
let spec = self.toplevel_spec.take();
|
||||
|
||||
self.iter.iterate_over_machine_stack(self.stack);
|
||||
self.handle_heap_term(spec, false, self.max_depth);
|
||||
|
||||
while let Some(loc_data) = self.state_stack.pop() {
|
||||
@@ -1670,7 +1668,7 @@ mod tests {
|
||||
let printer = HCPrinter::new(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.atom_tbl,
|
||||
&wam.machine_st.stack,
|
||||
&mut wam.machine_st.stack,
|
||||
&wam.op_dir,
|
||||
PrinterOutputter::new(),
|
||||
heap_loc_as_cell!(0)
|
||||
@@ -1699,7 +1697,7 @@ mod tests {
|
||||
let printer = HCPrinter::new(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.atom_tbl,
|
||||
&wam.machine_st.stack,
|
||||
&mut wam.machine_st.stack,
|
||||
&wam.op_dir,
|
||||
PrinterOutputter::new(),
|
||||
heap_loc_as_cell!(0)
|
||||
@@ -1723,7 +1721,7 @@ mod tests {
|
||||
let printer = HCPrinter::new(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.atom_tbl,
|
||||
&wam.machine_st.stack,
|
||||
&mut wam.machine_st.stack,
|
||||
&wam.op_dir,
|
||||
PrinterOutputter::new(),
|
||||
heap_loc_as_cell!(0)
|
||||
@@ -1736,7 +1734,7 @@ mod tests {
|
||||
let mut printer = HCPrinter::new(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.atom_tbl,
|
||||
&wam.machine_st.stack,
|
||||
&mut wam.machine_st.stack,
|
||||
&wam.op_dir,
|
||||
PrinterOutputter::new(),
|
||||
heap_loc_as_cell!(0)
|
||||
@@ -1769,7 +1767,7 @@ mod tests {
|
||||
let printer = HCPrinter::new(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.atom_tbl,
|
||||
&wam.machine_st.stack,
|
||||
&mut wam.machine_st.stack,
|
||||
&wam.op_dir,
|
||||
PrinterOutputter::new(),
|
||||
heap_loc_as_cell!(0),
|
||||
@@ -1788,7 +1786,7 @@ mod tests {
|
||||
let printer = HCPrinter::new(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.atom_tbl,
|
||||
&wam.machine_st.stack,
|
||||
&mut wam.machine_st.stack,
|
||||
&wam.op_dir,
|
||||
PrinterOutputter::new(),
|
||||
heap_loc_as_cell!(0),
|
||||
@@ -1805,7 +1803,7 @@ mod tests {
|
||||
let mut printer = HCPrinter::new(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.atom_tbl,
|
||||
&wam.machine_st.stack,
|
||||
&mut wam.machine_st.stack,
|
||||
&wam.op_dir,
|
||||
PrinterOutputter::new(),
|
||||
heap_loc_as_cell!(0)
|
||||
@@ -1837,7 +1835,7 @@ mod tests {
|
||||
let mut printer = HCPrinter::new(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.atom_tbl,
|
||||
&wam.machine_st.stack,
|
||||
&mut wam.machine_st.stack,
|
||||
&wam.op_dir,
|
||||
PrinterOutputter::new(),
|
||||
heap_loc_as_cell!(0)
|
||||
@@ -1860,7 +1858,7 @@ mod tests {
|
||||
let printer = HCPrinter::new(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.atom_tbl,
|
||||
&wam.machine_st.stack,
|
||||
&mut wam.machine_st.stack,
|
||||
&wam.op_dir,
|
||||
PrinterOutputter::new(),
|
||||
pstr_loc_as_cell!(0)
|
||||
@@ -1888,7 +1886,7 @@ mod tests {
|
||||
let printer = HCPrinter::new(
|
||||
&mut wam.machine_st.heap,
|
||||
&mut wam.machine_st.atom_tbl,
|
||||
&wam.machine_st.stack,
|
||||
&mut wam.machine_st.stack,
|
||||
&wam.op_dir,
|
||||
PrinterOutputter::new(),
|
||||
heap_loc_as_cell!(0),
|
||||
|
||||
@@ -1106,7 +1106,7 @@ impl MachineState {
|
||||
|
||||
pub(crate) fn arith_eval_by_metacall(&mut self, value: HeapCellValue) -> Result<Number, MachineStub> {
|
||||
let stub_gen = || functor_stub(atom!("is"), 2);
|
||||
let mut iter = stackful_post_order_iter(&mut self.heap, value);
|
||||
let mut iter = stackful_post_order_iter(&mut self.heap, &mut self.stack, value);
|
||||
|
||||
while let Some(value) = iter.next() {
|
||||
if value.get_forwarding_bit() {
|
||||
|
||||
@@ -136,7 +136,7 @@ impl MachineState {
|
||||
let mut seen_set = IndexSet::new();
|
||||
let mut seen_vars = vec![];
|
||||
|
||||
let mut iter = stackful_preorder_iter(&mut self.heap, cell);
|
||||
let mut iter = stackful_preorder_iter(&mut self.heap, &mut self.stack, cell);
|
||||
|
||||
while let Some(value) = iter.next() {
|
||||
read_heap_cell!(value,
|
||||
@@ -147,7 +147,7 @@ impl MachineState {
|
||||
|
||||
let value = unmark_cell_bits!(value);
|
||||
|
||||
if h != iter.focus() {
|
||||
if h != iter.focus().value() as usize {
|
||||
let deref_value = heap_bound_store(iter.heap, heap_bound_deref(iter.heap, value));
|
||||
|
||||
if deref_value.is_compound(iter.heap) {
|
||||
@@ -167,7 +167,7 @@ impl MachineState {
|
||||
loop {
|
||||
read_heap_cell!(iter.heap[l],
|
||||
(HeapCellValueTag::Lis) => {
|
||||
iter.push_stack(l);
|
||||
iter.push_stack(IterStackLoc::iterable_loc(l, HeapOrStackTag::Heap));
|
||||
// l = elem + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ use crate::machine::heap::*;
|
||||
use crate::types::*;
|
||||
|
||||
#[cfg(test)]
|
||||
use crate::heap_iter::FocusedHeapIter;
|
||||
use crate::heap_iter::{IterStackLoc, FocusedHeapIter, HeapOrStackTag};
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
||||
@@ -75,8 +75,8 @@ pub(crate) struct StacklessPreOrderHeapIter<'a, UMP: UnmarkPolicy> {
|
||||
#[cfg(test)]
|
||||
impl<'a> FocusedHeapIter for StacklessPreOrderHeapIter<'a, IteratorUMP> {
|
||||
#[inline]
|
||||
fn focus(&self) -> usize {
|
||||
self.current
|
||||
fn focus(&self) -> IterStackLoc {
|
||||
IterStackLoc::iterable_loc(self.current, HeapOrStackTag::Heap)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -536,7 +536,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
let term_addr = machine_st[heap_term_loc];
|
||||
|
||||
let mut term_stack = vec![];
|
||||
let mut iter = stackful_post_order_iter(&mut machine_st.heap, term_addr);
|
||||
let mut iter = stackful_post_order_iter(&mut machine_st.heap, &mut machine_st.stack, term_addr);
|
||||
|
||||
while let Some(addr) = iter.next() {
|
||||
let addr = unmark_cell_bits!(addr);
|
||||
@@ -568,7 +568,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
term_stack.push(Term::Literal(Cell::default(), Literal::try_from(addr).unwrap()));
|
||||
}
|
||||
(HeapCellValueTag::Atom, (name, arity)) => {
|
||||
let h = iter.focus();
|
||||
let h = iter.focus().value() as usize;
|
||||
let mut arity = arity;
|
||||
|
||||
if iter.heap.len() > h + arity + 1 {
|
||||
|
||||
@@ -558,10 +558,10 @@ impl MachineState {
|
||||
|
||||
let mut singleton_var_set: IndexMap<Ref, bool> = IndexMap::new();
|
||||
|
||||
for addr in stackful_preorder_iter(&mut self.heap, term) {
|
||||
let addr = unmark_cell_bits!(addr);
|
||||
for cell in stackful_preorder_iter(&mut self.heap, &mut self.stack, term) {
|
||||
let cell = unmark_cell_bits!(cell);
|
||||
|
||||
if let Some(var) = addr.as_var() {
|
||||
if let Some(var) = cell.as_var() {
|
||||
if !singleton_var_set.contains_key(&var) {
|
||||
singleton_var_set.insert(var, true);
|
||||
} else {
|
||||
|
||||
@@ -1125,7 +1125,7 @@ impl MachineState {
|
||||
return false;
|
||||
}
|
||||
|
||||
let mut iter = stackful_preorder_iter(&mut self.heap, value);
|
||||
let mut iter = stackful_preorder_iter(&mut self.heap, &mut self.stack, value);
|
||||
|
||||
while let Some(value) = iter.next() {
|
||||
if value.get_forwarding_bit() {
|
||||
@@ -1626,7 +1626,7 @@ impl MachineState {
|
||||
return true;
|
||||
}
|
||||
|
||||
let mut iter = stackful_preorder_iter(&mut self.heap, value);
|
||||
let mut iter = stackful_preorder_iter(&mut self.heap, &mut self.stack, value);
|
||||
|
||||
while let Some(value) = iter.next() {
|
||||
let value = unmark_cell_bits!(value);
|
||||
|
||||
@@ -532,7 +532,7 @@ impl MachineState {
|
||||
seen_set: &mut IndexSet<HeapCellValue, S>,
|
||||
value: HeapCellValue,
|
||||
) {
|
||||
let mut iter = stackful_preorder_iter(&mut self.heap, value);
|
||||
let mut iter = stackful_preorder_iter(&mut self.heap, &mut self.stack, value);
|
||||
|
||||
while let Some(value) = iter.next() {
|
||||
let value = unmark_cell_bits!(value);
|
||||
@@ -722,7 +722,7 @@ impl MachineState {
|
||||
let mut seen_set = IndexSet::new();
|
||||
|
||||
{
|
||||
let mut iter = stackful_post_order_iter(&mut self.heap, term);
|
||||
let mut iter = stackful_post_order_iter(&mut self.heap, &mut self.stack, term);
|
||||
|
||||
while let Some(value) = iter.next() {
|
||||
if iter.parent_stack_len() >= max_depth {
|
||||
|
||||
@@ -651,10 +651,12 @@ fn bind_with_occurs_check<U: Unifier>(unifier: &mut U, r: Ref, value: HeapCellVa
|
||||
let mut occurs_triggered = false;
|
||||
|
||||
if !value.is_constant() {
|
||||
for addr in stackful_preorder_iter(&mut unifier.heap, value) {
|
||||
let addr = unmark_cell_bits!(addr);
|
||||
let machine_st: &mut MachineState = unifier.deref_mut();
|
||||
|
||||
if let Some(inner_r) = addr.as_var() {
|
||||
for cell in stackful_preorder_iter(&mut machine_st.heap, &mut machine_st.stack, value) {
|
||||
let cell = unmark_cell_bits!(cell);
|
||||
|
||||
if let Some(inner_r) = cell.as_var() {
|
||||
if r == inner_r {
|
||||
occurs_triggered = true;
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user