]> Repositorios git - scryer-prolog.git/commitdiff
prepare to add bracketing conditions to heap_print
authorMark Thom <[email protected]>
Mon, 21 Jan 2019 06:56:15 +0000 (23:56 -0700)
committerMark Thom <[email protected]>
Mon, 21 Jan 2019 06:56:15 +0000 (23:56 -0700)
Cargo.lock
Cargo.toml
src/prolog/heap_iter.rs
src/prolog/heap_print.rs
src/prolog/instructions.rs

index 4db77776db064b875e7c3d868e3ab6f0b32e6128..03097f24cb3cf001e5ccac0b8e29a5940b736a20 100644 (file)
@@ -86,7 +86,7 @@ dependencies = [
 
 [[package]]
 name = "prolog_parser"
-version = "0.7.20"
+version = "0.7.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -113,7 +113,7 @@ dependencies = [
  "downcast 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "prolog_parser 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)",
+ "prolog_parser 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
  "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -152,7 +152,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070"
 "checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe"
 "checksum ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "58d25b6c0e47b20d05226d288ff434940296e7e2f8b877975da32f862152241f"
-"checksum prolog_parser 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)" = "68e88532e8eb09eb4606d47a53e0849643292bc253f14cb80b348f13591a050e"
+"checksum prolog_parser 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "b9b3862488cfa064334bb19f79578384ef0558f9f6462679cfb500291bf8980d"
 "checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0"
 "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
 "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
index 29bde88d23c884fcde672c4ae06db2b72fac740c..94c6126bda00c59af486390d8fc2a7f4dda311e8 100644 (file)
@@ -10,7 +10,7 @@ license = "BSD-3-Clause"
 downcast = "0.9.1"
 num = "0.2"
 ordered-float = "0.5.0"
-prolog_parser = "0.7.20"
+prolog_parser = "0.7.21"
 
 [dependencies.termion]
 version = "1.4.0"
\ No newline at end of file
index 30d78a961b0a34b92736ab3c489c9b904bdcdab3..411b84c1b8911d1b48b660e3642fbceb3f452d28 100644 (file)
@@ -4,10 +4,11 @@ use prolog::instructions::*;
 use prolog::machine::machine_state::*;
 
 use std::collections::HashSet;
+use std::ops::Deref;
 use std::vec::Vec;
 
 pub struct HCPreOrderIterator<'a> {
-    pub(crate) machine_st: &'a MachineState,
+    machine_st: &'a MachineState,
     state_stack: Vec<Addr>
 }
 
@@ -83,21 +84,83 @@ impl<'a> Iterator for HCPreOrderIterator<'a> {
     }
 }
 
-pub struct HCPostOrderIterator<'a> {
-    pre_iter:     HCPreOrderIterator<'a>,
+pub struct HCTrackingPreOrderIter<'a> {
+    pre_iter:  HCPreOrderIterator<'a>,
+    this_addr: Addr
+}
+
+impl<'a> HCTrackingPreOrderIter<'a> {
+    fn new(machine_st: &'a MachineState, a: Addr) -> Self {
+        HCTrackingPreOrderIter {
+            pre_iter: HCPreOrderIterator::new(machine_st, a.clone()),
+            this_addr: a
+        }
+    }
+
+    #[inline]
+    pub fn this_addr(&self) -> Addr {
+        self.this_addr.clone()
+    }
+
+    #[inline]
+    pub fn machine_st(&self) -> &MachineState {
+        self.pre_iter.machine_st
+    }
+}
+
+impl<'a> MutStackHCIterator for HCTrackingPreOrderIter<'a> {
+    fn stack(&mut self) -> &mut Vec<Addr> {
+        self.pre_iter.stack()
+    }
+}
+
+impl<'a> Iterator for HCTrackingPreOrderIter<'a> {
+    type Item = HeapCellValue;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        self.pre_iter.state_stack.pop().map(|a| {
+            let addr = self.pre_iter.follow(a);
+            self.this_addr = addr.clone();
+
+            match addr {
+                Addr::HeapCell(h) =>
+                    self.pre_iter.machine_st.heap[h].clone(),
+                Addr::StackCell(fr, sc) =>
+                    HeapCellValue::Addr(self.pre_iter.machine_st.and_stack[fr][sc].clone()),
+                da =>
+                    HeapCellValue::Addr(da)
+            }
+        })
+    }
+}
+
+pub trait MutStackHCIterator where Self: Iterator<Item=HeapCellValue> {
+    fn stack(&mut self) -> &mut Vec<Addr>;
+}
+
+pub struct HCPostOrderIterator<HCIter> {
+    base_iter:    HCIter,
     parent_stack: Vec<(usize, HeapCellValue)> // number of children, parent node.
 }
 
-impl<'a> HCPostOrderIterator<'a> {
-    pub fn new(pre_iter: HCPreOrderIterator<'a>) -> Self {
+impl<HCIter> Deref for HCPostOrderIterator<HCIter> {
+    type Target = HCIter;
+
+    fn deref(&self) -> &Self::Target {
+        &self.base_iter
+    }
+}
+
+impl<HCIter: Iterator<Item=HeapCellValue>> HCPostOrderIterator<HCIter> {
+    pub fn new(base_iter: HCIter) -> Self {
         HCPostOrderIterator {
-            pre_iter,
+            base_iter,
             parent_stack: vec![]
         }
     }
 }
 
-impl<'a> Iterator for HCPostOrderIterator<'a> {
+impl<HCIter: Iterator<Item=HeapCellValue>> Iterator for HCPostOrderIterator<HCIter> {
     type Item = HeapCellValue;
 
     fn next(&mut self) -> Option<Self::Item> {
@@ -110,7 +173,7 @@ impl<'a> Iterator for HCPostOrderIterator<'a> {
                 self.parent_stack.push((child_count - 1, node));
             }
 
-            if let Some(item) = self.pre_iter.next() {
+            if let Some(item) = self.base_iter.next() {
                 match item {
                     HeapCellValue::NamedStr(arity, name, fix) =>
                         self.parent_stack.push((arity, HeapCellValue::NamedStr(arity, name, fix))),
@@ -127,15 +190,26 @@ impl<'a> Iterator for HCPostOrderIterator<'a> {
     }
 }
 
+pub type HCProperPostOrderIterator<'a> = HCPostOrderIterator<HCPreOrderIterator<'a>>;
+pub type HCAcyclicPostOrderIterator<'a> = HCPostOrderIterator<HCAcyclicIterator<HCTrackingPreOrderIter<'a>>>;
+
 impl MachineState {
+    pub fn tracking_pre_order_iter<'a>(&'a self, a: Addr) -> HCTrackingPreOrderIter<'a> {
+        HCTrackingPreOrderIter::new(self, a)
+    }
+    
     pub fn pre_order_iter<'a>(&'a self, a: Addr) -> HCPreOrderIterator<'a> {
         HCPreOrderIterator::new(self, a)
     }
 
-    pub fn post_order_iter<'a>(&'a self, a: Addr) -> HCPostOrderIterator<'a> {
+    pub fn post_order_iter<'a>(&'a self, a: Addr) -> HCProperPostOrderIterator<'a> {
         HCPostOrderIterator::new(HCPreOrderIterator::new(self, a))
     }
 
+    pub fn acyclic_tracking_post_order_iter<'a>(&'a self, a: Addr) -> HCAcyclicPostOrderIterator<'a> {
+        HCPostOrderIterator::new(HCAcyclicIterator::new(HCTrackingPreOrderIter::new(self, a)))
+    }
+
     pub fn acyclic_pre_order_iter<'a>(&'a self, a: Addr) -> HCAcyclicIterator<HCPreOrderIterator<'a>>
     {
         HCAcyclicIterator::new(HCPreOrderIterator::new(self, a))
@@ -149,10 +223,6 @@ impl MachineState {
     }
 }
 
-pub trait MutStackHCIterator {
-    fn stack(&mut self) -> &mut Vec<Addr>;
-}
-
 impl<'a> MutStackHCIterator for HCPreOrderIterator<'a> {
     fn stack(&mut self) -> &mut Vec<Addr> {
         &mut self.state_stack
@@ -171,8 +241,16 @@ impl<HCIter: MutStackHCIterator> HCAcyclicIterator<HCIter>
     }
 }
 
+impl<HCIter> Deref for HCAcyclicIterator<HCIter> {
+    type Target = HCIter;
+    
+    fn deref(&self) -> &Self::Target {
+        &self.iter
+    }
+}
+
 impl<HCIter> Iterator for HCAcyclicIterator<HCIter>
-where HCIter: Iterator<Item=HeapCellValue> + MutStackHCIterator
+  where HCIter: Iterator<Item=HeapCellValue> + MutStackHCIterator
 {
     type Item = HeapCellValue;
 
@@ -204,7 +282,7 @@ impl<HCIter: MutStackHCIterator> HCZippedAcyclicIterator<HCIter>
 }
 
 impl<HCIter> Iterator for HCZippedAcyclicIterator<HCIter>
-where HCIter: Iterator<Item=HeapCellValue> + MutStackHCIterator
+  where HCIter: Iterator<Item=HeapCellValue> + MutStackHCIterator
 {
     type Item = (HeapCellValue, HeapCellValue);
 
index 7ee7be26bed4bc1521a645ce54160caa69fb270e..d2a30c690006ef991bd3ad707dd0aebade61b56a 100644 (file)
@@ -143,6 +143,7 @@ pub struct HCPrinter<'a, Outputter> {
     state_stack:  Vec<TokenOrRedirect>,
     heap_locs:    ReverseHeapVarDict,
     printed_vars: HashSet<Addr>,
+    bracketed_addrs: HashSet<Addr>,
     pub(crate) numbervars:   bool,
     pub(crate) quoted:       bool,
     pub(crate) ignore_ops:   bool
@@ -254,6 +255,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
                     state_stack: vec![],
                     heap_locs: ReverseHeapVarDict::new(),
                     printed_vars: HashSet::new(),
+                    bracketed_addrs: HashSet::new(),
                     numbervars: false,
                     quoted: false,
                     ignore_ops: false }
@@ -298,7 +300,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
         }
     }
 
-    fn enqueue_op(&mut self, ct: ClauseType, spec: (usize, Specifier)) {        
+    fn enqueue_op(&mut self, ct: ClauseType, spec: (usize, Specifier)) {
         if is_postfix!(spec.1) {
             self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
             self.state_stack.push(TokenOrRedirect::CompositeRedirect(DirectedOp::Right(ct.name())));
@@ -331,7 +333,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
         self.state_stack.push(TokenOrRedirect::Atom(name));
     }
 
-    fn format_clause(&mut self, iter: &mut HCPreOrderIterator, arity: usize, ct: ClauseType)
+    fn format_clause(&mut self, iter: &mut HCTrackingPreOrderIter, arity: usize, ct: ClauseType)
     {
         if let Some(spec) = ct.spec() {
             if !self.ignore_ops {
@@ -341,7 +343,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
             let addr = iter.stack().last().cloned().unwrap();
 
             // 7.10.4
-            if let Some(var) = iter.machine_st.numbervar(addr) {
+            if let Some(var) = iter.machine_st().numbervar(addr) {
                 iter.stack().pop();
                 self.state_stack.push(TokenOrRedirect::NumberedVar(var));
                 return;
@@ -361,7 +363,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
         }
     }
 
-    fn check_for_seen(&mut self, iter: &mut HCPreOrderIterator, op: &Option<DirectedOp>)
+    fn check_for_seen(&mut self, iter: &mut HCTrackingPreOrderIter, op: &Option<DirectedOp>)
                       -> Option<HeapCellValue>
     {
         iter.stack().last().cloned().and_then(|addr| {
@@ -533,7 +535,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
         self.state_stack.push(TokenOrRedirect::OpenList(cell));
     }
 
-    fn handle_heap_term(&mut self, iter: &mut HCPreOrderIterator, op: Option<DirectedOp>)
+    fn handle_heap_term(&mut self, iter: &mut HCTrackingPreOrderIter, op: Option<DirectedOp>)
     {
         let heap_val = match self.check_for_seen(iter, &op) {
             Some(heap_val) => heap_val,
@@ -600,8 +602,70 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
         }
     }
 
+    fn mark_terms_for_brackets(&mut self, addr: Addr) {
+        let mut iter = self.machine_st.acyclic_tracking_post_order_iter(addr);
+        let mut stack: Vec<(Addr, usize)> = vec![];
+
+        while let Some(heap_val) = iter.next() {
+            let addr = iter.this_addr();
+
+            match heap_val {
+                HeapCellValue::NamedStr(2, _, Some((prec, spec))) => {
+                    let (addr_2, prec_2) = stack.pop().unwrap();
+                    let (addr_1, prec_1) = stack.pop().unwrap();
+
+                    if prec_1 > prec || (prec_1 == prec && (is_xfy!(spec) || is_xfx!(spec))) {
+                        self.bracketed_addrs.insert(addr_1);
+                    }
+
+                    if prec_2 > prec || (prec_2 == prec && (is_yfx!(spec) || is_xfx!(spec))) {
+                        self.bracketed_addrs.insert(addr_2);
+                    }
+
+                    stack.push((addr, prec));
+                    continue;
+                },
+                HeapCellValue::NamedStr(1, _, Some((prec, spec))) => {
+                    let (addr_1, prec_1) = stack.pop().unwrap();
+
+                    if prec_1 > prec || (prec_1 == prec && (is_fx!(spec) || is_xf!(spec))) {
+                        self.bracketed_addrs.insert(addr_1);
+                    }
+
+                    stack.push((addr, prec));
+                    continue;
+                },
+                HeapCellValue::NamedStr(arity, _, None) => {
+                    let stack_len = stack.len();
+
+                    for (addr_1, prec_1) in stack.drain(stack_len - arity ..) {
+                        if prec_1 >= 1000 { // 1000 is the precedence of the (,) operator.
+                            self.bracketed_addrs.insert(addr_1);
+                        }
+                    }                    
+                },
+                HeapCellValue::Addr(addr_1 @ Addr::Con(Constant::Atom(_, Some(_)))) => {
+                    self.bracketed_addrs.insert(addr_1);
+                },
+                HeapCellValue::Addr(Addr::Lis(_)) => {
+                    let stack_len = stack.len();
+                    
+                    for (addr_1, prec_1) in stack.drain(stack_len - 2 ..) {
+                        if prec_1 >= 1000 { // 1000 is the precedence of the (,) operator.
+                            self.bracketed_addrs.insert(addr_1);
+                        }
+                    }
+                },
+                _ => {}
+            };
+
+            stack.push((addr, 0));
+        }
+    }
+
     pub fn print(mut self, addr: Addr) -> Outputter {
-        let mut iter = HCPreOrderIterator::new(&self.machine_st, addr);
+        self.mark_terms_for_brackets(addr.clone());
+        let mut iter = self.machine_st.tracking_pre_order_iter(addr);
 
         loop {
             if let Some(loc_data) = self.state_stack.pop() {
index 5eba3a97dd4fbe1666147933b0b86dd6825e6987..21bfa59a915400148f4779b1f7b08ee04aa45ae5 100644 (file)
@@ -836,7 +836,7 @@ impl Ref {
 #[derive(Clone, PartialEq)]
 pub enum HeapCellValue {
     Addr(Addr),
-    NamedStr(usize, ClauseName, Option<(usize, Specifier)>), // arity, name, fixity if it has one.
+    NamedStr(usize, ClauseName, Option<(usize, Specifier)>), // arity, name, precedence/Specifier if it has one.
 }
 
 impl HeapCellValue {