]> Repositorios git - scryer-prolog.git/commitdiff
use ellipses to indicate infinite terms in printer
authorMark Thom <[email protected]>
Fri, 26 Apr 2019 04:27:23 +0000 (22:27 -0600)
committerMark Thom <[email protected]>
Fri, 26 Apr 2019 04:27:23 +0000 (22:27 -0600)
Cargo.toml
src/prolog/heap_print.rs
src/tests.rs

index 3a1749aab5995bb8d7ea5ca1abef1bb25a0fa451..a70338869b85d9f3babb68d9ae2afb80fa6ccfb6 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "scryer-prolog"
-version = "0.8.65"
+version = "0.8.66"
 authors = ["Mark Thom <[email protected]>"]
 repository = "https://github.com/mthom/scryer-prolog"
 description = "A modern Prolog implementation written mostly in Rust."
index 5a2e37346fe72d4b0c7568dfc3a1a9efd3ee59fb..8757b3b77309bdffc71e509cda723f2dfb227a94 100644 (file)
@@ -293,6 +293,7 @@ pub struct HCPrinter<'a, Outputter> {
     heap_locs:    ReverseHeapVarDict,
     printed_vars: HashSet<Addr>,
     last_item_idx: usize,
+    cyclic_terms: HashMap<Addr, usize>,
     pub(crate) numbervars_offset: BigInt,
     pub(crate) numbervars:   bool,
     pub(crate) quoted:       bool,
@@ -407,7 +408,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
                     numbervars: false,
                     numbervars_offset: BigInt::zero(),
                     quoted: false,
-                    ignore_ops: false }
+                    ignore_ops: false,
+                    cyclic_terms: HashMap::new() }
     }
 
     pub fn from_heap_locs(machine_st: &'a MachineState, op_dir: &'a OpDir, output: Outputter,
@@ -601,24 +603,26 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
                     return None;
                 },
                 None => if self.machine_st.is_cyclic_term(addr.clone()) {
-                    if self.printed_vars.contains(&addr) {
-                        iter.stack().pop();
-
-                        if let Some(offset_str) = self.offset_as_string(addr) {
-                            push_space_if_amb!(self, &offset_str, {
-                                self.append_str(&offset_str);
-                            });
+                    match self.cyclic_terms.get(&addr).cloned() {
+                        Some(reps) =>
+                            if reps > 0 {
+                                self.cyclic_terms.insert(addr, reps - 1);
+                                iter.next()
+                            } else {                                
+                                if !self.at_cdr(", ...") {
+                                    push_space_if_amb!(self, "...", {
+                                        self.append_str("...");
+                                    });
+                                }
+
+                                iter.stack().pop();
+                                self.cyclic_terms.remove(&addr);
+                                None
+                            },
+                        None => {
+                            self.cyclic_terms.insert(addr, 2);
+                            iter.next()
                         }
-
-                        None
-                    } else {
-                        if let Some(s) = self.offset_as_string(addr.clone()) {
-                            let var = Rc::new(s);
-                            self.heap_locs.insert(addr.clone(), var);
-                        }
-
-                        self.printed_vars.insert(addr);
-                        iter.next()
                     }
                 } else {
                     iter.next()
@@ -720,16 +724,16 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
                         if self.outputter.ends_with(&format!(" {}", op.as_str())) {
                             result.push(' ');
                         }
-                        
+
                         result.push('(');
                     }
-                    
+
                     result += &self.print_op_addendum(atom.as_str());
-                    
+
                     if op.is_some() {
                         result.push(')');
                     }
-                    
+
                     push_space_if_amb!(self, &result, {
                         self.append_str(&result);
                     });
index 13f73315563834fa877c2e3e93dcd7a5fa076cad..46e09ff958935666f07433fc0833059da7dfd567 100644 (file)
@@ -1526,7 +1526,7 @@ fn test_queries_on_builtins()
     assert_prolog_success!(&mut wam, "X = g(X, Y), Y = f(X), copy_term(Y, f(Z)).",
                            [["Y = f(g(X, Y))", "X = g(X, f(X))", "Z = g(Z, f(Z))"]]);
     assert_prolog_success!(&mut wam, "X = g(X, Y), Y = f(X), copy_term(Y, V).",
-                           [["Y = f(g(X, Y))", "X = g(X, f(X))", "V = f(g(_9, V))"]]);
+                           [["V = f(g(g(g(..., V), V), V))", "X = g(X, f(X))", "Y = f(g(X, Y))"]]);
     assert_prolog_success!(&mut wam, "f(Y,Y,[X,a,[],Y]) = Term, copy_term(Term, NewTerm).",
                            [["NewTerm = f(_16, _16, [_19, a, [], _16])",
                              "Term = f(_0, Y, [_6, a, [], Y])",
@@ -1638,7 +1638,7 @@ fn test_queries_on_builtins()
 
     assert_prolog_failure!(&mut wam, "Pairs = [a-a|Pairs], keysort(Pairs, _).");
     assert_prolog_success!(&mut wam, "Pairs = [a-a|Pairs], catch(keysort(Pairs, _), error(E, _), true).",
-                           [["E = type_error(list, [a-a | _25])", "Pairs = [a-a | Pairs]"]]);
+                           [["E = type_error(list, [a-a, a-a, a-a, ...])", "Pairs = [a-a | Pairs]"]]);
 
     assert_prolog_success!(&mut wam, "keysort([], L).",
                            [["L = []"]]);