respect ambiguity with ., add ... to indicate more answers
This commit is contained in:
@@ -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."
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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;
|
|
||||||
},
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user