prepare to add bracketing conditions to heap_print
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user