respect ambiguity with ., add ... to indicate more answers

This commit is contained in:
Mark Thom
2019-04-29 22:44:53 -06:00
parent 14d629492d
commit fb023c99c1
6 changed files with 34 additions and 31 deletions

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "scryer-prolog" name = "scryer-prolog"
version = "0.8.75" version = "0.8.76"
authors = ["Mark Thom <markjordanthom@gmail.com>"] authors = ["Mark Thom <markjordanthom@gmail.com>"]
repository = "https://github.com/mthom/scryer-prolog" repository = "https://github.com/mthom/scryer-prolog"
description = "A modern Prolog implementation written mostly in Rust." description = "A modern Prolog implementation written mostly in Rust."

View File

@@ -195,11 +195,11 @@ impl HCValueOutputter for PrinterOutputter {
PrinterOutputter { contents: String::new() } PrinterOutputter { contents: String::new() }
} }
fn append(&mut self, contents: &str) { fn append(&mut self, contents: &str) {
if requires_space(&self.contents, contents) { if requires_space(&self.contents, contents) {
self.push_char(' '); self.push_char(' ');
} }
self.contents += contents; self.contents += contents;
} }
@@ -320,7 +320,7 @@ pub fn requires_space(atom: &str, op: &str) -> bool {
match atom.chars().last() { match atom.chars().last() {
Some(ac) => op.chars().next().map(|oc| { Some(ac) => op.chars().next().map(|oc| {
if ac == '0' { 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) { } else if alpha_numeric_char!(ac) {
oc == '(' || alpha_numeric_char!(oc) oc == '(' || alpha_numeric_char!(oc)
} else if graphic_token_char!(ac) { } else if graphic_token_char!(ac) {
@@ -575,7 +575,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
#[inline] #[inline]
fn append_str(&mut self, s: &str) { fn append_str(&mut self, s: &str) {
self.last_item_idx = self.outputter.len(); self.last_item_idx = self.outputter.len();
self.outputter.append(s); self.outputter.append(s);
} }
fn offset_as_string(&self, addr: Addr) -> Option<String> { fn offset_as_string(&self, addr: Addr) -> Option<String> {
@@ -795,7 +795,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
} }
} else if !self.at_cdr("") { } else if !self.at_cdr("") {
self.append_str("[]"); self.append_str("[]");
}, },
DoubleQuotes::Atom => { DoubleQuotes::Atom => {
let borrowed_str = s.borrow(); let borrowed_str = s.borrow();
@@ -805,7 +805,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
} }
} }
} }
fn push_list(&mut self) { fn push_list(&mut self) {
let cell = Rc::new(Cell::new(true)); let cell = Rc::new(Cell::new(true));

View File

@@ -1828,7 +1828,7 @@ impl MachineState {
} else { } else {
self.fail = true; self.fail = true;
} }
}, }
_ => // 8.5.2.3 d) _ => // 8.5.2.3 d)
return Err(self.error_form(MachineError::type_error(ValidType::Compound, term), return Err(self.error_form(MachineError::type_error(ValidType::Compound, term),
stub)) stub))

View File

@@ -465,8 +465,10 @@ impl Machine {
if !(self.machine_st.b > 0) { if !(self.machine_st.b > 0) {
if bindings.is_empty() { if bindings.is_empty() {
let space = if requires_space(&attr_goals, ".") { " " } else { "" };
if !attr_goals.is_empty() { if !attr_goals.is_empty() {
println!("{}.", attr_goals); println!("{}{}.", attr_goals, space);
} else { } else {
println!("true."); println!("true.");
} }
@@ -483,24 +485,24 @@ impl Machine {
if !attr_goals.is_empty() { if !attr_goals.is_empty() {
if bindings.is_empty() { if bindings.is_empty() {
let space = if requires_space(&attr_goals, ".") { " " } else { "" }; write!(raw_stdout, "{}", attr_goals).unwrap();
write!(raw_stdout, "{}{}", attr_goals, space).unwrap();
} else { } else {
let space = if requires_space(&attr_goals, ".") { " " } else { "" }; write!(raw_stdout, "{}, {}", bindings, attr_goals).unwrap();
write!(raw_stdout, "{}, {}{}", bindings, attr_goals, space).unwrap();
} }
} else if !bindings.is_empty() { } else if !bindings.is_empty() {
let space = if requires_space(&bindings, ".") { " " } else { "" }; write!(raw_stdout, "{}", bindings).unwrap();
write!(raw_stdout, "{}{}", bindings, space).unwrap();
} }
if self.machine_st.b > 0 { if self.machine_st.b > 0 {
raw_stdout.flush().unwrap(); raw_stdout.flush().unwrap();
let result = match next_keypress(raw_stdout) { let result = match next_keypress() {
ContinueResult::ContinueQuery => ContinueResult::ContinueQuery => {
self.continue_query(&alloc_locs, &mut heap_locs), write!(raw_stdout, " ;\r\n").unwrap();
self.continue_query(&alloc_locs, &mut heap_locs)
},
ContinueResult::Conclude => { ContinueResult::Conclude => {
write!(raw_stdout, " ...\r\n").unwrap();
self.machine_st.absorb_snapshot(snapshot); self.machine_st.absorb_snapshot(snapshot);
return; return;
} }
@@ -531,7 +533,13 @@ impl Machine {
if bindings.is_empty() && attr_goals.is_empty() { if bindings.is_empty() && attr_goals.is_empty() {
write!(raw_stdout, "true.\r\n").unwrap(); write!(raw_stdout, "true.\r\n").unwrap();
} else { } 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; break;

View File

@@ -15,6 +15,6 @@ read_and_match :-
!. !.
'$print_exception'(E) :- '$print_exception'(E) :-
write_term('error: exception thrown: ', [quoted(false)]), write_term('caught: ', [quoted(false)]),
writeq(E), writeq(E),
nl. nl.

View File

@@ -6,9 +6,8 @@ use prolog::machine::machine_indices::*;
use termion::input::TermRead; use termion::input::TermRead;
use termion::event::Key; use termion::event::Key;
use termion::raw::{RawTerminal};
use std::io::{Write, stdin}; use std::io::stdin;
use std::fmt; use std::fmt;
impl fmt::Display for LocalCodePtr { impl fmt::Display for LocalCodePtr {
@@ -364,20 +363,16 @@ pub enum ContinueResult {
} }
pub pub
fn next_keypress(mut stdout: RawTerminal<std::io::Stdout>) -> ContinueResult fn next_keypress() -> ContinueResult
{ {
let stdin = stdin(); let stdin = stdin();
for c in stdin.keys() { for c in stdin.keys() {
match c.unwrap() { match c.unwrap() {
Key::Char(' ') | Key::Char(';') => { Key::Char(' ') | Key::Char(';') =>
write!(stdout, " ;\r\n").unwrap(); return ContinueResult::ContinueQuery,
return ContinueResult::ContinueQuery; Key::Char('.') =>
}, return ContinueResult::Conclude,
Key::Char('.') => {
write!(stdout, " .\r\n").unwrap();
return ContinueResult::Conclude;
},
_ => {} _ => {}
} }
} }