make toplevel more consistent with answers, depend on readline package without renaming.
This commit is contained in:
@@ -231,8 +231,10 @@ fn setup_qualified_import(mut terms: Vec<Box<Term>>) -> Result<UseModuleExport,
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_declaration(term: Term) -> Result<Declaration, ParserError>
|
||||
fn setup_declaration(mut terms: Vec<Box<Term>>) -> Result<Declaration, ParserError>
|
||||
{
|
||||
let term = *terms.pop().unwrap();
|
||||
|
||||
match term {
|
||||
Term::Clause(_, name, mut terms, _) =>
|
||||
if name.as_str() == "op" && terms.len() == 3 {
|
||||
@@ -592,11 +594,12 @@ impl RelationWorker {
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_query(&mut self, indices: &mut CompositeIndices, terms: Vec<Box<Term>>, blocks_cuts: bool)
|
||||
fn setup_query(&mut self, indices: &mut CompositeIndices, terms: Vec<Box<Term>>,
|
||||
blocks_cuts: bool)
|
||||
-> Result<Vec<QueryTerm>, ParserError>
|
||||
{
|
||||
let mut query_terms = vec![];
|
||||
let mut work_queue = VecDeque::from(terms);
|
||||
let mut work_queue = VecDeque::from(terms);
|
||||
|
||||
while let Some(term) = work_queue.pop_front() {
|
||||
let mut term = *term;
|
||||
@@ -651,9 +654,9 @@ impl RelationWorker {
|
||||
blocks_cuts: bool, assume_dyn: bool)
|
||||
-> Result<Rule, ParserError>
|
||||
{
|
||||
let post_head_terms: Vec<_> = terms.drain(1 ..).collect();
|
||||
|
||||
let head = *terms.first().cloned().unwrap();
|
||||
let post_head_terms: Vec<_> = terms.drain(1 .. ).collect();
|
||||
|
||||
let tail = *post_head_terms.first().cloned().unwrap();
|
||||
|
||||
if assume_dyn {
|
||||
@@ -677,19 +680,23 @@ impl RelationWorker {
|
||||
-> Result<TopLevel, ParserError>
|
||||
{
|
||||
match term {
|
||||
Term::Clause(r, name, mut terms, fixity) =>
|
||||
Term::Clause(r, name, terms, fixity) =>
|
||||
if let Some(hook) = is_compile_time_hook(&name, &terms) {
|
||||
let term = Term::Clause(r, name, terms, fixity);
|
||||
let (hook, clause, queue) = self.setup_hook(hook, indices, term)?;
|
||||
|
||||
Ok(TopLevel::Declaration(Declaration::Hook(hook, clause, queue)))
|
||||
} else if name.as_str() == "?-" {
|
||||
Ok(TopLevel::Query(try!(self.setup_query(indices, terms, blocks_cuts))))
|
||||
} else if name.as_str() == ":-" && terms.len() > 1 {
|
||||
Ok(TopLevel::Rule(try!(self.setup_rule(indices, terms, blocks_cuts, true))))
|
||||
match setup_declaration(terms.iter().cloned().collect()) {
|
||||
Ok(decl) => return Ok(TopLevel::Declaration(decl)),
|
||||
_ => {}
|
||||
};
|
||||
|
||||
Ok(TopLevel::Query(self.setup_query(indices, terms, blocks_cuts)?))
|
||||
} else if name.as_str() == ":-" && terms.len() == 2 {
|
||||
Ok(TopLevel::Rule(self.setup_rule(indices, terms, blocks_cuts, true)?))
|
||||
} else if name.as_str() == ":-" && terms.len() == 1 {
|
||||
let term = *terms.pop().unwrap();
|
||||
Ok(TopLevel::Declaration(try!(setup_declaration(term))))
|
||||
Ok(TopLevel::Declaration(setup_declaration(terms)?))
|
||||
} else {
|
||||
let term = Term::Clause(r, name, terms, fixity);
|
||||
Ok(TopLevel::Fact(try!(self.setup_fact(term, true))))
|
||||
|
||||
@@ -11,7 +11,7 @@ use prolog::machine::machine_state::MachineState;
|
||||
use std::collections::VecDeque;
|
||||
use std::io::Read;
|
||||
|
||||
use readline_rs::readline::*;
|
||||
use readline_rs_compat::readline::*;
|
||||
|
||||
type SubtermDeque = VecDeque<(usize, usize)>;
|
||||
|
||||
@@ -27,7 +27,6 @@ impl<'a> TermRef<'a> {
|
||||
}
|
||||
|
||||
pub enum Input {
|
||||
Quit,
|
||||
Clear,
|
||||
Batch,
|
||||
TermString(&'static str)
|
||||
@@ -52,7 +51,7 @@ pub fn set_line_mode(mode: LineMode) {
|
||||
|
||||
fn is_directive(buf: &str) -> bool {
|
||||
match buf {
|
||||
"[user]" | "quit" | "clear" => true,
|
||||
"?- [user]." | "?- [clear]." => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
@@ -77,9 +76,6 @@ unsafe extern "C" fn bind_end_key(_: i32, _: i32) -> i32 {
|
||||
|
||||
unsafe extern "C" fn bind_cr(_: i32, _: i32) -> i32 {
|
||||
if END_OF_LINE {
|
||||
println!("");
|
||||
rl_done = 1;
|
||||
} else {
|
||||
if let Some(buf) = rl_line_buffer_as_str() {
|
||||
if is_directive(buf) {
|
||||
println!("");
|
||||
@@ -88,6 +84,9 @@ unsafe extern "C" fn bind_cr(_: i32, _: i32) -> i32 {
|
||||
}
|
||||
}
|
||||
|
||||
println!("");
|
||||
rl_done = 1;
|
||||
} else {
|
||||
insert_text_rl("\n");
|
||||
}
|
||||
|
||||
@@ -107,20 +106,46 @@ pub fn readline_initialize() {
|
||||
bind_keyseq_rl("\\C-d", bind_end_chord);
|
||||
}
|
||||
|
||||
pub fn read_line(prompt: &str) -> Result<&'static str, SessionError> {
|
||||
pub fn read_batch(prompt: &str) -> Result<&'static str, SessionError> {
|
||||
unsafe {
|
||||
use std::ptr::null;
|
||||
use std::mem;
|
||||
|
||||
// deactivate the startup hook that emits a "?- " to the
|
||||
// beginning of the readline buffer.
|
||||
let p: *const i8 = null();
|
||||
rl_startup_hook = mem::transmute(p);
|
||||
}
|
||||
|
||||
match readline_rl(prompt) {
|
||||
Some(input) => Ok(input),
|
||||
None => Err(SessionError::UserPrompt)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn toplevel_read_line() -> Result<Input, SessionError> {
|
||||
let buffer = read_line("prolog> ")?;
|
||||
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 {
|
||||
insert_text_rl("?- ");
|
||||
0
|
||||
}
|
||||
|
||||
pub fn toplevel_read_line() -> Result<Input, SessionError>
|
||||
{
|
||||
unsafe {
|
||||
rl_startup_hook = insert_query_prompt;
|
||||
}
|
||||
|
||||
let buffer = read_line("")?;
|
||||
|
||||
Ok(match &*buffer.trim() {
|
||||
"quit" => Input::Quit,
|
||||
"clear" => Input::Clear,
|
||||
"[user]" => {
|
||||
"?- [clear]." => Input::Clear,
|
||||
"?- [user]." => {
|
||||
println!("(type Enter + Ctrl-D to terminate the stream when finished)");
|
||||
Input::Batch
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user