address issues #104, #105, #103

This commit is contained in:
Mark Thom
2019-04-20 20:13:19 -03:00
parent e089c8bdd2
commit c8c8c5abae
5 changed files with 29 additions and 54 deletions

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "scryer-prolog" name = "scryer-prolog"
version = "0.8.56" version = "0.8.57"
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."
@@ -15,7 +15,7 @@ downcast = "0.10.0"
num = "0.2" num = "0.2"
ordered-float = "0.5.0" ordered-float = "0.5.0"
prolog_parser = "0.8.19" prolog_parser = "0.8.19"
readline_rs_compat = { version = "0.1.8", optional = true } readline_rs_compat = { version = "0.1.9", optional = true }
ref_thread_local = "0.0.0" ref_thread_local = "0.0.0"
[dependencies.termion] [dependencies.termion]

View File

@@ -12,7 +12,7 @@ use prolog::machine::machine_indices::*;
use prolog::machine::modules::*; use prolog::machine::modules::*;
use prolog::machine::or_stack::*; use prolog::machine::or_stack::*;
use prolog::num::{BigInt, BigUint, Zero, One}; use prolog::num::{BigInt, BigUint, Zero, One};
use prolog::read::{PrologStream, readline}; use prolog::read::PrologStream;
use downcast::Any; use downcast::Any;
@@ -589,8 +589,6 @@ pub(crate) trait CallPolicy: Any {
return_from_clause!(machine_st.last_call, machine_st) return_from_clause!(machine_st.last_call, machine_st)
}, },
&BuiltInClauseType::Read => { &BuiltInClauseType::Read => {
readline::toggle_prompt(false);
match machine_st.read(parsing_stream, indices.atom_tbl.clone(), &indices.op_dir) { match machine_st.read(parsing_stream, indices.atom_tbl.clone(), &indices.op_dir) {
Ok(offset) => { Ok(offset) => {
let addr = machine_st[temp_v!(1)].clone(); let addr = machine_st[temp_v!(1)].clone();

View File

@@ -310,6 +310,20 @@ impl MachineState {
} }
} }
fn int_to_char_code(&mut self, n: Rc<BigInt>, stub: &'static str, arity: usize)
-> Result<u8, MachineStub>
{
if let Some(c) = n.to_u8() {
Ok(c)
} else {
let stub = MachineError::functor_stub(clause_name!(stub), arity);
let err = MachineError::representation_error(RepFlag::CharacterCode);
let err = self.error_form(err, stub);
Err(err)
}
}
pub(super) fn system_call(&mut self, pub(super) fn system_call(&mut self,
ct: &SystemClauseType, ct: &SystemClauseType,
indices: &mut IndexStore, indices: &mut IndexStore,
@@ -444,6 +458,10 @@ impl MachineState {
for addr in addrs.iter() { for addr in addrs.iter() {
match addr { match addr {
&Addr::Con(Constant::Number(Number::Integer(ref n))) => {
let c = self.int_to_char_code(n.clone(), "atom_codes", 2)?;
chars.push(c as char);
},
&Addr::Con(Constant::CharCode(c)) => &Addr::Con(Constant::CharCode(c)) =>
chars.push(c as char), chars.push(c as char),
_ => { _ => {
@@ -516,16 +534,10 @@ impl MachineState {
match self.store(self.deref(a2)) { match self.store(self.deref(a2)) {
Addr::Con(Constant::CharCode(code)) => Addr::Con(Constant::CharCode(code)) =>
self.unify(Addr::Con(Constant::Char(code as char)), addr.clone()), self.unify(Addr::Con(Constant::Char(code as char)), addr.clone()),
Addr::Con(Constant::Number(Number::Integer(n))) => Addr::Con(Constant::Number(Number::Integer(n))) => {
if let Some(c) = n.to_u8() { let c = self.int_to_char_code(n, "char_code", 2)?;
self.unify(Addr::Con(Constant::Char(c as char)), addr.clone()); self.unify(Addr::Con(Constant::Char(c as char)), addr.clone());
} else { },
let stub = MachineError::functor_stub(clause_name!("char_code"), 2);
let err = MachineError::representation_error(RepFlag::CharacterCode);
let err = self.error_form(err, stub);
return Err(err);
},
_ => self.fail = true _ => self.fail = true
}; };
}, },
@@ -556,8 +568,6 @@ impl MachineState {
}; };
}, },
&SystemClauseType::GetChar => { &SystemClauseType::GetChar => {
readline::toggle_prompt(false);
let result = parsing_stream.next(); let result = parsing_stream.next();
let a1 = self[temp_v!(1)].clone(); let a1 = self[temp_v!(1)].clone();
@@ -1408,8 +1418,6 @@ impl MachineState {
self.install_new_block(temp_v!(1)); self.install_new_block(temp_v!(1));
}, },
&SystemClauseType::ReadTerm => { &SystemClauseType::ReadTerm => {
readline::toggle_prompt(true);
match self.read(parsing_stream, indices.atom_tbl.clone(), &indices.op_dir) { match self.read(parsing_stream, indices.atom_tbl.clone(), &indices.op_dir) {
Ok(term_write_result) => { Ok(term_write_result) => {
let a1 = self[temp_v!(1)].clone(); let a1 = self[temp_v!(1)].clone();

View File

@@ -85,27 +85,16 @@ pub mod readline
impl Read for ReadlineStream { impl Read for ReadlineStream {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> { fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
if self.pending_input.is_empty() { if self.pending_input.is_empty() {
let prompt = unsafe { self.call_readline("", buf)
if PRINT_PROMPT { "?- " } else { "" }
};
self.call_readline(prompt, buf)
} else { } else {
Ok(self.write_to_buf(buf)) Ok(self.write_to_buf(buf))
} }
} }
} }
static mut PRINT_PROMPT: bool = true;
static mut LINE_MODE: LineMode = LineMode::Single; static mut LINE_MODE: LineMode = LineMode::Single;
static mut END_OF_LINE: bool = false; static mut END_OF_LINE: bool = false;
pub fn toggle_prompt(on_or_off: bool) {
unsafe {
PRINT_PROMPT = on_or_off;
}
}
pub fn set_line_mode(mode: LineMode) { pub fn set_line_mode(mode: LineMode) {
unsafe { unsafe {
LINE_MODE = mode; LINE_MODE = mode;
@@ -141,6 +130,7 @@ pub mod readline
panic!("initialize_rl() failed with return code {}", rc); panic!("initialize_rl() failed with return code {}", rc);
} }
bind_key_rl('\t' as i32, rl_insert); // just insert tabs when typed.
bind_key_rl('\n' as i32, bind_cr); bind_key_rl('\n' as i32, bind_cr);
bind_key_rl('\r' as i32, bind_cr); bind_key_rl('\r' as i32, bind_cr);
bind_keyseq_rl("\\C-d", bind_end_chord); bind_keyseq_rl("\\C-d", bind_end_chord);
@@ -164,27 +154,14 @@ pub mod readline
pub mod readline pub mod readline
{ {
use prolog_parser::ast::*; use prolog_parser::ast::*;
use std::io::{BufReader, Read, Stdin, Write, stdin, stdout}; use std::io::{BufReader, Read, Stdin, stdin};
static mut PRINT_PROMPT: bool = false;
struct StdinWrapper { struct StdinWrapper {
buf: BufReader<Stdin> buf: BufReader<Stdin>
} }
fn print_prompt() {
unsafe {
if PRINT_PROMPT {
print!("?- ");
stdout().flush().unwrap();
PRINT_PROMPT = false;
}
}
}
impl Read for StdinWrapper { impl Read for StdinWrapper {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> { fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
print_prompt();
self.buf.read(buf) self.buf.read(buf)
} }
} }
@@ -203,18 +180,9 @@ pub mod readline
#[inline] #[inline]
pub fn input_stream() -> ::PrologStream { pub fn input_stream() -> ::PrologStream {
print_prompt();
let reader: Box<Read> = Box::new(StdinWrapper { buf: BufReader::new(stdin()) }); let reader: Box<Read> = Box::new(StdinWrapper { buf: BufReader::new(stdin()) });
parsing_stream(reader) parsing_stream(reader)
} }
pub fn toggle_prompt(on_or_off: bool) {
unsafe {
PRINT_PROMPT = on_or_off;
}
}
} }
impl MachineState { impl MachineState {

View File

@@ -4,6 +4,7 @@ repl :-
repl :- repl. repl :- repl.
read_and_match :- read_and_match :-
write_term('?- ', [quoted(false)]),
read_term(Term, [variable_names(VarList)]), read_term(Term, [variable_names(VarList)]),
'$instruction_match'(Term, VarList). '$instruction_match'(Term, VarList).