From fb023c99c13f13340b4f7f01276f832c9ba346c5 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Mon, 29 Apr 2019 22:44:53 -0600 Subject: [PATCH] respect ambiguity with ., add ... to indicate more answers --- Cargo.toml | 2 +- src/prolog/heap_print.rs | 12 +++++----- src/prolog/machine/machine_state_impl.rs | 2 +- src/prolog/machine/mod.rs | 30 +++++++++++++++--------- src/prolog/toplevel.pl | 2 +- src/prolog/write.rs | 17 +++++--------- 6 files changed, 34 insertions(+), 31 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9ff86ad0..baafadc6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "scryer-prolog" -version = "0.8.75" +version = "0.8.76" authors = ["Mark Thom "] repository = "https://github.com/mthom/scryer-prolog" description = "A modern Prolog implementation written mostly in Rust." diff --git a/src/prolog/heap_print.rs b/src/prolog/heap_print.rs index c27301d2..286631e6 100644 --- a/src/prolog/heap_print.rs +++ b/src/prolog/heap_print.rs @@ -195,11 +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; } @@ -320,7 +320,7 @@ pub fn requires_space(atom: &str, op: &str) -> bool { match atom.chars().last() { Some(ac) => op.chars().next().map(|oc| { if ac == '0' { - oc == 'b' || oc == 'x' || oc == 'o' || !non_quoted_token(op.chars()) + oc == 'b' || oc == 'x' || oc == 'o' || oc == '\'' } else if alpha_numeric_char!(ac) { oc == '(' || alpha_numeric_char!(oc) } else if graphic_token_char!(ac) { @@ -575,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 { @@ -795,7 +795,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> } } else if !self.at_cdr("") { self.append_str("[]"); - }, + }, DoubleQuotes::Atom => { let borrowed_str = s.borrow(); @@ -805,7 +805,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> } } } - + fn push_list(&mut self) { let cell = Rc::new(Cell::new(true)); diff --git a/src/prolog/machine/machine_state_impl.rs b/src/prolog/machine/machine_state_impl.rs index 78e24f8f..1b206b1a 100644 --- a/src/prolog/machine/machine_state_impl.rs +++ b/src/prolog/machine/machine_state_impl.rs @@ -1828,7 +1828,7 @@ impl MachineState { } else { self.fail = true; } - }, + } _ => // 8.5.2.3 d) return Err(self.error_form(MachineError::type_error(ValidType::Compound, term), stub)) diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index 03802f2e..d076ea8b 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -465,8 +465,10 @@ impl Machine { if !(self.machine_st.b > 0) { if bindings.is_empty() { + let space = if requires_space(&attr_goals, ".") { " " } else { "" }; + if !attr_goals.is_empty() { - println!("{}.", attr_goals); + println!("{}{}.", attr_goals, space); } else { println!("true."); } @@ -483,24 +485,24 @@ impl Machine { if !attr_goals.is_empty() { if bindings.is_empty() { - let space = if requires_space(&attr_goals, ".") { " " } else { "" }; - write!(raw_stdout, "{}{}", attr_goals, space).unwrap(); + write!(raw_stdout, "{}", attr_goals).unwrap(); } else { - let space = if requires_space(&attr_goals, ".") { " " } else { "" }; - write!(raw_stdout, "{}, {}{}", bindings, attr_goals, space).unwrap(); + write!(raw_stdout, "{}, {}", bindings, attr_goals).unwrap(); } } else if !bindings.is_empty() { - let space = if requires_space(&bindings, ".") { " " } else { "" }; - write!(raw_stdout, "{}{}", bindings, space).unwrap(); + write!(raw_stdout, "{}", bindings).unwrap(); } if self.machine_st.b > 0 { raw_stdout.flush().unwrap(); - let result = match next_keypress(raw_stdout) { - ContinueResult::ContinueQuery => - self.continue_query(&alloc_locs, &mut heap_locs), + let result = match next_keypress() { + ContinueResult::ContinueQuery => { + write!(raw_stdout, " ;\r\n").unwrap(); + self.continue_query(&alloc_locs, &mut heap_locs) + }, ContinueResult::Conclude => { + write!(raw_stdout, " ...\r\n").unwrap(); self.machine_st.absorb_snapshot(snapshot); return; } @@ -531,7 +533,13 @@ impl Machine { if bindings.is_empty() && attr_goals.is_empty() { write!(raw_stdout, "true.\r\n").unwrap(); } else { - write!(raw_stdout, ".\r\n").unwrap(); + let space = if !attr_goals.is_empty() { + if requires_space(&attr_goals, ".") { " " } else { "" } + } else { + if requires_space(&bindings, ".") { " " } else { "" } + }; + + write!(raw_stdout, "{}.\r\n", space).unwrap(); } break; diff --git a/src/prolog/toplevel.pl b/src/prolog/toplevel.pl index b8c5f9a8..df0f808a 100644 --- a/src/prolog/toplevel.pl +++ b/src/prolog/toplevel.pl @@ -15,6 +15,6 @@ read_and_match :- !. '$print_exception'(E) :- - write_term('error: exception thrown: ', [quoted(false)]), + write_term('caught: ', [quoted(false)]), writeq(E), nl. diff --git a/src/prolog/write.rs b/src/prolog/write.rs index 682e7e03..7a4f193c 100644 --- a/src/prolog/write.rs +++ b/src/prolog/write.rs @@ -6,9 +6,8 @@ use prolog::machine::machine_indices::*; use termion::input::TermRead; use termion::event::Key; -use termion::raw::{RawTerminal}; -use std::io::{Write, stdin}; +use std::io::stdin; use std::fmt; impl fmt::Display for LocalCodePtr { @@ -364,20 +363,16 @@ pub enum ContinueResult { } pub -fn next_keypress(mut stdout: RawTerminal) -> ContinueResult +fn next_keypress() -> ContinueResult { let stdin = stdin(); for c in stdin.keys() { match c.unwrap() { - Key::Char(' ') | Key::Char(';') => { - write!(stdout, " ;\r\n").unwrap(); - return ContinueResult::ContinueQuery; - }, - Key::Char('.') => { - write!(stdout, " .\r\n").unwrap(); - return ContinueResult::Conclude; - }, + Key::Char(' ') | Key::Char(';') => + return ContinueResult::ContinueQuery, + Key::Char('.') => + return ContinueResult::Conclude, _ => {} } } -- 2.54.0