]> Repositorios git - scryer-prolog.git/commitdiff
correct space formatting in heap_print
authorMark Thom <[email protected]>
Wed, 19 Dec 2018 07:26:46 +0000 (00:26 -0700)
committerMark Thom <[email protected]>
Wed, 19 Dec 2018 07:26:46 +0000 (00:26 -0700)
src/prolog/heap_print.rs
src/tests.rs

index f119e7f7f4051324760fbed6eaa1e0b76f817092..4c577974bc1e771419db0e6fa61239b87aeb227e 100644 (file)
@@ -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<Cell<bool>>),
     CloseList(Rc<Cell<bool>>),
     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<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>
 {
     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<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,
                           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<DirectedOp>) {
         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 =>
index 4910ff263ba55295cf706d284d73bb5a02b598e4..9602fba8a3c392fd2b7b50ac06be4f2b93497cd1 100644 (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 {
         self.results
     }