fix bug in printer over lists.

This commit is contained in:
Mark Thom
2018-01-27 18:28:20 -07:00
parent 60440ea86b
commit 17d98f3942
4 changed files with 55 additions and 87 deletions

View File

@@ -5,26 +5,15 @@ use std::vec::Vec;
pub struct HeapCellPreOrderIterator<'a> {
machine_st : &'a MachineState,
state_stack : Vec<Ref>
state_stack : Vec<Addr>
}
impl<'a> HeapCellPreOrderIterator<'a> {
pub fn new(machine_st: &'a MachineState, r: Ref) -> Self
pub fn new(machine_st: &'a MachineState, a: Addr) -> Self
{
HeapCellPreOrderIterator {
machine_st,
state_stack: vec![r]
}
}
// called under the assumption that the location at r is about to
// be visited, and so any follow up states need to be added to
// state_stack. returns the dereferenced Addr from Ref.
fn follow(&mut self, r: Ref) -> Addr
{
match r {
Ref::HeapCell(hc) => self.follow_heap(hc),
Ref::StackCell(fr, sc) => self.follow_addr(Addr::StackCell(fr, sc))
state_stack: vec![a]
}
}
@@ -33,34 +22,35 @@ impl<'a> HeapCellPreOrderIterator<'a> {
match &self.machine_st.heap[h] {
&HeapCellValue::NamedStr(arity, _, _) => {
for idx in (1 .. arity + 1).rev() {
self.state_stack.push(Ref::HeapCell(h + idx));
self.state_stack.push(Addr::HeapCell(h + idx));
}
Addr::HeapCell(h)
},
&HeapCellValue::Addr(ref a) =>
self.follow_addr(a.clone())
self.follow(a.clone())
}
}
fn follow_addr(&mut self, addr: Addr) -> Addr
// called under the assumption that the location at r is about to
// be visited, and so any follow up states need to be added to
// state_stack. returns the dereferenced Addr from Ref.
fn follow(&mut self, addr: Addr) -> Addr
{
let da = self.machine_st.store(self.machine_st.deref(addr));
match &da {
&Addr::Con(_) => da,
&Addr::Lis(a) => {
self.state_stack.push(Ref::HeapCell(a + 1));
self.state_stack.push(Ref::HeapCell(a));
self.state_stack.push(Addr::HeapCell(a + 1));
self.state_stack.push(Addr::HeapCell(a));
da
},
&Addr::HeapCell(_) | &Addr::StackCell(_, _) =>
da,
&Addr::Str(s) => {
self.follow_heap(s); // record terms of structure.
Addr::HeapCell(s)
}
&Addr::Str(s) =>
self.follow_heap(s) // record terms of structure.
}
}
}
@@ -69,8 +59,8 @@ impl<'a> Iterator for HeapCellPreOrderIterator<'a> {
type Item = HeapCellValue;
fn next(&mut self) -> Option<Self::Item> {
if let Some(r) = self.state_stack.pop() {
match self.follow(r) {
if let Some(a) = self.state_stack.pop() {
match self.follow(a) {
Addr::HeapCell(h) => Some(self.machine_st.heap[h].clone()),
Addr::StackCell(fr, sc) => {
let heap_val = HeapCellValue::Addr(self.machine_st.and_stack[fr][sc].clone());
@@ -129,7 +119,7 @@ impl<'a> Iterator for HeapCellPostOrderIterator<'a> {
}
impl MachineState {
pub fn post_order_iter<'a>(&'a self, r: Ref) -> HeapCellPostOrderIterator<'a> {
HeapCellPostOrderIterator::new(HeapCellPreOrderIterator::new(self, r))
pub fn post_order_iter<'a>(&'a self, a: Addr) -> HeapCellPostOrderIterator<'a> {
HeapCellPostOrderIterator::new(HeapCellPreOrderIterator::new(self, a))
}
}

View File

@@ -259,31 +259,15 @@ impl MachineState {
self.trail(r1);
}
fn print_var<Fmt, Outputter>(&self, r: Ref, fmt: Fmt, output: Outputter) -> Outputter
pub(super) fn print_term<Fmt, Outputter>(&self, a: Addr, fmt: Fmt, output: Outputter) -> Outputter
where Fmt: HeapCellValueFormatter, Outputter: HeapCellValueOutputter
{
let iter = HeapCellPreOrderIterator::new(&self, r);
let iter = HeapCellPreOrderIterator::new(&self, a);
let printer = HeapCellPrinter::new(iter, fmt, output);
printer.print()
}
pub(super) fn print_term<Fmt, Outputter>(&self, addr: &Addr, fmt: Fmt, mut output: Outputter)
-> Outputter
where Fmt: HeapCellValueFormatter, Outputter: HeapCellValueOutputter
{
match addr {
&Addr::Con(ref c) => {
output.append(format!("{}", c).as_str());
output
},
&Addr::Lis(h) | &Addr::HeapCell(h) | &Addr::Str(h) =>
self.print_var(Ref::HeapCell(h), fmt, output),
&Addr::StackCell(fr, sc) =>
self.print_var(Ref::StackCell(fr, sc), fmt, output)
}
}
fn unify(&mut self, a1: Addr, a2: Addr) {
let mut pdl = vec![a1, a2];
@@ -508,15 +492,9 @@ impl MachineState {
return Ok(n.clone());
}
let r = match a {
Addr::Str(h) | Addr::HeapCell(h) => Ok(Ref::HeapCell(h)),
Addr::StackCell(fr, sc) => Ok(Ref::StackCell(fr, sc)),
_ => Err(instantiation_err.clone())
}?;
let mut interms: Vec<Number> = Vec::with_capacity(64);
for heap_val in self.post_order_iter(r) {
for heap_val in self.post_order_iter(a) {
match heap_val {
HeapCellValue::NamedStr(2, name, Some(Fixity::In)) => {
let a2 = interms.pop().unwrap();
@@ -1641,7 +1619,7 @@ impl MachineState {
self.p += 1;
},
&ControlInstruction::DisplayCall => {
let output = self.print_term(&self[temp_v!(1)],
let output = self.print_term(self[temp_v!(1)].clone(),
DisplayFormatter {},
PrinterOutputter::new());
@@ -1650,7 +1628,7 @@ impl MachineState {
self.p += 1;
},
&ControlInstruction::DisplayExecute => {
let output = self.print_term(&self[temp_v!(1)],
let output = self.print_term(self[temp_v!(1)].clone(),
DisplayFormatter {},
PrinterOutputter::new());

View File

@@ -228,7 +228,7 @@ impl Machine {
let h = self.ms.heap.h;
self.ms.copy_and_align_ball_to_heap();
let msg = self.ms.print_term(&Addr::HeapCell(h),
let msg = self.ms.print_term(Addr::HeapCell(h),
TermFormatter {},
PrinterOutputter::new())
.result();
@@ -322,7 +322,7 @@ impl Machine {
output.append(var.as_str());
output.append(" = ");
output = self.ms.print_term(addr, TermFormatter {}, output);
output = self.ms.print_term(addr.clone(), TermFormatter {}, output);
}
output