]> Repositorios git - scryer-prolog.git/commitdiff
fix odd response, toplevel issues
authorMark Thom <[email protected]>
Sun, 28 Apr 2019 23:19:16 +0000 (17:19 -0600)
committerMark Thom <[email protected]>
Sun, 28 Apr 2019 23:19:16 +0000 (17:19 -0600)
Cargo.toml
src/prolog/heap_print.rs
src/prolog/machine/mod.rs

index fbd78ddbc99bb08220f787af96d5e3759ab67677..384e1f8f41f575c6f893de27a81d612cd9fa61c2 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "scryer-prolog"
-version = "0.8.72"
+version = "0.8.73"
 authors = ["Mark Thom <[email protected]>"]
 repository = "https://github.com/mthom/scryer-prolog"
 description = "A modern Prolog implementation written mostly in Rust."
index 4ec6ef16cb7e60c7e2af5571c2df51b6d990299a..c27301d2bc2a755f5a0320b58b58b21bb0a62347 100644 (file)
@@ -195,7 +195,11 @@ impl HCValueOutputter for PrinterOutputter {
         PrinterOutputter { contents: String::new() }
     }
 
-    fn append(&mut self, contents: &str) {
+    fn append(&mut self, contents: &str) {        
+        if requires_space(&self.contents, contents) {
+            self.push_char(' ');
+        }
+        
         self.contents += contents;
     }
 
@@ -312,7 +316,7 @@ macro_rules! push_space_if_amb {
     )
 }
 
-fn requires_space(atom: &str, op: &str) -> bool {
+pub fn requires_space(atom: &str, op: &str) -> bool {
     match atom.chars().last() {
         Some(ac) => op.chars().next().map(|oc| {
             if ac == '0' {
@@ -571,7 +575,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
     #[inline]
     fn append_str(&mut self, s: &str) {
         self.last_item_idx = self.outputter.len();
-        self.outputter.append(s);
+        self.outputter.append(s);            
     }
 
     fn offset_as_string(&self, addr: Addr) -> Option<String> {
index 1620ddc98f05a6eddad955ae5f6664db2a2063c5..03802f2e0a1da7f4ee255c905d33f1bb9658bba3 100644 (file)
@@ -440,6 +440,18 @@ impl Machine {
         self.machine_st.p = CodePtr::Local(p);
     }
 
+    fn propagate_exception_to_toplevel(&mut self, snapshot: MachineState) {
+        let ball = self.machine_st.ball.take();
+
+        self.machine_st.absorb_snapshot(snapshot);
+        self.machine_st.ball = ball;
+
+        let stub = self.machine_st.copy_and_align_ball();
+        self.machine_st.throw_exception(stub);
+
+        return;
+    }
+
     fn handle_eval_session(&mut self, result: EvalSession, snapshot: MachineState) {
         match result {
             EvalSession::InitialQuerySuccess(alloc_locs, mut heap_locs) =>
@@ -471,12 +483,15 @@ impl Machine {
 
                     if !attr_goals.is_empty() {
                         if bindings.is_empty() {
-                            write!(raw_stdout, "{}", attr_goals).unwrap();
+                            let space = if requires_space(&attr_goals, ".") { " " } else { "" };
+                            write!(raw_stdout, "{}{}", attr_goals, space).unwrap();
                         } else {
-                            write!(raw_stdout, "{}, {}", bindings, attr_goals).unwrap();
+                            let space = if requires_space(&attr_goals, ".") { " " } else { "" };
+                            write!(raw_stdout, "{}, {}{}", bindings, attr_goals, space).unwrap();
                         }
                     } else if !bindings.is_empty() {
-                        write!(raw_stdout, "{}", bindings).unwrap();
+                        let space = if requires_space(&bindings, ".") { " " } else { "" };
+                        write!(raw_stdout, "{}{}", bindings, space).unwrap();
                     }
 
                     if self.machine_st.b > 0 {
@@ -494,13 +509,17 @@ impl Machine {
                         let mut raw_stdout = stdout().into_raw_mode().unwrap();
 
                         match result {
-                            EvalSession::QueryFailure => {
-                                write!(raw_stdout, "false.\r\n").unwrap();
-                                raw_stdout.flush().unwrap();
-
-                                self.machine_st.absorb_snapshot(snapshot);
-                                return;
-                            },
+                            EvalSession::QueryFailure =>
+                                if self.machine_st.ball.stub.len() > 0 {
+                                    self.propagate_exception_to_toplevel(snapshot);
+                                    return;
+                                } else {
+                                    write!(raw_stdout, "false.\r\n").unwrap();
+                                    raw_stdout.flush().unwrap();
+
+                                    self.machine_st.absorb_snapshot(snapshot);
+                                    return;
+                                },
                             EvalSession::Error(err) => {
                                 self.machine_st.absorb_snapshot(snapshot);
                                 self.throw_session_error(err, (clause_name!("repl"), 0));
@@ -525,15 +544,7 @@ impl Machine {
             },
             EvalSession::QueryFailure =>
                 if self.machine_st.ball.stub.len() > 0 {
-                    let ball = self.machine_st.ball.take();
-
-                    self.machine_st.absorb_snapshot(snapshot);
-                    self.machine_st.ball = ball;
-
-                    let stub = self.machine_st.copy_and_align_ball();
-                    self.machine_st.throw_exception(stub);
-
-                    return;
+                    return self.propagate_exception_to_toplevel(snapshot);
                 } else {
                     println!("false.");
                 },
@@ -658,20 +669,27 @@ impl Machine {
 
 
 impl MachineState {
-    fn print_query(&self, addr: Addr, op_dir: &OpDir, var_dict: &HeapVarDict) -> PrinterOutputter
+    fn print_query(&mut self, addr: Addr, op_dir: &OpDir, var_dict: &HeapVarDict) -> PrinterOutputter
     {
-        let output = PrinterOutputter::new();
-        let mut printer = HCPrinter::from_heap_locs(&self, op_dir, output, var_dict);
-
-        printer.quoted = true;
-        printer.numbervars = false;
-        printer.drop_toplevel_spec();
-
-        printer.see_all_locs();
+        let flags = self.flags;
+        
+        let mut output = {
+            self.flags = MachineFlags { double_quotes: DoubleQuotes::Atom };
+            
+            let output = PrinterOutputter::new();
+            let mut printer = HCPrinter::from_heap_locs(&self, op_dir, output, var_dict);            
+
+            printer.quoted = true;
+            printer.numbervars = false;
+            printer.drop_toplevel_spec();
+
+            printer.see_all_locs();
+            printer.print(addr)
+        };
 
-        let mut output = printer.print(addr);
+        self.flags = flags;
 
-        output.push_char('.');
+        output.append(".");
         output
     }
 
@@ -818,9 +836,9 @@ impl MachineState {
                         if self.fail {
                             break;
                         }
-                        
+
                         let cp = self.p.local();
-                        self.run_verify_attr_interrupt(cp);                    
+                        self.run_verify_attr_interrupt(cp);
                     }
                 },
                 _ =>