From 6f0018c3e0a5256a6df2873b6c72ab805a3d4990 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Wed, 19 Dec 2018 00:26:46 -0700 Subject: [PATCH] correct space formatting in heap_print --- src/prolog/heap_print.rs | 84 +++++++++++++++++++++++++++++----------- src/tests.rs | 4 ++ 2 files changed, 65 insertions(+), 23 deletions(-) diff --git a/src/prolog/heap_print.rs b/src/prolog/heap_print.rs index f119e7f7..4c577974 100644 --- a/src/prolog/heap_print.rs +++ b/src/prolog/heap_print.rs @@ -13,10 +13,19 @@ use std::rc::Rc; #[derive(Clone)] pub enum DirectedOp { - Left(ClauseName), + Left(ClauseName, bool), // bool is true if infix. Right(ClauseName), } +impl DirectedOp { + fn as_str(&self) -> &str { + match self { + &DirectedOp::Left(ref name, _) | &DirectedOp::Right(ref name) => + name.as_str() + } + } +} + #[derive(Clone)] pub enum TokenOrRedirect { Atom(ClauseName), @@ -30,6 +39,7 @@ pub enum TokenOrRedirect { OpenList(Rc>), CloseList(Rc>), HeadTailSeparator, + Space } pub trait HCValueOutputter { @@ -39,10 +49,11 @@ pub trait HCValueOutputter { fn push_char(&mut self, char); fn append(&mut self, &str); fn begin_new_var(&mut self); + fn insert_from_end(&mut self, usize, char); fn result(self) -> Self::Output; fn ends_with(&self, &str) -> bool; fn len(&self) -> usize; - fn truncate(&mut self, usize); + fn truncate(&mut self, usize); } pub struct PrinterOutputter { @@ -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 { self.contents } @@ -134,12 +149,12 @@ pub struct HCPrinter<'a, Outputter> { macro_rules! push_space_if_amb { ($self:expr, $atom:expr, $op:expr, $action:block) => ( - match ambiguity_check($atom, $op) { - Some(DirectedOp::Left(_)) => { + match $self.ambiguity_check($atom, $op) { + Some(DirectedOp::Left(..)) => { $self.outputter.push_char(' '); $action; }, - Some(DirectedOp::Right(_)) => { + Some(DirectedOp::Right(..)) => { $action; $self.outputter.push_char(' '); }, @@ -224,20 +239,6 @@ fn non_quoted_token>(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) -> Option -{ - 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> { pub fn new(machine_st: &'a MachineState, output: Outputter) -> Self @@ -252,6 +253,29 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> 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) -> Option + { + 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, heap_locs: &'a HeapVarDict) -> Self @@ -276,11 +300,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> self.state_stack.push(TokenOrRedirect::CompositeRedirect(DirectedOp::Right(ct.name()))); }, 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)); }, 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::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) { match c { 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('('); } @@ -512,8 +544,12 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> let ct = ClauseType::from(name.clone(), arity, Some(fixity)); self.format_clause(iter, arity, ct); - if op.is_some() { + if let Some(ref op) = op { 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) => @@ -575,6 +611,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> self.handle_heap_term(&mut iter, Some(op)), TokenOrRedirect::Redirect => self.handle_heap_term(&mut iter, None), + TokenOrRedirect::Space => + self.outputter.push_char(' '), TokenOrRedirect::Close => self.outputter.push_char(')'), TokenOrRedirect::Open => diff --git a/src/tests.rs b/src/tests.rs index 4910ff26..9602fba8 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -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 { self.results } -- 2.54.0