prepare for improved (?) ambiguity checks
This commit is contained in:
6
Cargo.lock
generated
6
Cargo.lock
generated
@@ -86,8 +86,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prolog_parser"
|
name = "prolog_parser"
|
||||||
version = "0.7.21"
|
version = "0.7.22"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num 0.2.0 (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)",
|
"ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -113,7 +112,7 @@ dependencies = [
|
|||||||
"downcast 0.9.1 (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)",
|
"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)",
|
"ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"prolog_parser 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"prolog_parser 0.7.22",
|
||||||
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -152,7 +151,6 @@ 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.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 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 ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "58d25b6c0e47b20d05226d288ff434940296e7e2f8b877975da32f862152241f"
|
||||||
"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_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 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"
|
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ license = "BSD-3-Clause"
|
|||||||
downcast = "0.9.1"
|
downcast = "0.9.1"
|
||||||
num = "0.2"
|
num = "0.2"
|
||||||
ordered-float = "0.5.0"
|
ordered-float = "0.5.0"
|
||||||
prolog_parser = "0.7.21"
|
prolog_parser = { version = "0.7.22", path = "../prolog_parser" }
|
||||||
|
|
||||||
[dependencies.termion]
|
[dependencies.termion]
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
@@ -20,6 +20,10 @@ impl<'a> HCPreOrderIterator<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn machine_st(&self) -> &MachineState {
|
||||||
|
&self.machine_st
|
||||||
|
}
|
||||||
|
|
||||||
fn follow_heap(&mut self, h: usize) -> Addr
|
fn follow_heap(&mut self, h: usize) -> Addr
|
||||||
{
|
{
|
||||||
match &self.machine_st.heap[h] {
|
match &self.machine_st.heap[h] {
|
||||||
@@ -84,56 +88,6 @@ impl<'a> Iterator for 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> {
|
pub trait MutStackHCIterator where Self: Iterator<Item=HeapCellValue> {
|
||||||
fn stack(&mut self) -> &mut Vec<Addr>;
|
fn stack(&mut self) -> &mut Vec<Addr>;
|
||||||
}
|
}
|
||||||
@@ -191,13 +145,8 @@ impl<HCIter: Iterator<Item=HeapCellValue>> Iterator for HCPostOrderIterator<HCIt
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub type HCProperPostOrderIterator<'a> = HCPostOrderIterator<HCPreOrderIterator<'a>>;
|
pub type HCProperPostOrderIterator<'a> = HCPostOrderIterator<HCPreOrderIterator<'a>>;
|
||||||
pub type HCAcyclicPostOrderIterator<'a> = HCPostOrderIterator<HCAcyclicIterator<HCTrackingPreOrderIter<'a>>>;
|
|
||||||
|
|
||||||
impl MachineState {
|
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> {
|
pub fn pre_order_iter<'a>(&'a self, a: Addr) -> HCPreOrderIterator<'a> {
|
||||||
HCPreOrderIterator::new(self, a)
|
HCPreOrderIterator::new(self, a)
|
||||||
}
|
}
|
||||||
@@ -206,10 +155,6 @@ impl MachineState {
|
|||||||
HCPostOrderIterator::new(HCPreOrderIterator::new(self, 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>>
|
pub fn acyclic_pre_order_iter<'a>(&'a self, a: Addr) -> HCAcyclicIterator<HCPreOrderIterator<'a>>
|
||||||
{
|
{
|
||||||
HCAcyclicIterator::new(HCPreOrderIterator::new(self, a))
|
HCAcyclicIterator::new(HCPreOrderIterator::new(self, a))
|
||||||
|
|||||||
@@ -11,28 +11,43 @@ use std::collections::{HashMap, HashSet};
|
|||||||
use std::iter::once;
|
use std::iter::once;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
/* contains the location, name, precision and Specifier of the parent op. */
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum DirectedOp {
|
pub enum DirectedOp {
|
||||||
Left(ClauseName, bool), // bool is true if infix.
|
Left(ClauseName, (usize, Specifier)),
|
||||||
Right(ClauseName),
|
Right(ClauseName, (usize, Specifier)),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DirectedOp {
|
impl DirectedOp {
|
||||||
|
#[inline]
|
||||||
fn as_str(&self) -> &str {
|
fn as_str(&self) -> &str {
|
||||||
match self {
|
match self {
|
||||||
&DirectedOp::Left(ref name, _) | &DirectedOp::Right(ref name) =>
|
&DirectedOp::Left(ref name, _) | &DirectedOp::Right(ref name, _) =>
|
||||||
name.as_str()
|
name.as_str()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn needs_bracketing(child_spec: (usize, Specifier), op: &DirectedOp) -> bool {
|
||||||
|
match op {
|
||||||
|
&DirectedOp::Left(_, (priority, spec)) => {
|
||||||
|
let is_strict_right = is_yfx!(spec) || is_xfx!(spec) || is_fx!(spec);
|
||||||
|
child_spec.0 > priority || (child_spec.0 == priority && is_strict_right)
|
||||||
|
},
|
||||||
|
&DirectedOp::Right(_, (priority, spec)) => {
|
||||||
|
let is_strict_left = is_xfx!(spec) || is_xfy!(spec) || is_xf!(spec);
|
||||||
|
child_spec.0 > priority || (child_spec.0 == priority && is_strict_left)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum TokenOrRedirect {
|
pub enum TokenOrRedirect {
|
||||||
Atom(ClauseName),
|
Atom(ClauseName),
|
||||||
Op(ClauseName, (usize, Specifier)),
|
Op(ClauseName, (usize, Specifier)),
|
||||||
NumberedVar(String),
|
NumberedVar(String),
|
||||||
CompositeRedirect(DirectedOp),
|
CompositeRedirect(DirectedOp),
|
||||||
Redirect,
|
FunctorRedirect,
|
||||||
Open,
|
Open,
|
||||||
Close,
|
Close,
|
||||||
Comma,
|
Comma,
|
||||||
@@ -143,7 +158,6 @@ pub struct HCPrinter<'a, Outputter> {
|
|||||||
state_stack: Vec<TokenOrRedirect>,
|
state_stack: Vec<TokenOrRedirect>,
|
||||||
heap_locs: ReverseHeapVarDict,
|
heap_locs: ReverseHeapVarDict,
|
||||||
printed_vars: HashSet<Addr>,
|
printed_vars: HashSet<Addr>,
|
||||||
bracketed_addrs: HashSet<Addr>,
|
|
||||||
pub(crate) numbervars: bool,
|
pub(crate) numbervars: bool,
|
||||||
pub(crate) quoted: bool,
|
pub(crate) quoted: bool,
|
||||||
pub(crate) ignore_ops: bool
|
pub(crate) ignore_ops: bool
|
||||||
@@ -152,15 +166,15 @@ pub struct HCPrinter<'a, Outputter> {
|
|||||||
macro_rules! push_space_if_amb {
|
macro_rules! push_space_if_amb {
|
||||||
($self:expr, $atom:expr, $op:expr, $action:block) => (
|
($self:expr, $atom:expr, $op:expr, $action:block) => (
|
||||||
match $self.ambiguity_check($atom, $op) {
|
match $self.ambiguity_check($atom, $op) {
|
||||||
Some(DirectedOp::Left(_, false)) => {
|
Some(DirectedOp::Left(lop, (_, spec))) =>
|
||||||
$self.outputter.push_char(' ');
|
if is_infix!(spec) {
|
||||||
$action;
|
$self.outputter.insert_from_end(lop.as_str().len(), ' ');
|
||||||
},
|
$self.outputter.push_char(' ');
|
||||||
Some(DirectedOp::Left(lop, true)) => {
|
$action;
|
||||||
$self.outputter.insert_from_end(lop.as_str().len(), ' ');
|
} else {
|
||||||
$self.outputter.push_char(' ');
|
$self.outputter.push_char(' ');
|
||||||
$action;
|
$action;
|
||||||
},
|
},
|
||||||
Some(DirectedOp::Right(..)) => {
|
Some(DirectedOp::Right(..)) => {
|
||||||
$action;
|
$action;
|
||||||
$self.outputter.push_char(' ');
|
$self.outputter.push_char(' ');
|
||||||
@@ -255,7 +269,6 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
|
|||||||
state_stack: vec![],
|
state_stack: vec![],
|
||||||
heap_locs: ReverseHeapVarDict::new(),
|
heap_locs: ReverseHeapVarDict::new(),
|
||||||
printed_vars: HashSet::new(),
|
printed_vars: HashSet::new(),
|
||||||
bracketed_addrs: HashSet::new(),
|
|
||||||
numbervars: false,
|
numbervars: false,
|
||||||
quoted: false,
|
quoted: false,
|
||||||
ignore_ops: false }
|
ignore_ops: false }
|
||||||
@@ -283,18 +296,20 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
|
|||||||
fn ambiguity_check(&self, atom: &str, op: &Option<DirectedOp>) -> Option<DirectedOp>
|
fn ambiguity_check(&self, atom: &str, op: &Option<DirectedOp>) -> Option<DirectedOp>
|
||||||
{
|
{
|
||||||
match op {
|
match op {
|
||||||
&Some(DirectedOp::Left(ref lop, false)) if continues_with_append(lop.as_str(), atom) =>
|
&Some(DirectedOp::Left(ref lop, (priority, spec))) if is_infix!(spec) =>
|
||||||
Some(DirectedOp::Left(lop.clone(), false)),
|
|
||||||
&Some(DirectedOp::Left(ref lop, true)) =>
|
|
||||||
if self.outputter.ends_with(&format!(" {}", lop.as_str())) {
|
if self.outputter.ends_with(&format!(" {}", lop.as_str())) {
|
||||||
Some(DirectedOp::Left(lop.clone(), false))
|
Some(DirectedOp::Left(lop.clone(), (priority, spec)))
|
||||||
} else if continues_with_append(lop.as_str(), atom) {
|
} else if continues_with_append(lop.as_str(), atom) {
|
||||||
Some(DirectedOp::Left(lop.clone(), true))
|
Some(DirectedOp::Left(lop.clone(), (priority, spec)))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
&Some(DirectedOp::Right(ref rop)) if continues_with_append(atom, rop.as_str()) =>
|
&Some(DirectedOp::Left(ref lop, spec))
|
||||||
Some(DirectedOp::Right(rop.clone())),
|
if continues_with_append(lop.as_str(), atom) =>
|
||||||
|
Some(DirectedOp::Left(lop.clone(), spec)),
|
||||||
|
&Some(DirectedOp::Right(ref rop, spec))
|
||||||
|
if continues_with_append(atom, rop.as_str()) =>
|
||||||
|
Some(DirectedOp::Right(rop.clone(), spec)),
|
||||||
_ =>
|
_ =>
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@@ -302,19 +317,22 @@ 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) {
|
if is_postfix!(spec.1) {
|
||||||
|
let right_directed_op = DirectedOp::Right(ct.name(), spec);
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
|
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
|
||||||
self.state_stack.push(TokenOrRedirect::CompositeRedirect(DirectedOp::Right(ct.name())));
|
self.state_stack.push(TokenOrRedirect::CompositeRedirect(right_directed_op));
|
||||||
} else if is_prefix!(spec.1) {
|
} else if is_prefix!(spec.1) {
|
||||||
let left_directed_op = DirectedOp::Left(ct.name(), false);
|
let left_directed_op = DirectedOp::Left(ct.name(), spec);
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::CompositeRedirect(left_directed_op));
|
self.state_stack.push(TokenOrRedirect::CompositeRedirect(left_directed_op));
|
||||||
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
|
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
|
||||||
} else { // if is_infix!(spec.1)
|
} else { // if is_infix!(spec.1)
|
||||||
let left_directed_op = DirectedOp::Left(ct.name(), true);
|
let left_directed_op = DirectedOp::Left(ct.name(), spec);
|
||||||
|
let right_directed_op = DirectedOp::Right(ct.name(), spec);
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::CompositeRedirect(left_directed_op));
|
self.state_stack.push(TokenOrRedirect::CompositeRedirect(left_directed_op));
|
||||||
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
|
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
|
||||||
self.state_stack.push(TokenOrRedirect::CompositeRedirect(DirectedOp::Right(ct.name())));
|
self.state_stack.push(TokenOrRedirect::CompositeRedirect(right_directed_op));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,7 +341,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
|
|||||||
self.state_stack.push(TokenOrRedirect::Close);
|
self.state_stack.push(TokenOrRedirect::Close);
|
||||||
|
|
||||||
for _ in 0 .. arity {
|
for _ in 0 .. arity {
|
||||||
self.state_stack.push(TokenOrRedirect::Redirect);
|
self.state_stack.push(TokenOrRedirect::FunctorRedirect);
|
||||||
self.state_stack.push(TokenOrRedirect::Comma);
|
self.state_stack.push(TokenOrRedirect::Comma);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,7 +351,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
|
|||||||
self.state_stack.push(TokenOrRedirect::Atom(name));
|
self.state_stack.push(TokenOrRedirect::Atom(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn format_clause(&mut self, iter: &mut HCTrackingPreOrderIter, arity: usize, ct: ClauseType)
|
fn format_clause(&mut self, iter: &mut HCPreOrderIterator, arity: usize, ct: ClauseType)
|
||||||
{
|
{
|
||||||
if let Some(spec) = ct.spec() {
|
if let Some(spec) = ct.spec() {
|
||||||
if !self.ignore_ops {
|
if !self.ignore_ops {
|
||||||
@@ -363,7 +381,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_for_seen(&mut self, iter: &mut HCTrackingPreOrderIter, op: &Option<DirectedOp>)
|
fn check_for_seen(&mut self, iter: &mut HCPreOrderIterator, op: &Option<DirectedOp>)
|
||||||
-> Option<HeapCellValue>
|
-> Option<HeapCellValue>
|
||||||
{
|
{
|
||||||
iter.stack().last().cloned().and_then(|addr| {
|
iter.stack().last().cloned().and_then(|addr| {
|
||||||
@@ -528,14 +546,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
|
|||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::CloseList(cell.clone()));
|
self.state_stack.push(TokenOrRedirect::CloseList(cell.clone()));
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Redirect);
|
self.state_stack.push(TokenOrRedirect::FunctorRedirect);
|
||||||
self.state_stack.push(TokenOrRedirect::HeadTailSeparator); // bar
|
self.state_stack.push(TokenOrRedirect::HeadTailSeparator); // bar
|
||||||
self.state_stack.push(TokenOrRedirect::Redirect);
|
self.state_stack.push(TokenOrRedirect::FunctorRedirect);
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::OpenList(cell));
|
self.state_stack.push(TokenOrRedirect::OpenList(cell));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_heap_term(&mut self, iter: &mut HCTrackingPreOrderIter, op: Option<DirectedOp>)
|
fn handle_heap_term(&mut self, iter: &mut HCPreOrderIterator, op: Option<DirectedOp>,
|
||||||
|
is_functor_redirect: bool)
|
||||||
{
|
{
|
||||||
let heap_val = match self.check_for_seen(iter, &op) {
|
let heap_val = match self.check_for_seen(iter, &op) {
|
||||||
Some(heap_val) => heap_val,
|
Some(heap_val) => heap_val,
|
||||||
@@ -543,18 +562,30 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
|
|||||||
};
|
};
|
||||||
|
|
||||||
match heap_val {
|
match heap_val {
|
||||||
HeapCellValue::NamedStr(arity, ref name, Some(spec)) if name.as_str() != "," => {
|
HeapCellValue::NamedStr(arity, ref name, Some(spec)) => {
|
||||||
if op.is_some() {
|
let add_brackets = if !self.ignore_ops {
|
||||||
|
if let Some(ref op) = &op {
|
||||||
|
needs_bracketing(spec, op)
|
||||||
|
} else {
|
||||||
|
is_functor_redirect && spec.0 >= 1000
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
|
||||||
|
if add_brackets {
|
||||||
self.state_stack.push(TokenOrRedirect::Close);
|
self.state_stack.push(TokenOrRedirect::Close);
|
||||||
}
|
}
|
||||||
|
|
||||||
let ct = ClauseType::from(name.clone(), arity, Some(spec));
|
let ct = ClauseType::from(name.clone(), arity, Some(spec));
|
||||||
self.format_clause(iter, arity, ct);
|
self.format_clause(iter, arity, ct);
|
||||||
|
|
||||||
if let Some(ref op) = op {
|
if add_brackets {
|
||||||
self.state_stack.push(TokenOrRedirect::Open);
|
self.state_stack.push(TokenOrRedirect::Open);
|
||||||
|
}
|
||||||
|
|
||||||
if self.outputter.ends_with(&format!(" {}", op.as_str())) {
|
if let Some(op) = op {
|
||||||
|
if !add_brackets && self.outputter.ends_with(&format!(" {}", op.as_str())) {
|
||||||
self.state_stack.push(TokenOrRedirect::Space);
|
self.state_stack.push(TokenOrRedirect::Space);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -602,70 +633,8 @@ 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 {
|
pub fn print(mut self, addr: Addr) -> Outputter {
|
||||||
self.mark_terms_for_brackets(addr.clone());
|
let mut iter = self.machine_st.pre_order_iter(addr);
|
||||||
let mut iter = self.machine_st.tracking_pre_order_iter(addr);
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
if let Some(loc_data) = self.state_stack.pop() {
|
if let Some(loc_data) = self.state_stack.pop() {
|
||||||
@@ -677,9 +646,9 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
|
|||||||
TokenOrRedirect::NumberedVar(num_var) =>
|
TokenOrRedirect::NumberedVar(num_var) =>
|
||||||
self.outputter.append(num_var.as_str()),
|
self.outputter.append(num_var.as_str()),
|
||||||
TokenOrRedirect::CompositeRedirect(op) =>
|
TokenOrRedirect::CompositeRedirect(op) =>
|
||||||
self.handle_heap_term(&mut iter, Some(op)),
|
self.handle_heap_term(&mut iter, Some(op), false),
|
||||||
TokenOrRedirect::Redirect =>
|
TokenOrRedirect::FunctorRedirect =>
|
||||||
self.handle_heap_term(&mut iter, None),
|
self.handle_heap_term(&mut iter, None, true),
|
||||||
TokenOrRedirect::Space =>
|
TokenOrRedirect::Space =>
|
||||||
self.outputter.push_char(' '),
|
self.outputter.push_char(' '),
|
||||||
TokenOrRedirect::Close =>
|
TokenOrRedirect::Close =>
|
||||||
@@ -702,7 +671,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
|
|||||||
self.outputter.append(", ")
|
self.outputter.append(", ")
|
||||||
}
|
}
|
||||||
} else if !iter.stack().is_empty() {
|
} else if !iter.stack().is_empty() {
|
||||||
self.handle_heap_term(&mut iter, None);
|
self.handle_heap_term(&mut iter, None, false);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,7 +314,6 @@ impl MachineState {
|
|||||||
|
|
||||||
printer.quoted = true;
|
printer.quoted = true;
|
||||||
printer.numbervars = true;
|
printer.numbervars = true;
|
||||||
printer.ignore_ops = true;
|
|
||||||
|
|
||||||
printer.see_all_locs();
|
printer.see_all_locs();
|
||||||
|
|
||||||
|
|||||||
@@ -1676,7 +1676,9 @@ fn test_queries_on_builtins()
|
|||||||
assert_prolog_success!(&mut wam, "?- X = [.,.(.,.,.)].",
|
assert_prolog_success!(&mut wam, "?- X = [.,.(.,.,.)].",
|
||||||
[["X = ['.', '.'('.', '.', '.')]"]]);
|
[["X = ['.', '.'('.', '.', '.')]"]]);
|
||||||
assert_prolog_success!(&mut wam, "?- X = a+(b*c).",
|
assert_prolog_success!(&mut wam, "?- X = a+(b*c).",
|
||||||
[["X = a+(b*c)"]]);
|
[["X = a+b*c"]]);
|
||||||
|
assert_prolog_success!(&mut wam, "?- X = a*(b+c).",
|
||||||
|
[["X = a*(b+c)"]]);
|
||||||
assert_prolog_success!(&mut wam, "?- X = [:-,-].",
|
assert_prolog_success!(&mut wam, "?- X = [:-,-].",
|
||||||
[["X = [:-, -]"]]);
|
[["X = [:-, -]"]]);
|
||||||
assert_prolog_success!(&mut wam, "?- X = a*(b+c).",
|
assert_prolog_success!(&mut wam, "?- X = a*(b+c).",
|
||||||
|
|||||||
Reference in New Issue
Block a user