correct space formatting in heap_print

This commit is contained in:
Mark Thom
2018-12-19 00:26:46 -07:00
parent 9064f73655
commit 6f0018c3e0
2 changed files with 65 additions and 23 deletions

View File

@@ -13,10 +13,19 @@ use std::rc::Rc;
#[derive(Clone)] #[derive(Clone)]
pub enum DirectedOp { pub enum DirectedOp {
Left(ClauseName), Left(ClauseName, bool), // bool is true if infix.
Right(ClauseName), Right(ClauseName),
} }
impl DirectedOp {
fn as_str(&self) -> &str {
match self {
&DirectedOp::Left(ref name, _) | &DirectedOp::Right(ref name) =>
name.as_str()
}
}
}
#[derive(Clone)] #[derive(Clone)]
pub enum TokenOrRedirect { pub enum TokenOrRedirect {
Atom(ClauseName), Atom(ClauseName),
@@ -30,6 +39,7 @@ pub enum TokenOrRedirect {
OpenList(Rc<Cell<bool>>), OpenList(Rc<Cell<bool>>),
CloseList(Rc<Cell<bool>>), CloseList(Rc<Cell<bool>>),
HeadTailSeparator, HeadTailSeparator,
Space
} }
pub trait HCValueOutputter { pub trait HCValueOutputter {
@@ -39,6 +49,7 @@ pub trait HCValueOutputter {
fn push_char(&mut self, char); fn push_char(&mut self, char);
fn append(&mut self, &str); fn append(&mut self, &str);
fn begin_new_var(&mut self); fn begin_new_var(&mut self);
fn insert_from_end(&mut self, usize, char);
fn result(self) -> Self::Output; fn result(self) -> Self::Output;
fn ends_with(&self, &str) -> bool; fn ends_with(&self, &str) -> bool;
fn len(&self) -> usize; fn len(&self) -> usize;
@@ -70,6 +81,10 @@ impl HCValueOutputter for PrinterOutputter {
} }
} }
fn insert_from_end(&mut self, idx: usize, c: char) {
self.contents.insert(idx, c);
}
fn result(self) -> Self::Output { fn result(self) -> Self::Output {
self.contents self.contents
} }
@@ -134,12 +149,12 @@ 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 ambiguity_check($atom, $op) { match $self.ambiguity_check($atom, $op) {
Some(DirectedOp::Left(_)) => { Some(DirectedOp::Left(..)) => {
$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(' ');
}, },
@@ -224,20 +239,6 @@ fn non_quoted_token<Iter: Iterator<Item=char>>(mut iter: Iter) -> bool {
} }
} }
// return op itself if there is an ambiguity to indicate the direction the op
// lies, None otherwise.
fn ambiguity_check(atom: &str, op: &Option<DirectedOp>) -> Option<DirectedOp>
{
match op {
&Some(DirectedOp::Left(ref lop)) if continues_with_append(lop.as_str(), atom) =>
Some(DirectedOp::Left(lop.clone())),
&Some(DirectedOp::Right(ref rop)) if continues_with_append(atom, rop.as_str()) =>
Some(DirectedOp::Right(rop.clone())),
_ =>
None
}
}
impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
{ {
pub fn new(machine_st: &'a MachineState, output: Outputter) -> Self pub fn new(machine_st: &'a MachineState, output: Outputter) -> Self
@@ -252,6 +253,29 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
ignore_ops: false } ignore_ops: false }
} }
// return op itself if there is an ambiguity to indicate the direction the op
// lies, None otherwise.
fn ambiguity_check(&mut self, atom: &str, op: &Option<DirectedOp>) -> Option<DirectedOp>
{
match op {
&Some(DirectedOp::Left(ref lop, false)) if continues_with_append(lop.as_str(), atom) =>
Some(DirectedOp::Left(lop.clone(), false)),
&Some(DirectedOp::Left(ref lop, true)) =>
if self.outputter.ends_with(&format!(" {}", lop.as_str())) {
Some(DirectedOp::Left(lop.clone(), true))
} else if continues_with_append(lop.as_str(), atom) {
self.outputter.insert_from_end(lop.as_str().len(), ' ');
Some(DirectedOp::Left(lop.clone(), true))
} else {
None
},
&Some(DirectedOp::Right(ref rop)) if continues_with_append(atom, rop.as_str()) =>
Some(DirectedOp::Right(rop.clone())),
_ =>
None
}
}
pub fn from_heap_locs(machine_st: &'a MachineState, output: Outputter, pub fn from_heap_locs(machine_st: &'a MachineState, output: Outputter,
heap_locs: &'a HeapVarDict) heap_locs: &'a HeapVarDict)
-> Self -> Self
@@ -276,11 +300,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
self.state_stack.push(TokenOrRedirect::CompositeRedirect(DirectedOp::Right(ct.name()))); self.state_stack.push(TokenOrRedirect::CompositeRedirect(DirectedOp::Right(ct.name())));
}, },
Fixity::Pre => { Fixity::Pre => {
self.state_stack.push(TokenOrRedirect::CompositeRedirect(DirectedOp::Left(ct.name()))); let left_directed_op = DirectedOp::Left(ct.name(), false);
self.state_stack.push(TokenOrRedirect::CompositeRedirect(left_directed_op));
self.state_stack.push(TokenOrRedirect::Op(ct.name(), fixity)); self.state_stack.push(TokenOrRedirect::Op(ct.name(), fixity));
}, },
Fixity::In => { Fixity::In => {
self.state_stack.push(TokenOrRedirect::CompositeRedirect(DirectedOp::Left(ct.name()))); let left_directed_op = DirectedOp::Left(ct.name(), true);
self.state_stack.push(TokenOrRedirect::CompositeRedirect(left_directed_op));
self.state_stack.push(TokenOrRedirect::Op(ct.name(), fixity)); self.state_stack.push(TokenOrRedirect::Op(ct.name(), fixity));
self.state_stack.push(TokenOrRedirect::CompositeRedirect(DirectedOp::Right(ct.name()))); self.state_stack.push(TokenOrRedirect::CompositeRedirect(DirectedOp::Right(ct.name())));
} }
@@ -416,7 +444,11 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
fn print_constant(&mut self, c: Constant, op: &Option<DirectedOp>) { fn print_constant(&mut self, c: Constant, op: &Option<DirectedOp>) {
match c { match c {
Constant::Atom(ref atom, Some(fixity)) => { Constant::Atom(ref atom, Some(fixity)) => {
if op.is_some() { if let Some(ref op) = op {
if self.outputter.ends_with(&format!(" {}", op.as_str())) {
self.outputter.push_char(' ');
}
self.outputter.push_char('('); self.outputter.push_char('(');
} }
@@ -512,8 +544,12 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
let ct = ClauseType::from(name.clone(), arity, Some(fixity)); let ct = ClauseType::from(name.clone(), arity, Some(fixity));
self.format_clause(iter, arity, ct); self.format_clause(iter, arity, ct);
if op.is_some() { if let Some(ref op) = op {
self.state_stack.push(TokenOrRedirect::Open); self.state_stack.push(TokenOrRedirect::Open);
if self.outputter.ends_with(&format!(" {}", op.as_str())) {
self.state_stack.push(TokenOrRedirect::Space);
}
} }
}, },
HeapCellValue::NamedStr(0, name, fixity) => HeapCellValue::NamedStr(0, name, fixity) =>
@@ -575,6 +611,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
self.handle_heap_term(&mut iter, Some(op)), self.handle_heap_term(&mut iter, Some(op)),
TokenOrRedirect::Redirect => TokenOrRedirect::Redirect =>
self.handle_heap_term(&mut iter, None), self.handle_heap_term(&mut iter, None),
TokenOrRedirect::Space =>
self.outputter.push_char(' '),
TokenOrRedirect::Close => TokenOrRedirect::Close =>
self.outputter.push_char(')'), self.outputter.push_char(')'),
TokenOrRedirect::Open => TokenOrRedirect::Open =>

View File

@@ -50,6 +50,10 @@ impl HCValueOutputter for TestOutputter {
} }
} }
fn insert_from_end(&mut self, idx: usize, c: char) {
self.focus.insert(idx, c);
}
fn result(self) -> Self::Output { fn result(self) -> Self::Output {
self.results self.results
} }