@@ -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]
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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,15 +534,9 @@ 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();
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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).
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user