smooth out ambiguity check

This commit is contained in:
Mark Thom
2018-10-08 23:23:52 -06:00
parent b2d9673593
commit 2b32d2d94e

View File

@@ -208,14 +208,9 @@ pub struct HCPrinter<'a, Formatter, Outputter> {
printed_vars: HashSet<Addr> printed_vars: HashSet<Addr>
} }
#[derive(Clone, Copy)]
enum TrailingType {
Atom, Var
}
macro_rules! push_space_if_amb { macro_rules! push_space_if_amb {
($self:expr, $atom:expr, $tt:expr, $op:expr, $action:block) => ( ($self:expr, $atom:expr, $op:expr, $action:block) => (
match $self.ambiguity_check($atom, $tt, $op) { match $self.ambiguity_check($atom, $op) {
Some(DirectedOp::Left(_)) => { Some(DirectedOp::Left(_)) => {
$self.outputter.push_char(' '); $self.outputter.push_char(' ');
$action; $action;
@@ -229,32 +224,22 @@ macro_rules! push_space_if_amb {
) )
} }
fn continues_with_append(atom: &str, tt: TrailingType, op: &str) -> bool { fn continues_with_append(atom: &str, op: &str) -> bool {
match tt { match atom.chars().next() {
TrailingType::Atom => match atom.chars().next() { Some(ac) => op.chars().next().map(|oc| {
Some(ac) => op.chars().next().map(|oc| { if alpha_char!(ac) {
if alpha_char!(ac) { alpha_numeric_char!(oc)
alpha_numeric_char!(oc) } else if graphic_token_char!(ac) {
} else if graphic_token_char!(ac) { graphic_char!(oc)
graphic_char!(oc) } else if variable_indicator_char!(ac) {
} else { alpha_numeric_char!(oc)
false } else if capital_letter_char!(ac) {
} alpha_numeric_char!(oc)
}).unwrap_or(false), } else {
None => false, false
}, }
TrailingType::Var => match atom.chars().next() { }).unwrap_or(false),
Some(ac) => op.chars().next().map(|oc| { _ => false
if variable_indicator_char!(ac) {
alpha_numeric_char!(oc)
} else if capital_letter_char!(ac) {
alpha_numeric_char!(oc)
} else {
false
}
}).unwrap_or(false),
None => false
}
} }
} }
@@ -350,13 +335,12 @@ impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter>
// return op itself if there is an ambiguity to indicate the direction the op // return op itself if there is an ambiguity to indicate the direction the op
// lies, None otherwise. // lies, None otherwise.
fn ambiguity_check(&mut self, atom: &str, tt: TrailingType, op: &Option<DirectedOp>) fn ambiguity_check(&mut self, atom: &str, op: &Option<DirectedOp>) -> Option<DirectedOp>
-> Option<DirectedOp>
{ {
match op { match op {
&Some(DirectedOp::Left(ref lop)) if continues_with_append(lop.as_str(), tt, atom) => &Some(DirectedOp::Left(ref lop)) if continues_with_append(lop.as_str(), atom) =>
Some(DirectedOp::Left(lop.clone())), Some(DirectedOp::Left(lop.clone())),
&Some(DirectedOp::Right(ref rop)) if continues_with_append(atom, tt, rop.as_str()) => &Some(DirectedOp::Right(ref rop)) if continues_with_append(atom, rop.as_str()) =>
Some(DirectedOp::Right(rop.clone())), Some(DirectedOp::Right(rop.clone())),
_ => _ =>
None None
@@ -375,7 +359,7 @@ impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter>
return iter.next(); return iter.next();
} else { } else {
iter.stack().pop(); iter.stack().pop();
push_space_if_amb!(self, &var, TrailingType::Var, op, { push_space_if_amb!(self, &var, op, {
self.outputter.append(&var); self.outputter.append(&var);
}); });
@@ -386,7 +370,7 @@ impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter>
iter.stack().pop(); iter.stack().pop();
if let Some(offset_str) = self.offset_as_string(addr) { if let Some(offset_str) = self.offset_as_string(addr) {
push_space_if_amb!(self, &offset_str, TrailingType::Var, op, { push_space_if_amb!(self, &offset_str, op, {
self.outputter.append(offset_str.as_str()); self.outputter.append(offset_str.as_str());
}); });
} }
@@ -453,7 +437,7 @@ impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter>
} }
}, },
Constant::Atom(ref atom, None) => Constant::Atom(ref atom, None) =>
push_space_if_amb!(self, atom.as_str(), TrailingType::Atom, &op, { push_space_if_amb!(self, atom.as_str(), &op, {
self.print_atom(atom, None); self.print_atom(atom, None);
}), }),
Constant::Char(c) if non_quoted_token(once(c)) => Constant::Char(c) if non_quoted_token(once(c)) =>
@@ -467,20 +451,20 @@ impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter>
self.outputter.append("[]"), self.outputter.append("[]"),
Constant::Number(Number::Float(fl)) => Constant::Number(Number::Float(fl)) =>
if &fl == &OrderedFloat(0f64) { if &fl == &OrderedFloat(0f64) {
push_space_if_amb!(self, "0", TrailingType::Atom, &op, { push_space_if_amb!(self, "0", &op, {
self.outputter.append("0"); self.outputter.append("0");
}); });
} else { } else {
let output_str = format!("{}", fl); let output_str = format!("{}", fl);
push_space_if_amb!(self, &output_str, TrailingType::Atom, &op, { push_space_if_amb!(self, &output_str, &op, {
self.outputter.append(&output_str); self.outputter.append(&output_str);
}); });
}, },
Constant::Number(n) => { Constant::Number(n) => {
let output_str = format!("{}", n); let output_str = format!("{}", n);
push_space_if_amb!(self, &output_str, TrailingType::Atom, &op, { push_space_if_amb!(self, &output_str, &op, {
self.outputter.append(&output_str); self.outputter.append(&output_str);
}); });
}, },
@@ -539,10 +523,11 @@ impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter>
self.state_stack.push(TokenOrRedirect::Open); self.state_stack.push(TokenOrRedirect::Open);
} }
}, },
HeapCellValue::NamedStr(arity, name, fixity) => { HeapCellValue::NamedStr(arity, name, fixity) =>
let ct = ClauseType::from(name, arity, fixity); push_space_if_amb!(self, name.as_str(), &op, {
self.formatter.format_clause(iter, arity, ct, &mut self.state_stack) let ct = ClauseType::from(name, arity, fixity);
}, self.formatter.format_clause(iter, arity, ct, &mut self.state_stack)
}),
HeapCellValue::Addr(Addr::Con(Constant::EmptyList)) => HeapCellValue::Addr(Addr::Con(Constant::EmptyList)) =>
if !self.at_cdr("") { if !self.at_cdr("") {
self.outputter.append("[]"); self.outputter.append("[]");
@@ -553,7 +538,7 @@ impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter>
self.push_list(), self.push_list(),
HeapCellValue::Addr(addr) => HeapCellValue::Addr(addr) =>
if let Some(offset_str) = self.offset_as_string(addr) { if let Some(offset_str) = self.offset_as_string(addr) {
push_space_if_amb!(self, &offset_str, TrailingType::Var, &op, { push_space_if_amb!(self, &offset_str, &op, {
self.outputter.append(offset_str.as_str()); self.outputter.append(offset_str.as_str());
}) })
} }