streamline variable search in heap_print.rs
This commit is contained in:
@@ -2,9 +2,8 @@ use prolog::ast::*;
|
|||||||
use prolog::heap_iter::*;
|
use prolog::heap_iter::*;
|
||||||
use prolog::machine::machine_state::MachineState;
|
use prolog::machine::machine_state::MachineState;
|
||||||
|
|
||||||
use std::borrow::Cow;
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::collections::HashSet;
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@@ -142,15 +141,25 @@ impl HCValueFormatter for TermFormatter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ReverseHeapVarDict<'a> = HashMap<Addr, Rc<Var>>;
|
||||||
|
|
||||||
pub struct HCPrinter<'a, Formatter, Outputter> {
|
pub struct HCPrinter<'a, Formatter, Outputter> {
|
||||||
formatter: Formatter,
|
formatter: Formatter,
|
||||||
outputter: Outputter,
|
outputter: Outputter,
|
||||||
machine_st: &'a MachineState,
|
machine_st: &'a MachineState,
|
||||||
state_stack: Vec<TokenOrRedirect>,
|
state_stack: Vec<TokenOrRedirect>,
|
||||||
heap_locs: Cow<'a, HeapVarDict>,
|
heap_locs: ReverseHeapVarDict<'a>,
|
||||||
printed_vars: HashSet<Addr>
|
printed_vars: HashSet<Addr>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn reverse_heap_locs<'a>(machine_st: &'a MachineState, heap_locs: &'a HeapVarDict)
|
||||||
|
-> ReverseHeapVarDict<'a>
|
||||||
|
{
|
||||||
|
heap_locs.iter().map(|(var, var_addr)| {
|
||||||
|
(machine_st.store(machine_st.deref(var_addr.clone())), var.clone())
|
||||||
|
}).collect()
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter>
|
impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter>
|
||||||
HCPrinter<'a, Formatter, Outputter>
|
HCPrinter<'a, Formatter, Outputter>
|
||||||
{
|
{
|
||||||
@@ -160,7 +169,7 @@ impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter>
|
|||||||
outputter: output,
|
outputter: output,
|
||||||
machine_st,
|
machine_st,
|
||||||
state_stack: vec![],
|
state_stack: vec![],
|
||||||
heap_locs: Cow::default(),
|
heap_locs: ReverseHeapVarDict::new(),
|
||||||
printed_vars: HashSet::new() }
|
printed_vars: HashSet::new() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,21 +179,7 @@ impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter>
|
|||||||
{
|
{
|
||||||
let mut printer = Self::new(machine_st, fmt, output);
|
let mut printer = Self::new(machine_st, fmt, output);
|
||||||
|
|
||||||
printer.heap_locs = Cow::Borrowed(heap_locs);
|
printer.heap_locs = reverse_heap_locs(machine_st, heap_locs);
|
||||||
printer
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_heap_locs_as_seen(machine_st: &'a MachineState, fmt: Formatter,
|
|
||||||
output: Outputter, heap_locs: &'a HeapVarDict)
|
|
||||||
-> Self
|
|
||||||
{
|
|
||||||
let mut printer = Self::from_heap_locs(machine_st, fmt, output, heap_locs);
|
|
||||||
|
|
||||||
for (_, addr) in heap_locs.iter() {
|
|
||||||
let addr = machine_st.store(machine_st.deref(addr.clone()));
|
|
||||||
printer.printed_vars.insert(addr.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
printer
|
printer
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,37 +193,33 @@ impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns a HeapCellValue iff the next element to come hasn't been seen previously.
|
|
||||||
fn check_for_seen(&mut self, iter: &mut HCPreOrderIterator) -> Option<HeapCellValue> {
|
fn check_for_seen(&mut self, iter: &mut HCPreOrderIterator) -> Option<HeapCellValue> {
|
||||||
iter.stack().last().cloned().and_then(|addr| {
|
iter.stack().last().cloned().and_then(|addr| {
|
||||||
let addr = self.machine_st.store(self.machine_st.deref(addr));
|
let addr = self.machine_st.store(self.machine_st.deref(addr));
|
||||||
|
|
||||||
for (var, var_addr) in self.heap_locs.iter() {
|
match self.heap_locs.get(&addr).cloned() {
|
||||||
if &addr == &self.machine_st.store(self.machine_st.deref(var_addr.clone())) {
|
Some(var) => if !self.printed_vars.contains(&addr) {
|
||||||
if !self.printed_vars.contains(&addr) {
|
|
||||||
self.printed_vars.insert(addr);
|
|
||||||
return iter.next();
|
|
||||||
} else {
|
|
||||||
iter.stack().pop();
|
|
||||||
self.outputter.append(var.as_str());
|
|
||||||
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.machine_st.is_cyclic_term(addr.clone()) {
|
|
||||||
if self.printed_vars.contains(&addr) {
|
|
||||||
iter.stack().pop();
|
|
||||||
self.print_offset(addr);
|
|
||||||
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
self.printed_vars.insert(addr);
|
self.printed_vars.insert(addr);
|
||||||
|
return iter.next();
|
||||||
|
} else {
|
||||||
|
iter.stack().pop();
|
||||||
|
self.outputter.append(var.as_str());
|
||||||
|
|
||||||
|
return None;
|
||||||
|
},
|
||||||
|
None => if self.machine_st.is_cyclic_term(addr.clone()) {
|
||||||
|
if self.printed_vars.contains(&addr) {
|
||||||
|
iter.stack().pop();
|
||||||
|
self.print_offset(addr);
|
||||||
|
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
self.printed_vars.insert(addr);
|
||||||
|
iter.next()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
iter.next()
|
iter.next()
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
iter.next()
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -279,8 +270,6 @@ impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: idea: hand a mutable ref to iter to handle_heap_term,
|
|
||||||
// and have it query the stack before getting the next thing.
|
|
||||||
pub fn print(mut self, addr: Addr) -> Outputter {
|
pub fn print(mut self, addr: Addr) -> Outputter {
|
||||||
let mut iter = HCPreOrderIterator::new(&self.machine_st, addr);
|
let mut iter = HCPreOrderIterator::new(&self.machine_st, addr);
|
||||||
|
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ impl MachineState {
|
|||||||
-> Outputter
|
-> Outputter
|
||||||
where Fmt: HCValueFormatter, Outputter: HCValueOutputter
|
where Fmt: HCValueFormatter, Outputter: HCValueOutputter
|
||||||
{
|
{
|
||||||
let printer = HCPrinter::from_heap_locs_as_seen(&self, fmt, output, var_dir);
|
let printer = HCPrinter::from_heap_locs(&self, fmt, output, var_dir);
|
||||||
printer.print(addr)
|
printer.print(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user