[[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)",
"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)",
]
"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"
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
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>
}
}
}
-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> {
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))),
}
}
+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))
}
}
-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
}
}
+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;
}
impl<HCIter> Iterator for HCZippedAcyclicIterator<HCIter>
-where HCIter: Iterator<Item=HeapCellValue> + MutStackHCIterator
+ where HCIter: Iterator<Item=HeapCellValue> + MutStackHCIterator
{
type Item = (HeapCellValue, HeapCellValue);
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
state_stack: vec![],
heap_locs: ReverseHeapVarDict::new(),
printed_vars: HashSet::new(),
+ bracketed_addrs: HashSet::new(),
numbervars: false,
quoted: false,
ignore_ops: false }
}
}
- 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())));
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 {
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;
}
}
- 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| {
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,
}
}
+ 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() {
#[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 {