ensure stdin is not being locked more than once

This commit is contained in:
Mark Thom
2019-02-17 01:33:35 -07:00
parent 023fec0d9d
commit a898824b65

View File

@@ -2,7 +2,7 @@ use prolog::instructions::*;
use prolog::heap_print::*; use prolog::heap_print::*;
use prolog::machine::*; use prolog::machine::*;
use termion::raw::IntoRawMode; use termion::raw::{IntoRawMode, RawTerminal};
use termion::input::TermRead; use termion::input::TermRead;
use termion::event::Key; use termion::event::Key;
@@ -336,6 +336,32 @@ impl fmt::Display for Level {
} }
} }
enum ContinueResult {
ContinueQuery,
Conclude
}
fn next_step(mut stdout: RawTerminal<std::io::Stdout>) -> ContinueResult
{
let stdin = stdin();
for c in stdin.keys() {
match c.unwrap() {
Key::Char(' ') | Key::Char(';') => {
write!(stdout, " ;\r\n").unwrap();
return ContinueResult::ContinueQuery;
},
Key::Char('.') => {
write!(stdout, " .\r\n").unwrap();
return ContinueResult::Conclude;
},
_ => {}
}
}
ContinueResult::Conclude
}
pub fn print(wam: &mut Machine, result: EvalSession) { pub fn print(wam: &mut Machine, result: EvalSession) {
match result { match result {
EvalSession::InitialQuerySuccess(alloc_locs, mut heap_locs) => { EvalSession::InitialQuerySuccess(alloc_locs, mut heap_locs) => {
@@ -349,48 +375,39 @@ pub fn print(wam: &mut Machine, result: EvalSession) {
} }
loop { loop {
let mut result = EvalSession::from(SessionError::QueryFailure);
let mut output = PrinterOutputter::new(); let mut output = PrinterOutputter::new();
let bindings = wam.heap_view(&heap_locs, output).result(); let bindings = wam.heap_view(&heap_locs, output).result();
let mut raw_stdout = stdout().into_raw_mode().unwrap();
let stdin = stdin(); write!(raw_stdout, "{}", bindings).unwrap();
let mut stdout = stdout().into_raw_mode().unwrap(); raw_stdout.flush().unwrap();
write!(stdout, "{}", bindings).unwrap();
stdout.flush().unwrap();
wam.attribute_goals(&heap_locs); wam.attribute_goals(&heap_locs);
if !wam.or_stack_is_empty() { if !wam.or_stack_is_empty() {
stdout.flush().unwrap(); raw_stdout.flush().unwrap();
for c in stdin.keys() { let result = match next_step(raw_stdout) {
match c.unwrap() { ContinueResult::ContinueQuery =>
Key::Char(' ') | Key::Char(';') => { wam.continue_query(&alloc_locs, &mut heap_locs),
write!(stdout, " ;\r\n").unwrap(); ContinueResult::Conclude =>
result = wam.continue_query(&alloc_locs, &mut heap_locs); return
break; };
},
Key::Char('.') => { let mut raw_stdout = stdout().into_raw_mode().unwrap();
write!(stdout, " .\r\n").unwrap();
return;
},
_ => {}
}
}
if let &EvalSession::Error(SessionError::QueryFailure) = &result if let &EvalSession::Error(SessionError::QueryFailure) = &result
{ {
write!(stdout, "false.\r\n").unwrap(); write!(raw_stdout, "false.\r\n").unwrap();
stdout.flush().unwrap(); raw_stdout.flush().unwrap();
return; return;
} }
if let &EvalSession::Error(SessionError::QueryFailureWithException(ref e)) = &result if let &EvalSession::Error(SessionError::QueryFailureWithException(ref e)) = &result
{ {
write!(stdout, "{}\r\n", error_string(e)).unwrap(); write!(raw_stdout, "{}\r\n", error_string(e)).unwrap();
stdout.flush().unwrap(); raw_stdout.flush().unwrap();
return; return;
} }
} else { } else {