use crate::machine::stack::*;
use crate::types::*;
+use core::marker::PhantomData;
use modular_bitfield::prelude::*;
use std::ops::Deref;
}
}
+pub trait ListElisionPolicy {
+ fn elide_lists() -> bool;
+}
+
+#[derive(Debug)]
+pub struct ListElider {}
+
+impl ListElisionPolicy for ListElider {
+ #[inline(always)]
+ fn elide_lists() -> bool {
+ true
+ }
+}
+
#[derive(Debug)]
-pub struct StackfulPreOrderHeapIter<'a> {
+pub struct NonListElider {}
+
+impl ListElisionPolicy for NonListElider {
+ #[inline(always)]
+ fn elide_lists() -> bool {
+ false
+ }
+}
+
+#[derive(Debug)]
+pub struct StackfulPreOrderHeapIter<'a, ElideLists> {
pub heap: &'a mut Vec<HeapCellValue>,
pub machine_stack: &'a mut Stack,
stack: Vec<IterStackLoc>,
h: IterStackLoc,
+ _marker: PhantomData<ElideLists>,
}
-impl<'a> Drop for StackfulPreOrderHeapIter<'a> {
+impl<'a, ElideLists> Drop for StackfulPreOrderHeapIter<'a, ElideLists> {
fn drop(&mut self) {
while let Some(h) = self.stack.pop() {
let cell = self.read_cell_mut(h);
fn focus(&self) -> IterStackLoc;
}
-impl<'a> FocusedHeapIter for StackfulPreOrderHeapIter<'a> {
+impl<'a, ElideLists: ListElisionPolicy> FocusedHeapIter for StackfulPreOrderHeapIter<'a, ElideLists> {
#[inline]
fn focus(&self) -> IterStackLoc {
self.h
}
}
-impl<'a> StackfulPreOrderHeapIter<'a> {
- #[inline]
- 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: stack,
- stack: vec![h],
- }
- }
-
- #[inline]
- fn forward_if_referent_marked(&mut self, loc: IterStackLoc) {
- let cell = self.read_cell(loc);
-
- read_heap_cell!(cell,
- (HeapCellValueTag::Lis, vh) => {
- if cell.get_mark_bit() && self.heap[vh].get_mark_bit() {
- self.read_cell_mut(loc).set_forwarding_bit(true);
- }
- }
- (HeapCellValueTag::Str |
- 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: IterStackLoc) {
- self.stack.push(h);
- }
-
+impl<'a, ElideLists> StackfulPreOrderHeapIter<'a, ElideLists> {
#[inline]
pub fn read_cell_mut(&mut self, loc: IterStackLoc) -> &mut HeapCellValue {
match loc.heap_or_stack() {
}
}
+ #[inline]
+ pub fn push_stack(&mut self, h: IterStackLoc) {
+ self.stack.push(h);
+ }
+
#[inline]
pub fn stack_last(&self) -> Option<IterStackLoc> {
for h in self.stack.iter().rev() {
));
}
}
+}
+
+impl<'a, ElideLists: ListElisionPolicy> StackfulPreOrderHeapIter<'a, ElideLists> {
+ #[inline]
+ 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: stack,
+ stack: vec![h],
+ _marker: PhantomData,
+ }
+ }
+
+ #[inline]
+ fn forward_if_referent_marked(&mut self, loc: IterStackLoc) {
+ let cell = self.read_cell(loc);
+
+ read_heap_cell!(cell,
+ (HeapCellValueTag::Lis, vh) => {
+ let forward = if ElideLists::elide_lists() { true } else { cell.get_mark_bit() };
+
+ if forward && self.heap[vh].get_mark_bit() {
+ self.read_cell_mut(loc).set_forwarding_bit(true);
+ }
+ }
+ (HeapCellValueTag::Str |
+ 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);
+ }
+ }
+ _ => {}
+ );
+ }
fn follow(&mut self) -> Option<HeapCellValue> {
while let Some(h) = self.stack.pop() {
}
}
-impl<'a> Iterator for StackfulPreOrderHeapIter<'a> {
+impl<'a, ElideLists: ListElisionPolicy> Iterator for StackfulPreOrderHeapIter<'a, ElideLists> {
type Item = HeapCellValue;
#[inline]
}
#[inline(always)]
-pub(crate) fn stackful_preorder_iter<'a>(
+pub(crate) fn stackful_preorder_iter<'a, ElideLists: ListElisionPolicy>(
heap: &'a mut Vec<HeapCellValue>,
stack: &'a mut Stack,
cell: HeapCellValue,
-) -> StackfulPreOrderHeapIter<'a> {
+) -> StackfulPreOrderHeapIter<'a, ElideLists> {
StackfulPreOrderHeapIter::new(heap, stack, cell)
}
}
}
-pub(crate) type LeftistPostOrderHeapIter<'a> = PostOrderIterator<StackfulPreOrderHeapIter<'a>>;
+pub(crate) type LeftistPostOrderHeapIter<'a, ElideLists> =
+ PostOrderIterator<StackfulPreOrderHeapIter<'a, ElideLists>>;
-impl<'a> LeftistPostOrderHeapIter<'a> {
+impl<'a, ElideLists: ListElisionPolicy> LeftistPostOrderHeapIter<'a, ElideLists> {
#[inline]
pub fn pop_stack(&mut self) {
if let Some((child_count, ..)) = self.parent_stack.last() {
}
#[inline]
-pub(crate) fn stackful_post_order_iter<'a>(
+pub(crate) fn stackful_post_order_iter<'a, ElideLists: ListElisionPolicy>(
heap: &'a mut Heap,
stack: &'a mut Stack,
cell: HeapCellValue,
-) -> LeftistPostOrderHeapIter<'a> {
+) -> LeftistPostOrderHeapIter<'a, ElideLists> {
PostOrderIterator::new(StackfulPreOrderHeapIter::new(heap, stack, cell))
}
.extend(functor!(f_atom, [atom(a_atom), atom(b_atom)]));
{
- let mut iter = StackfulPreOrderHeapIter::new(
+ let mut iter = StackfulPreOrderHeapIter::<NonListElider>::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
str_loc_as_cell!(0),
));
for _ in 0..20 {
- let mut iter = StackfulPreOrderHeapIter::new(
+ let mut iter = StackfulPreOrderHeapIter::<NonListElider>::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
str_loc_as_cell!(0),
{
wam.machine_st.heap.push(heap_loc_as_cell!(0));
- let mut iter = StackfulPreOrderHeapIter::new(
+ let mut iter = StackfulPreOrderHeapIter::<NonListElider>::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
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(
+ let mut iter = StackfulPreOrderHeapIter::<NonListElider>::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
wam.machine_st.heap.push(empty_list_as_cell!());
{
- let mut iter = StackfulPreOrderHeapIter::new(
+ let mut iter = StackfulPreOrderHeapIter::<NonListElider>::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
wam.machine_st.heap.push(heap_loc_as_cell!(0));
{
- let mut iter = StackfulPreOrderHeapIter::new(
+ let mut iter = StackfulPreOrderHeapIter::<NonListElider>::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
}
{
- let mut iter = StackfulPreOrderHeapIter::new(
+ let mut iter = StackfulPreOrderHeapIter::<NonListElider>::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
{
- let mut iter = StackfulPreOrderHeapIter::new(
+ let mut iter = StackfulPreOrderHeapIter::<NonListElider>::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize];
{
- let mut iter = stackful_preorder_iter(
+ let mut iter = stackful_preorder_iter::<NonListElider>(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
.push(fixnum_as_cell!(Fixnum::build_with(0i64)));
{
- let mut iter = stackful_preorder_iter(
+ let mut iter = stackful_preorder_iter::<NonListElider>(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
pstr_loc_as_cell!(0),
.push(fixnum_as_cell!(Fixnum::build_with(1i64)));
{
- let mut iter = stackful_preorder_iter(
+ let mut iter = stackful_preorder_iter::<NonListElider>(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
pstr_loc_as_cell!(0),
wam.machine_st.heap.extend(functor);
{
- let mut iter = StackfulPreOrderHeapIter::new(
+ let mut iter = StackfulPreOrderHeapIter::<NonListElider>::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
wam.machine_st.heap[4] = list_loc_as_cell!(1);
{
- let mut iter = stackful_preorder_iter(
+ let mut iter = stackful_preorder_iter::<NonListElider>(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
wam.machine_st.heap.push(list_loc_as_cell!(1));
{
- let mut iter = StackfulPreOrderHeapIter::new(
+ let mut iter = StackfulPreOrderHeapIter::<NonListElider>::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
wam.machine_st.heap.push(empty_list_as_cell!());
{
- let mut iter = stackful_preorder_iter(
+ let mut iter = stackful_preorder_iter::<NonListElider>(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
wam.machine_st.heap.push(empty_list_as_cell!());
{
- let mut iter = stackful_preorder_iter(
+ let mut iter = stackful_preorder_iter::<NonListElider>(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
.extend(functor!(f_atom, [atom(a_atom), atom(b_atom)]));
{
- let mut iter = stackful_post_order_iter(
+ let mut iter = stackful_post_order_iter::<NonListElider>(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
str_loc_as_cell!(0),
for _ in 0..20 {
// 0000 {
- let mut iter = stackful_post_order_iter(
+ let mut iter = stackful_post_order_iter::<NonListElider>(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
str_loc_as_cell!(0),
{
wam.machine_st.heap.push(heap_loc_as_cell!(0));
- let mut iter = stackful_post_order_iter(
+ let mut iter = stackful_post_order_iter::<NonListElider>(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
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(
+ let mut iter = stackful_post_order_iter::<NonListElider>(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
wam.machine_st.heap.push(empty_list_as_cell!());
{
- let mut iter = stackful_post_order_iter(
+ let mut iter = stackful_post_order_iter::<NonListElider>(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
wam.machine_st.heap.push(heap_loc_as_cell!(0));
{
- let mut iter = stackful_post_order_iter(
+ let mut iter = stackful_post_order_iter::<NonListElider>(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
}
{
- let mut iter = stackful_post_order_iter(
+ let mut iter = stackful_post_order_iter::<NonListElider>(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
{
- let mut iter = stackful_post_order_iter(
+ let mut iter = stackful_post_order_iter::<NonListElider>(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
pstr_loc_as_cell!(0),
let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize];
{
- let mut iter = stackful_post_order_iter(
+ let mut iter = stackful_post_order_iter::<NonListElider>(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
pstr_loc_as_cell!(0),
.push(fixnum_as_cell!(Fixnum::build_with(0i64)));
{
- let mut iter = stackful_post_order_iter(
+ let mut iter = stackful_post_order_iter::<NonListElider>(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
pstr_loc_as_cell!(0),
.push(fixnum_as_cell!(Fixnum::build_with(1i64)));
{
- let mut iter = stackful_post_order_iter(
+ let mut iter = stackful_post_order_iter::<NonListElider>(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
pstr_loc_as_cell!(0),
wam.machine_st.heap.extend(functor);
{
- let mut iter = stackful_post_order_iter(
+ let mut iter = stackful_post_order_iter::<NonListElider>(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
wam.machine_st.heap[4] = list_loc_as_cell!(1);
{
- let mut iter = stackful_post_order_iter(
+ let mut iter = stackful_post_order_iter::<NonListElider>(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),