From: Mark Thom Date: Mon, 21 Jan 2019 06:56:15 +0000 (-0700) Subject: prepare to add bracketing conditions to heap_print X-Git-Tag: v0.8.110~292 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=498fe5247d60c818b01ebb00ab747285edbde76f;p=scryer-prolog.git prepare to add bracketing conditions to heap_print --- diff --git a/Cargo.lock b/Cargo.lock index 4db77776..03097f24 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/Cargo.toml b/Cargo.toml index 29bde88d..94c6126b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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 diff --git a/src/prolog/heap_iter.rs b/src/prolog/heap_iter.rs index 30d78a96..411b84c1 100644 --- a/src/prolog/heap_iter.rs +++ b/src/prolog/heap_iter.rs @@ -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 } @@ -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 { + self.pre_iter.stack() + } +} + +impl<'a> Iterator for HCTrackingPreOrderIter<'a> { + type Item = HeapCellValue; + + fn next(&mut self) -> Option { + 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 { + fn stack(&mut self) -> &mut Vec; +} + +pub struct HCPostOrderIterator { + 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 Deref for HCPostOrderIterator { + type Target = HCIter; + + fn deref(&self) -> &Self::Target { + &self.base_iter + } +} + +impl> HCPostOrderIterator { + pub fn new(base_iter: HCIter) -> Self { HCPostOrderIterator { - pre_iter, + base_iter, parent_stack: vec![] } } } -impl<'a> Iterator for HCPostOrderIterator<'a> { +impl> Iterator for HCPostOrderIterator { type Item = HeapCellValue; fn next(&mut self) -> Option { @@ -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>; +pub type HCAcyclicPostOrderIterator<'a> = HCPostOrderIterator>>; + 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> { HCAcyclicIterator::new(HCPreOrderIterator::new(self, a)) @@ -149,10 +223,6 @@ impl MachineState { } } -pub trait MutStackHCIterator { - fn stack(&mut self) -> &mut Vec; -} - impl<'a> MutStackHCIterator for HCPreOrderIterator<'a> { fn stack(&mut self) -> &mut Vec { &mut self.state_stack @@ -171,8 +241,16 @@ impl HCAcyclicIterator } } +impl Deref for HCAcyclicIterator { + type Target = HCIter; + + fn deref(&self) -> &Self::Target { + &self.iter + } +} + impl Iterator for HCAcyclicIterator -where HCIter: Iterator + MutStackHCIterator + where HCIter: Iterator + MutStackHCIterator { type Item = HeapCellValue; @@ -204,7 +282,7 @@ impl HCZippedAcyclicIterator } impl Iterator for HCZippedAcyclicIterator -where HCIter: Iterator + MutStackHCIterator + where HCIter: Iterator + MutStackHCIterator { type Item = (HeapCellValue, HeapCellValue); diff --git a/src/prolog/heap_print.rs b/src/prolog/heap_print.rs index 7ee7be26..d2a30c69 100644 --- a/src/prolog/heap_print.rs +++ b/src/prolog/heap_print.rs @@ -143,6 +143,7 @@ pub struct HCPrinter<'a, Outputter> { state_stack: Vec, heap_locs: ReverseHeapVarDict, printed_vars: HashSet, + bracketed_addrs: HashSet, 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) + fn check_for_seen(&mut self, iter: &mut HCTrackingPreOrderIter, op: &Option) -> Option { 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) + fn handle_heap_term(&mut self, iter: &mut HCTrackingPreOrderIter, op: Option) { 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() { diff --git a/src/prolog/instructions.rs b/src/prolog/instructions.rs index 5eba3a97..21bfa59a 100644 --- a/src/prolog/instructions.rs +++ b/src/prolog/instructions.rs @@ -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 {