enable an option to disable readline

This commit is contained in:
Mark Thom
2019-03-21 19:46:42 -06:00
parent 4b2fb8b1c7
commit 33b581effc
4 changed files with 165 additions and 98 deletions

View File

@@ -1,17 +1,21 @@
[package]
name = "scryer-prolog"
version = "0.8.11"
version = "0.8.12"
authors = ["Mark Thom <markjordanthom@gmail.com>"]
repository = "https://github.com/mthom/scryer-prolog"
description = "A modern Prolog implementation written mostly in Rust."
license = "BSD-3-Clause"
[features]
default = ["readline_rs_compat"]
[dependencies]
cfg-if = "0.1.7"
downcast = "0.9.1"
num = "0.2"
ordered-float = "0.5.0"
prolog_parser = "0.8.1"
readline_rs_compat = "0.1.5"
readline_rs_compat = { version = "0.1.5", optional = true }
[dependencies.termion]
version = "1.4.0"

View File

@@ -114,6 +114,13 @@ readline:
/opt/local/lib
```
If you'd like to disable readline (and the need for linking to it),
install with the line
```
cargo install scryer-prolog --no-default-features
```
You can find the `scryer-prolog` executable in `~/.cargo/bin`.
Note on compatibility: Scryer Prolog should work on Linux, Mac OS X,

View File

@@ -1,7 +1,13 @@
#[macro_use] extern crate cfg_if;
#[macro_use] extern crate downcast;
#[macro_use] extern crate prolog_parser;
cfg_if! {
if #[cfg(feature = "readline_rs_compat")] {
extern crate readline_rs_compat;
}
}
extern crate termion;
mod prolog;
@@ -20,7 +26,8 @@ fn prolog_repl() {
let mut wam = Machine::new();
loop {
set_line_mode(LineMode::Single);
#[cfg(feature = "readline_rs_compat")]
readline::set_line_mode(readline::LineMode::Single);
match toplevel_read_line() {
Ok(Input::TermString(buffer)) => {
@@ -32,9 +39,10 @@ fn prolog_repl() {
print(&mut wam, result)
},
Ok(Input::Batch) => {
set_line_mode(LineMode::Multi);
#[cfg(feature = "readline_rs_compat")]
readline::set_line_mode(readline::LineMode::Multi);
let src = match read_batch("") {
let src = match readline::read_batch("") {
Ok(src) => src,
Err(e) => {
println!("{}", e);
@@ -42,7 +50,7 @@ fn prolog_repl() {
}
};
let result = compile_user_module(&mut wam, src.as_bytes());
let result = compile_user_module(&mut wam, &src[0 ..]);
print(&mut wam, result);
},
Ok(Input::Clear) => {
@@ -57,6 +65,7 @@ fn prolog_repl() {
}
fn main() {
readline_initialize();
#[cfg(feature = "readline_rs_compat")]
readline::readline_initialize();
prolog_repl();
}

View File

@@ -11,8 +11,6 @@ use prolog::machine::machine_state::MachineState;
use std::collections::VecDeque;
use std::io::Read;
use readline_rs_compat::readline::*;
type SubtermDeque = VecDeque<(usize, usize)>;
impl<'a> TermRef<'a> {
@@ -29,9 +27,14 @@ impl<'a> TermRef<'a> {
pub enum Input {
Clear,
Batch,
TermString(&'static str)
TermString(String)
}
#[cfg(feature = "readline_rs_compat")]
pub mod readline
{
use readline_rs_compat::readline::*;
#[derive(Clone, Copy)]
pub enum LineMode {
Single,
@@ -100,26 +103,16 @@ pub fn readline_initialize() {
panic!("initialize_rl() failed with return code {}", rc);
}
unsafe {
rl_startup_hook = insert_query_prompt;
}
bind_key_rl('.' as i32, bind_end_key);
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 fn read_batch(prompt: &str) -> Result<&'static str, SessionError> {
match readline_rl(prompt) {
Some(input) => Ok(input),
None => Err(SessionError::UserPrompt)
}
}
fn read_line(prompt: &str) -> Result<&'static str, SessionError> {
match readline_rl(prompt) {
Some(input) => Ok(input),
None => Err(SessionError::UserPrompt)
}
}
unsafe extern "C" fn insert_query_prompt() -> i32 {
if let LineMode::Single = LINE_MODE {
insert_text_rl("?- ");
@@ -128,13 +121,67 @@ unsafe extern "C" fn insert_query_prompt() -> i32 {
0
}
pub fn toplevel_read_line() -> Result<Input, SessionError>
{
unsafe {
rl_startup_hook = insert_query_prompt;
pub fn read_batch(prompt: &str) -> Result<Vec<u8>, ::SessionError> {
match readline_rl(prompt) {
Some(input) => Ok(Vec::from(input.as_bytes())),
None => Err(::SessionError::UserPrompt)
}
}
let buffer = read_line("")?;
pub fn read_line(prompt: &str) -> Result<String, ::SessionError> {
match readline_rl(prompt) {
Some(input) => Ok(String::from(input)),
None => Err(::SessionError::UserPrompt)
}
}
}
#[cfg(not(feature = "readline_rs_compat"))]
pub mod readline
{
use std::io::{BufRead, Read, stdin, stdout, Write};
pub fn read_batch(_: &str) -> Result<Vec<u8>, ::SessionError> {
let mut buf = vec![];
let stdin = stdin();
let mut stdin = stdin.lock();
match stdin.read_to_end(&mut buf) {
Ok(_) => Ok(buf),
_ => Err(::SessionError::UserPrompt)
}
}
pub fn read_line(_: &str) -> Result<String, ::SessionError> {
print!("?- ");
stdout().flush().unwrap();
let stdin = stdin();
let stdin = stdin.lock();
let mut buf = "?- ".to_string();
for line in stdin.lines() {
match line {
Ok(line) => {
buf += &line;
if line.trim().ends_with(".") {
break;
}
},
_ => return Err(::SessionError::UserPrompt)
}
}
Ok(buf)
}
}
pub fn toplevel_read_line() -> Result<Input, SessionError>
{
let buffer = readline::read_line("")?;
Ok(match &*buffer.trim() {
"?- [clear]." => Input::Clear,