implement ListElisionPolicy to restore previous printer behavior

This commit is contained in:
Mark
2023-09-30 16:00:15 -06:00
parent 25afc11168
commit 62c23166fa
9 changed files with 134 additions and 98 deletions

View File

@@ -6,6 +6,7 @@ use crate::machine::heap::*;
use crate::machine::stack::*;
use crate::types::*;
use core::marker::PhantomData;
use modular_bitfield::prelude::*;
use std::ops::Deref;
@@ -79,15 +80,40 @@ impl IterStackLoc {
}
}
pub trait ListElisionPolicy {
fn elide_lists() -> bool;
}
#[derive(Debug)]
pub struct StackfulPreOrderHeapIter<'a> {
pub struct ListElider {}
impl ListElisionPolicy for ListElider {
#[inline(always)]
fn elide_lists() -> bool {
true
}
}
#[derive(Debug)]
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);
@@ -104,59 +130,14 @@ pub trait FocusedHeapIter: Iterator<Item = HeapCellValue> {
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() {
@@ -173,6 +154,11 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
}
}
#[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() {
@@ -228,6 +214,51 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
));
}
}
}
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() {
@@ -330,7 +361,7 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
}
}
impl<'a> Iterator for StackfulPreOrderHeapIter<'a> {
impl<'a, ElideLists: ListElisionPolicy> Iterator for StackfulPreOrderHeapIter<'a, ElideLists> {
type Item = HeapCellValue;
#[inline]
@@ -349,11 +380,11 @@ pub(crate) fn stackless_preorder_iter(
}
#[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)
}
@@ -460,9 +491,10 @@ impl<Iter: FocusedHeapIter> PostOrderIterator<Iter> {
}
}
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() {
@@ -481,11 +513,11 @@ impl<'a> LeftistPostOrderHeapIter<'a> {
}
#[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))
}
@@ -1555,7 +1587,7 @@ mod tests {
.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),
@@ -1590,7 +1622,7 @@ mod tests {
));
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),
@@ -1622,7 +1654,7 @@ mod tests {
{
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),
@@ -1649,7 +1681,7 @@ 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(
let mut iter = StackfulPreOrderHeapIter::<NonListElider>::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
@@ -1673,7 +1705,7 @@ mod tests {
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),
@@ -1709,7 +1741,7 @@ mod tests {
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),
@@ -1741,7 +1773,7 @@ mod tests {
}
{
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),
@@ -1780,7 +1812,7 @@ mod tests {
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),
@@ -1805,7 +1837,7 @@ mod tests {
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),
@@ -1832,7 +1864,7 @@ mod tests {
.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),
@@ -1867,7 +1899,7 @@ mod tests {
.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),
@@ -1911,7 +1943,7 @@ mod tests {
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),
@@ -1974,7 +2006,7 @@ mod tests {
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),
@@ -2043,7 +2075,7 @@ mod tests {
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),
@@ -2079,7 +2111,7 @@ mod tests {
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),
@@ -2111,7 +2143,7 @@ mod tests {
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),
@@ -2149,7 +2181,7 @@ mod tests {
.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),
@@ -2185,7 +2217,7 @@ mod tests {
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),
@@ -2219,7 +2251,7 @@ mod tests {
{
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),
@@ -2246,7 +2278,7 @@ 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(
let mut iter = stackful_post_order_iter::<NonListElider>(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
@@ -2270,7 +2302,7 @@ mod tests {
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),
@@ -2306,7 +2338,7 @@ mod tests {
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),
@@ -2338,7 +2370,7 @@ mod tests {
}
{
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),
@@ -2377,7 +2409,7 @@ mod tests {
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),
@@ -2401,7 +2433,7 @@ 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(
let mut iter = stackful_post_order_iter::<NonListElider>(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
pstr_loc_as_cell!(0),
@@ -2428,7 +2460,7 @@ mod tests {
.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),
@@ -2455,7 +2487,7 @@ mod tests {
.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),
@@ -2489,7 +2521,7 @@ mod tests {
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),
@@ -2553,7 +2585,7 @@ mod tests {
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),

View File

@@ -104,7 +104,7 @@ fn needs_bracketing(child_desc: OpDesc, op: &DirectedOp) -> bool {
}
}
impl<'a> StackfulPreOrderHeapIter<'a> {
impl<'a, ElideLists> StackfulPreOrderHeapIter<'a, ElideLists> {
/*
* descend into the subtree where the iterator is currently parked
* and check that the leftmost leaf is a number, with every node
@@ -407,7 +407,7 @@ fn is_numbered_var(name: Atom, arity: usize) -> bool {
#[inline]
fn negated_op_needs_bracketing(
iter: &StackfulPreOrderHeapIter,
iter: &StackfulPreOrderHeapIter<ListElider>,
op_dir: &OpDir,
op: &Option<DirectedOp>,
) -> bool {
@@ -491,7 +491,7 @@ pub fn fmt_float(mut fl: f64) -> String {
#[derive(Debug)]
pub struct HCPrinter<'a, Outputter> {
outputter: Outputter,
iter: StackfulPreOrderHeapIter<'a>,
iter: StackfulPreOrderHeapIter<'a, ListElider>,
atom_tbl: Arc<AtomTable>,
op_dir: &'a OpDir,
state_stack: Vec<TokenOrRedirect>,

View File

@@ -1208,7 +1208,8 @@ impl MachineState {
value: HeapCellValue,
) -> Result<Number, MachineStub> {
let stub_gen = || functor_stub(atom!("is"), 2);
let mut iter = stackful_post_order_iter(&mut self.heap, &mut self.stack, value);
let mut iter = stackful_post_order_iter::<NonListElider>
(&mut self.heap, &mut self.stack, value);
while let Some(value) = iter.next() {
if value.get_forwarding_bit() {

View File

@@ -133,7 +133,8 @@ impl MachineState {
let mut seen_set = IndexSet::new();
let mut seen_vars = vec![];
let mut iter = stackful_preorder_iter(&mut self.heap, &mut self.stack, cell);
let mut iter = stackful_preorder_iter::<NonListElider>
(&mut self.heap, &mut self.stack, cell);
while let Some(value) = iter.next() {
read_heap_cell!(value,

View File

@@ -1418,7 +1418,8 @@ impl MachineState {
term_addr: HeapCellValue,
) -> Term {
let mut term_stack = vec![];
let mut iter = stackful_post_order_iter(&mut self.heap, &mut self.stack, term_addr);
let mut iter = stackful_post_order_iter::<NonListElider>
(&mut self.heap, &mut self.stack, term_addr);
while let Some(addr) = iter.next() {
let addr = unmark_cell_bits!(addr);

View File

@@ -588,7 +588,7 @@ impl MachineState {
let mut singleton_var_set: IndexMap<Ref, bool> = IndexMap::new();
for cell in stackful_preorder_iter(&mut self.heap, &mut self.stack, heap_loc) {
for cell in stackful_preorder_iter::<NonListElider>(&mut self.heap, &mut self.stack, heap_loc) {
let cell = unmark_cell_bits!(cell);
if let Some(var) = cell.as_var() {

View File

@@ -1135,7 +1135,8 @@ impl MachineState {
return false;
}
let mut iter = stackful_preorder_iter(&mut self.heap, &mut self.stack, value);
let mut iter = stackful_preorder_iter::<NonListElider>
(&mut self.heap, &mut self.stack, value);
while let Some(value) = iter.next() {
if value.get_forwarding_bit() {
@@ -1633,7 +1634,7 @@ impl MachineState {
}
let mut visited = IndexSet::with_hasher(FxBuildHasher::default());
let mut iter = stackful_preorder_iter(&mut self.heap, &mut self.stack, value);
let mut iter = stackful_preorder_iter::<NonListElider>(&mut self.heap, &mut self.stack, value);
let mut stack_len = 0;
while let Some(value) = iter.next() {

View File

@@ -583,7 +583,7 @@ impl MachineState {
seen_set: &mut IndexSet<HeapCellValue, S>,
value: HeapCellValue,
) {
let mut iter = stackful_preorder_iter(&mut self.heap, &mut self.stack, value);
let mut iter = stackful_preorder_iter::<NonListElider>(&mut self.heap, &mut self.stack, value);
while let Some(value) = iter.next() {
let value = unmark_cell_bits!(value);
@@ -793,7 +793,7 @@ impl MachineState {
let mut seen_set = IndexSet::new();
{
let mut iter = stackful_post_order_iter(&mut self.heap, &mut self.stack, term);
let mut iter = stackful_post_order_iter::<NonListElider>(&mut self.heap, &mut self.stack, term);
while let Some(value) = iter.next() {
if iter.parent_stack_len() >= max_depth {

View File

@@ -1,6 +1,6 @@
use crate::arena::*;
use crate::forms::*;
use crate::heap_iter::stackful_preorder_iter;
use crate::heap_iter::{NonListElider, stackful_preorder_iter};
use crate::machine::machine_state::*;
use crate::machine::partial_string::*;
use crate::machine::*;
@@ -717,7 +717,7 @@ fn bind_with_occurs_check<U: Unifier>(unifier: &mut U, r: Ref, value: HeapCellVa
if !value.is_constant() {
let machine_st: &mut MachineState = unifier.deref_mut();
for cell in stackful_preorder_iter(&mut machine_st.heap, &mut machine_st.stack, value) {
for cell in stackful_preorder_iter::<NonListElider>(&mut machine_st.heap, &mut machine_st.stack, value) {
let cell = unmark_cell_bits!(cell);
if let Some(inner_r) = cell.as_var() {