[package]
name = "scryer-prolog"
-version = "0.8.56"
+version = "0.8.57"
repository = "https://github.com/mthom/scryer-prolog"
description = "A modern Prolog implementation written mostly in Rust."
num = "0.2"
ordered-float = "0.5.0"
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"
[dependencies.termion]
use prolog::machine::modules::*;
use prolog::machine::or_stack::*;
use prolog::num::{BigInt, BigUint, Zero, One};
-use prolog::read::{PrologStream, readline};
+use prolog::read::PrologStream;
use downcast::Any;
return_from_clause!(machine_st.last_call, machine_st)
},
&BuiltInClauseType::Read => {
- readline::toggle_prompt(false);
-
match machine_st.read(parsing_stream, indices.atom_tbl.clone(), &indices.op_dir) {
Ok(offset) => {
let addr = machine_st[temp_v!(1)].clone();
}
}
+ 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,
ct: &SystemClauseType,
indices: &mut IndexStore,
for addr in addrs.iter() {
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)) =>
chars.push(c as char),
_ => {
match self.store(self.deref(a2)) {
Addr::Con(Constant::CharCode(code)) =>
self.unify(Addr::Con(Constant::Char(code as char)), addr.clone()),
- Addr::Con(Constant::Number(Number::Integer(n))) =>
- if let Some(c) = n.to_u8() {
- 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);
- },
+ Addr::Con(Constant::Number(Number::Integer(n))) => {
+ let c = self.int_to_char_code(n, "char_code", 2)?;
+ self.unify(Addr::Con(Constant::Char(c as char)), addr.clone());
+ },
_ => self.fail = true
};
},
};
},
&SystemClauseType::GetChar => {
- readline::toggle_prompt(false);
-
let result = parsing_stream.next();
let a1 = self[temp_v!(1)].clone();
self.install_new_block(temp_v!(1));
},
&SystemClauseType::ReadTerm => {
- readline::toggle_prompt(true);
-
match self.read(parsing_stream, indices.atom_tbl.clone(), &indices.op_dir) {
Ok(term_write_result) => {
let a1 = self[temp_v!(1)].clone();
impl Read for ReadlineStream {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
if self.pending_input.is_empty() {
- let prompt = unsafe {
- if PRINT_PROMPT { "?- " } else { "" }
- };
-
- self.call_readline(prompt, buf)
+ self.call_readline("", buf)
} else {
Ok(self.write_to_buf(buf))
}
}
}
- static mut PRINT_PROMPT: bool = true;
static mut LINE_MODE: LineMode = LineMode::Single;
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) {
unsafe {
LINE_MODE = mode;
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('\r' as i32, bind_cr);
bind_keyseq_rl("\\C-d", bind_end_chord);
pub mod readline
{
use prolog_parser::ast::*;
- use std::io::{BufReader, Read, Stdin, Write, stdin, stdout};
-
- static mut PRINT_PROMPT: bool = false;
+ use std::io::{BufReader, Read, Stdin, stdin};
struct StdinWrapper {
buf: BufReader<Stdin>
}
- fn print_prompt() {
- unsafe {
- if PRINT_PROMPT {
- print!("?- ");
- stdout().flush().unwrap();
- PRINT_PROMPT = false;
- }
- }
- }
-
impl Read for StdinWrapper {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
- print_prompt();
self.buf.read(buf)
}
}
#[inline]
pub fn input_stream() -> ::PrologStream {
- print_prompt();
-
let reader: Box<Read> = Box::new(StdinWrapper { buf: BufReader::new(stdin()) });
parsing_stream(reader)
}
-
-
- pub fn toggle_prompt(on_or_off: bool) {
- unsafe {
- PRINT_PROMPT = on_or_off;
- }
- }
}
impl MachineState {
repl :- repl.
read_and_match :-
+ write_term('?- ', [quoted(false)]),
read_term(Term, [variable_names(VarList)]),
'$instruction_match'(Term, VarList).