]> Repositorios git - scryer-prolog.git/commitdiff
simplify and correct prefix-bracket spacing in heap_print.rs (#1914, #1918)
authorMark <[email protected]>
Tue, 25 Jul 2023 21:03:35 +0000 (15:03 -0600)
committerMark <[email protected]>
Wed, 26 Jul 2023 15:32:54 +0000 (09:32 -0600)
src/heap_print.rs

index 3ca68c4fcb35ed759c68556a19dd7e8228d3f3bd..8be390768d533a227ab9040c8927338e70060416 100644 (file)
@@ -484,7 +484,6 @@ pub struct HCPrinter<'a, Outputter> {
     state_stack: Vec<TokenOrRedirect>,
     toplevel_spec: Option<DirectedOp>,
     last_item_idx: usize,
-    num_ops_on_stack: usize,
     parent_of_first_op: Option<(DirectedOp, usize)>,
     pub var_names: IndexMap<HeapCellValue, VarPtr>,
     pub numbervars_offset: Integer,
@@ -563,7 +562,6 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
             state_stack: vec![],
             toplevel_spec: None,
             last_item_idx: 0,
-            num_ops_on_stack: 0,
             parent_of_first_op: None,
             numbervars: false,
             numbervars_offset: Integer::from(0),
@@ -588,15 +586,18 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
     }
 
     fn set_parent_of_first_op(&mut self, parent_op: Option<DirectedOp>) {
-        self.parent_of_first_op = parent_op.map(|op| (op, self.last_item_idx));
+        if let Some(op) = parent_op {
+            if op.is_left() && op.is_prefix() {
+                self.parent_of_first_op = Some((op, self.last_item_idx));
+            }
+        }
     }
 
-    fn enqueue_op(&mut self, mut max_depth: usize, name: Atom, spec: OpDesc, parent_op: Option<DirectedOp>) {
+    fn enqueue_op(&mut self, mut max_depth: usize, name: Atom, spec: OpDesc) {
         if is_postfix!(spec.get_spec()) {
             if self.max_depth_exhausted(max_depth) {
                 self.iter.pop_stack();
                 self.state_stack.push(TokenOrRedirect::Atom(atom!("...")));
-                return;
             } else if self.check_max_depth(&mut max_depth) {
                 self.iter.pop_stack();
 
@@ -641,7 +642,6 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
                 self.iter.pop_stack();
 
                 self.state_stack.push(TokenOrRedirect::Atom(atom!("...")));
-                return;
             } else if self.check_max_depth(&mut max_depth) {
                 self.iter.pop_stack();
                 self.iter.pop_stack();
@@ -658,12 +658,6 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
                 self.state_stack.push(TokenOrRedirect::CompositeRedirect(max_depth, right_directed_op));
             }
         }
-
-        if self.num_ops_on_stack == 0 {
-            self.set_parent_of_first_op(parent_op);
-        }
-
-        self.num_ops_on_stack += 1;
     }
 
     fn format_struct(&mut self, mut max_depth: usize, arity: usize, name: Atom) -> bool {
@@ -777,7 +771,6 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
         arity: usize,
         name: Atom,
         op_desc: Option<OpDesc>,
-        parent_op: Option<DirectedOp>,
     ) -> bool {
         if self.numbervars && is_numbered_var(name, arity) {
             if self.format_numbered_vars() {
@@ -796,7 +789,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
             }
 
             if !self.ignore_ops && spec.get_prec() > 0 {
-                self.enqueue_op(max_depth, name, spec, parent_op);
+                self.enqueue_op(max_depth, name, spec);
                 return true;
             }
         }
@@ -1064,7 +1057,6 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
                         right_directed_op,
                     ));
 
-                    self.num_ops_on_stack += 1;
                     self.set_parent_of_first_op(parent_op);
                 } else {
                     self.state_stack.push(TokenOrRedirect::Close);
@@ -1385,33 +1377,33 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
 
         if add_brackets {
             self.state_stack.push(TokenOrRedirect::Close);
-            self.format_clause(max_depth, arity, name, Some(op_desc), op);
+            self.format_clause(max_depth, arity, name, Some(op_desc));
             self.state_stack.push(TokenOrRedirect::Open);
 
-            let parent_op = self.parent_of_first_op
-                .and_then(|(parent_op, last_item_idx)| {
-                    // if parent_op isn't printed to the output string
-                    // already, then it doesn't border the present op
-                    // and we should return None.
-                    if self.last_item_idx == last_item_idx {
-                        Some(parent_op)
-                    } else {
-                        None
-                    }
-                });
+            if !self.outputter.ends_with(" ") {
+                let parent_op = self.parent_of_first_op
+                    .and_then(|(parent_op, last_item_idx)| {
+                        // if parent_op isn't printed to the output string
+                        // already, then it doesn't border the present op
+                        // and we should return None.
+                        if self.last_item_idx == last_item_idx {
+                            Some(parent_op)
+                        } else {
+                            None
+                        }
+                    });
 
-            for op in &[op, parent_op] {
-                if let Some(ref op) = &op {
-                    if !self.outputter.ends_with(" ") {
+                for op in &[op, parent_op] {
+                    if let Some(ref op) = &op {
                         if op.is_left() && (op.is_prefix() || requires_space(op.as_atom().as_str(), "(")) {
                             self.state_stack.push(TokenOrRedirect::Space);
-                            break;
+                            return;
                         }
                     }
                 }
             }
         } else {
-            self.format_clause(max_depth, arity, name, Some(op_desc), op);
+            self.format_clause(max_depth, arity, name, Some(op_desc));
         }
     }
 
@@ -1528,7 +1520,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
                     );
                 } else {
                     push_space_if_amb!(printer, name.as_str(), {
-                        printer.format_clause(max_depth, arity, name, None, op);
+                        printer.format_clause(max_depth, arity, name, None);
                     });
                 }
             } else if fetch_op_spec(name, arity, printer.op_dir).is_some() {
@@ -1594,7 +1586,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
                     );
                 } else {
                     push_space_if_amb!(self, name.as_str(), {
-                        self.format_clause(max_depth, arity, name, None, op);
+                        self.format_clause(max_depth, arity, name, None);
                     });
                 }
             }
@@ -1675,10 +1667,12 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
                 TokenOrRedirect::Atom(atom) => self.print_impromptu_atom(atom),
                 TokenOrRedirect::BarAsOp => append_str!(self, " | "),
                 TokenOrRedirect::Char(c) => print_char!(self, self.quoted, c),
-                TokenOrRedirect::Op(atom, ..) => {
-                    self.num_ops_on_stack -= 1;
-                    self.parent_of_first_op = None;
+                TokenOrRedirect::Op(atom, op) => {
                     self.print_op(atom.as_str());
+
+                    if is_prefix!(op.get_spec()) {
+                        self.set_parent_of_first_op(Some(DirectedOp::Left(atom, op)));
+                    }
                 }
                 TokenOrRedirect::NumberedVar(num_var) => append_str!(self, &num_var),
                 TokenOrRedirect::CompositeRedirect(max_depth, op) => {
@@ -2020,5 +2014,21 @@ mod tests {
         all_cells_unmarked(&wam.machine_st.heap);
 
         assert_eq!(&wam.parse_and_print_term("[a|[b|c]*d].").unwrap(), "[a|[b|c]*d]");
+
+        all_cells_unmarked(&wam.machine_st.heap);
+
+        wam.op_dir.insert(
+            (atom!("fy"), Fixity::Pre),
+            OpDesc::build_with(9, FY as u8),
+        );
+
+        wam.op_dir.insert(
+            (atom!("yf"), Fixity::Post),
+            OpDesc::build_with(9, YF as u8),
+        );
+
+        assert_eq!(&wam.parse_and_print_term("(fy (fy 1)yf)yf.").unwrap(), "(fy (fy 1)yf)yf");
+
+        assert_eq!(&wam.parse_and_print_term("fy(fy(yf(fy(1)))).").unwrap(), "fy fy (fy 1)yf");
     }
 }