]> Repositorios git - scryer-prolog.git/commitdiff
optionally read from machine stack in stackful pre-order iterator (#1812)
authorMark <[email protected]>
Fri, 26 May 2023 21:19:07 +0000 (15:19 -0600)
committerMark <[email protected]>
Fri, 26 May 2023 21:19:07 +0000 (15:19 -0600)
src/heap_iter.rs
src/heap_print.rs
src/machine/machine_state.rs
src/machine/mock_wam.rs

index 9760be9ea75dc406fbb5e2a341cd374cf0de99f8..e957225ca0a82e3e2ecb140b78f5176963c9e3f8 100644 (file)
@@ -1,8 +1,9 @@
 #[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::*;
@@ -72,6 +73,7 @@ fn forward_if_referent_marked(heap: &mut [HeapCellValue], h: usize) {
 #[derive(Debug)]
 pub struct StackfulPreOrderHeapIter<'a> {
     pub heap: &'a mut Vec<HeapCellValue>,
+    machine_stack: Option<&'a Stack>,
     stack: Vec<IterStackLoc>,
     h: usize,
 }
@@ -109,10 +111,15 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
         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));
@@ -166,6 +173,26 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
         }
     }
 
+    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() {
@@ -193,7 +220,14 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
                 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));
@@ -241,7 +275,7 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
                    return Some(self.heap[h]);
                }
                _ => {
-                   return Some(*cell);
+                   return Some(cell);
                }
             )
         }
index 61477b1a29cdc8fa60a8f7acc204e04609f0f4fa..c0ea5fa3abcec79f45ae965ded33615f44209327 100644 (file)
@@ -14,6 +14,7 @@ use crate::machine::heap::*;
 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::*;
 
@@ -474,6 +475,7 @@ 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>,
@@ -539,6 +541,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
     pub fn new(
         heap: &'a mut Heap,
         atom_tbl: &'a mut AtomTable,
+        stack: &'a Stack,
         op_dir: &'a OpDir,
         output: Outputter,
         cell: HeapCellValue,
@@ -547,6 +550,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
             outputter: output,
             iter: stackful_preorder_iter(heap, cell),
             atom_tbl,
+            stack,
             op_dir,
             state_stack: vec![],
             toplevel_spec: None,
@@ -1441,12 +1445,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
     ) {
         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, "[]");
@@ -1494,29 +1493,33 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
             }
         };
 
+        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);
@@ -1551,27 +1554,27 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
             }
             (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!()
@@ -1594,6 +1597,8 @@ 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() {
@@ -1665,6 +1670,7 @@ mod tests {
             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)
@@ -1693,6 +1699,7 @@ mod tests {
             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)
@@ -1716,6 +1723,7 @@ mod tests {
             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)
@@ -1728,6 +1736,7 @@ mod tests {
             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)
@@ -1760,6 +1769,7 @@ mod tests {
             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),
@@ -1778,6 +1788,7 @@ mod tests {
             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),
@@ -1794,6 +1805,7 @@ mod tests {
             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)
@@ -1825,6 +1837,7 @@ mod tests {
             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)
@@ -1847,6 +1860,7 @@ mod tests {
             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)
@@ -1874,6 +1888,7 @@ mod tests {
             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),
index e489742a919b23bde229aa77c9eade93034cf891..6deab8d10923542a5df55c86d2bdf5d5a783f1f6 100644 (file)
@@ -766,6 +766,7 @@ impl MachineState {
                 let mut printer = HCPrinter::new(
                     &mut self.heap,
                     &mut self.atom_tbl,
+                    &mut self.stack,
                     op_dir,
                     PrinterOutputter::new(),
                     term_to_be_printed,
index 2ddde1291c2095b2b1c7b07c87d0e1e1edbe1a05..f71f32e32321545336de674819a9e6806ec74064 100644 (file)
@@ -62,6 +62,7 @@ impl MockWAM {
         let mut printer = HCPrinter::new(
             &mut self.machine_st.heap,
             &mut self.machine_st.atom_tbl,
+            &mut self.machine_st.stack,
             &self.op_dir,
             PrinterOutputter::new(),
             heap_loc_as_cell!(term_write_result.heap_loc),