]> Repositorios git - scryer-prolog.git/commitdiff
streamline variable search in heap_print.rs
authorMark Thom <[email protected]>
Mon, 7 May 2018 04:10:51 +0000 (22:10 -0600)
committerMark Thom <[email protected]>
Mon, 7 May 2018 04:10:51 +0000 (22:10 -0600)
src/prolog/heap_print.rs
src/prolog/machine/machine_state_impl.rs

index e7f5ea48442d789864dee112c8a8d7cdfbc2dfd9..54e70ced8554992f87bea3aef21d28a307d9c27b 100644 (file)
@@ -2,9 +2,8 @@ use prolog::ast::*;
 use prolog::heap_iter::*;
 use prolog::machine::machine_state::MachineState;
 
-use std::borrow::Cow;
 use std::cell::Cell;
-use std::collections::HashSet;
+use std::collections::{HashMap, HashSet};
 use std::rc::Rc;
 
 #[derive(Clone)]
@@ -142,15 +141,25 @@ impl HCValueFormatter for TermFormatter {
     }
 }
 
+type ReverseHeapVarDict<'a> = HashMap<Addr, Rc<Var>>;
+
 pub struct HCPrinter<'a, Formatter, Outputter> {
     formatter:    Formatter,
     outputter:    Outputter,
     machine_st:   &'a MachineState,
     state_stack:  Vec<TokenOrRedirect>,
-    heap_locs:    Cow<'a, HeapVarDict>,
+    heap_locs:    ReverseHeapVarDict<'a>,
     printed_vars: HashSet<Addr>
 }
 
+fn reverse_heap_locs<'a>(machine_st: &'a MachineState, heap_locs: &'a HeapVarDict)
+                         -> ReverseHeapVarDict<'a>
+{
+    heap_locs.iter().map(|(var, var_addr)| {
+        (machine_st.store(machine_st.deref(var_addr.clone())), var.clone())
+    }).collect()
+}
+
 impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter>
     HCPrinter<'a, Formatter, Outputter>
 {
@@ -160,7 +169,7 @@ impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter>
                     outputter: output,
                     machine_st,
                     state_stack: vec![],
-                    heap_locs: Cow::default(),
+                    heap_locs: ReverseHeapVarDict::new(),
                     printed_vars: HashSet::new() }
     }
 
@@ -170,21 +179,7 @@ impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter>
     {
         let mut printer = Self::new(machine_st, fmt, output);
 
-        printer.heap_locs = Cow::Borrowed(heap_locs);
-        printer
-    }
-
-    pub fn from_heap_locs_as_seen(machine_st: &'a MachineState, fmt: Formatter,
-                                  output: Outputter, heap_locs: &'a HeapVarDict)
-                                  -> Self
-    {
-        let mut printer = Self::from_heap_locs(machine_st, fmt, output, heap_locs);
-
-        for (_, addr) in heap_locs.iter() {
-            let addr = machine_st.store(machine_st.deref(addr.clone()));
-            printer.printed_vars.insert(addr.clone());
-        }
-
+        printer.heap_locs = reverse_heap_locs(machine_st, heap_locs);
         printer
     }
 
@@ -198,37 +193,33 @@ impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter>
         }
     }
 
-    // returns a HeapCellValue iff the next element to come hasn't been seen previously.
     fn check_for_seen(&mut self, iter: &mut HCPreOrderIterator) -> Option<HeapCellValue> {
         iter.stack().last().cloned().and_then(|addr| {
             let addr = self.machine_st.store(self.machine_st.deref(addr));
 
-            for (var, var_addr) in self.heap_locs.iter() {
-                if &addr == &self.machine_st.store(self.machine_st.deref(var_addr.clone())) {
-                    if !self.printed_vars.contains(&addr) {
-                        self.printed_vars.insert(addr);
-                        return iter.next();
-                    } else {
+            match self.heap_locs.get(&addr).cloned() {
+                Some(var) => if !self.printed_vars.contains(&addr) {
+                    self.printed_vars.insert(addr);
+                    return iter.next();
+                } else {
+                    iter.stack().pop();
+                    self.outputter.append(var.as_str());
+
+                    return None;
+                },
+                None => if self.machine_st.is_cyclic_term(addr.clone()) {
+                    if self.printed_vars.contains(&addr) {
                         iter.stack().pop();
-                        self.outputter.append(var.as_str());
+                        self.print_offset(addr);
 
-                        return None;
+                        None
+                    } else {
+                        self.printed_vars.insert(addr);
+                        iter.next()
                     }
-                }
-            }
-
-            if self.machine_st.is_cyclic_term(addr.clone()) {
-                if self.printed_vars.contains(&addr) {
-                    iter.stack().pop();
-                    self.print_offset(addr);
-                    
-                    None
                 } else {
-                    self.printed_vars.insert(addr);
                     iter.next()
                 }
-            } else {
-                iter.next()
             }
         })
     }
@@ -279,8 +270,6 @@ impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter>
         }
     }
 
-    //TODO: idea: hand a mutable ref to iter to handle_heap_term,
-    // and have it query the stack before getting the next thing.
     pub fn print(mut self, addr: Addr) -> Outputter {
         let mut iter = HCPreOrderIterator::new(&self.machine_st, addr);
 
index 2392741d47ec19f68641643fb89ca9c9af74fbef..940d0a926ed0f7160fea848ad5762053dbcc6e18 100644 (file)
@@ -122,7 +122,7 @@ impl MachineState {
                                        -> Outputter
       where Fmt: HCValueFormatter, Outputter: HCValueOutputter
     {
-        let printer = HCPrinter::from_heap_locs_as_seen(&self, fmt, output, var_dir);
+        let printer = HCPrinter::from_heap_locs(&self, fmt, output, var_dir);
         printer.print(addr)
     }