#[cfg(test)]
pub(crate) use crate::machine::gc::{IteratorUMP, StacklessPreOrderHeapIter};
-use crate::machine::heap::*;
use crate::atom_table::*;
+use crate::machine::heap::*;
+use crate::machine::stack::*;
use crate::types::*;
use modular_bitfield::prelude::*;
#[derive(Debug)]
pub struct StackfulPreOrderHeapIter<'a> {
pub heap: &'a mut Vec<HeapCellValue>,
+ machine_stack: Option<&'a Stack>,
stack: Vec<IterStackLoc>,
h: usize,
}
Self {
heap,
h,
+ machine_stack: None,
stack: vec![IterStackLoc::iterable_heap_loc(h)],
}
}
+ pub fn iterate_over_machine_stack(&mut self, stack: &'a Stack) {
+ self.machine_stack = Some(stack);
+ }
+
#[inline]
pub fn push_stack(&mut self, h: usize) {
self.stack.push(IterStackLoc::iterable_heap_loc(h));
}
}
+ 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() {
continue;
}
- read_heap_cell!(*cell,
+ 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,
(HeapCellValueTag::Str | HeapCellValueTag::PStrLoc, vh) => {
self.push_if_unmarked(vh);
self.stack.push(IterStackLoc::mark_heap_loc(vh));
return Some(self.heap[h]);
}
_ => {
- return Some(*cell);
+ return Some(cell);
}
)
}
use crate::machine::machine_indices::*;
use crate::machine::machine_state::pstr_loc_and_offset;
use crate::machine::partial_string::*;
+use crate::machine::stack::*;
use crate::machine::streams::*;
use crate::types::*;
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>,
pub fn new(
heap: &'a mut Heap,
atom_tbl: &'a mut AtomTable,
+ stack: &'a Stack,
op_dir: &'a OpDir,
output: Outputter,
cell: HeapCellValue,
outputter: output,
iter: stackful_preorder_iter(heap, cell),
atom_tbl,
+ stack,
op_dir,
state_stack: vec![],
toplevel_spec: None,
) {
let negated_operand = negated_op_needs_bracketing(&self.iter, self.op_dir, &op);
- let addr = match self.check_for_seen() {
- Some(addr) => addr,
- None => return,
- };
-
- let print_atom = |printer: &mut Self, name: Atom, arity: usize| {
+ let print_struct = |printer: &mut Self, name: Atom, arity: usize| {
if name == atom!("[]") && arity == 0 {
if !printer.at_cdr("") {
append_str!(printer, "[]");
}
};
+ let addr = match self.check_for_seen() {
+ Some(addr) => addr,
+ None => return,
+ };
+
read_heap_cell!(addr,
(HeapCellValueTag::Atom, (name, arity)) => {
- print_atom(self, name, arity);
+ print_struct(self, name, arity);
}
(HeapCellValueTag::Char, c) => {
let name = self.atom_tbl.build_with(&String::from(c));
- print_atom(self, name, 0);
- // print_char!(self, self.quoted, c);
+ print_struct(self, name, 0);
}
(HeapCellValueTag::Str, s) => {
let (name, arity) = cell_as_atom_cell!(self.iter.heap[s])
.get_name_and_arity();
if let Some(spec) = fetch_op_spec(name, arity, self.op_dir) {
- self.handle_op_as_struct(
- name,
- arity,
- &op,
- is_functor_redirect,
- spec,
- negated_operand,
- max_depth,
- );
+ self.handle_op_as_struct(
+ name,
+ arity,
+ &op,
+ is_functor_redirect,
+ spec,
+ negated_operand,
+ max_depth,
+ );
} else {
push_space_if_amb!(self, name.as_str(), {
self.format_clause(max_depth, arity, name, None);
}
(HeapCellValueTag::Cons, c) => {
match_untyped_arena_ptr!(c,
- (ArenaHeaderTag::Integer, n) => {
- self.print_number(max_depth, NumberFocus::Unfocused(Number::Integer(n)), &op);
- }
- (ArenaHeaderTag::Rational, r) => {
- self.print_number(max_depth, NumberFocus::Unfocused(Number::Rational(r)), &op);
- }
- (ArenaHeaderTag::Stream, stream) => {
- self.print_stream(stream, max_depth);
- }
- (ArenaHeaderTag::OssifiedOpDir, _op_dir) => {
- self.print_impromptu_atom(atom!("$ossified_op_dir"));
- }
- (ArenaHeaderTag::Dropped, _value) => {
- self.print_impromptu_atom(atom!("$dropped_value"));
- }
- (ArenaHeaderTag::IndexPtr, index_ptr) => {
- self.print_index_ptr(*index_ptr, max_depth);
- }
- _ => {
- }
- );
+ (ArenaHeaderTag::Integer, n) => {
+ self.print_number(max_depth, NumberFocus::Unfocused(Number::Integer(n)), &op);
+ }
+ (ArenaHeaderTag::Rational, r) => {
+ self.print_number(max_depth, NumberFocus::Unfocused(Number::Rational(r)), &op);
+ }
+ (ArenaHeaderTag::Stream, stream) => {
+ self.print_stream(stream, max_depth);
+ }
+ (ArenaHeaderTag::OssifiedOpDir, _op_dir) => {
+ self.print_impromptu_atom(atom!("$ossified_op_dir"));
+ }
+ (ArenaHeaderTag::Dropped, _value) => {
+ self.print_impromptu_atom(atom!("$dropped_value"));
+ }
+ (ArenaHeaderTag::IndexPtr, index_ptr) => {
+ self.print_index_ptr(*index_ptr, max_depth);
+ }
+ _ => {
+ }
+ );
}
_ => {
unreachable!()
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() {
let printer = HCPrinter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.atom_tbl,
+ &wam.machine_st.stack,
&wam.op_dir,
PrinterOutputter::new(),
heap_loc_as_cell!(0)
let printer = HCPrinter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.atom_tbl,
+ &wam.machine_st.stack,
&wam.op_dir,
PrinterOutputter::new(),
heap_loc_as_cell!(0)
let printer = HCPrinter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.atom_tbl,
+ &wam.machine_st.stack,
&wam.op_dir,
PrinterOutputter::new(),
heap_loc_as_cell!(0)
let mut printer = HCPrinter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.atom_tbl,
+ &wam.machine_st.stack,
&wam.op_dir,
PrinterOutputter::new(),
heap_loc_as_cell!(0)
let printer = HCPrinter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.atom_tbl,
+ &wam.machine_st.stack,
&wam.op_dir,
PrinterOutputter::new(),
heap_loc_as_cell!(0),
let printer = HCPrinter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.atom_tbl,
+ &wam.machine_st.stack,
&wam.op_dir,
PrinterOutputter::new(),
heap_loc_as_cell!(0),
let mut printer = HCPrinter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.atom_tbl,
+ &wam.machine_st.stack,
&wam.op_dir,
PrinterOutputter::new(),
heap_loc_as_cell!(0)
let mut printer = HCPrinter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.atom_tbl,
+ &wam.machine_st.stack,
&wam.op_dir,
PrinterOutputter::new(),
heap_loc_as_cell!(0)
let printer = HCPrinter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.atom_tbl,
+ &wam.machine_st.stack,
&wam.op_dir,
PrinterOutputter::new(),
pstr_loc_as_cell!(0)
let printer = HCPrinter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.atom_tbl,
+ &wam.machine_st.stack,
&wam.op_dir,
PrinterOutputter::new(),
heap_loc_as_cell!(0),