Merge pull request #360 from notoria/master
Add get_single_char predicate.
This commit is contained in:
@@ -168,8 +168,8 @@ predicates it defines. For example, with the program shown above:
|
||||
; What = pure_world.
|
||||
```
|
||||
|
||||
Press `SPACE` to show further answers, if any exist. Press `.` to
|
||||
abort the search and return to the toplevel prompt.
|
||||
Press `SPACE` to show further answers, if any exist. Press `RETURN` or
|
||||
`.` to abort the search and return to the toplevel prompt.
|
||||
Press `h` to show a help message.
|
||||
|
||||
To quit Scryer Prolog, use the standard predicate `halt/0`:
|
||||
|
||||
@@ -178,6 +178,7 @@ pub enum SystemClauseType {
|
||||
FetchGlobalVar,
|
||||
FetchGlobalVarWithOffset,
|
||||
GetChar,
|
||||
GetSingleChar,
|
||||
ResetAttrVarState,
|
||||
TruncateIfNoLiftedHeapGrowthDiff,
|
||||
TruncateIfNoLiftedHeapGrowth,
|
||||
@@ -241,7 +242,6 @@ pub enum SystemClauseType {
|
||||
InstallNewBlock,
|
||||
Maybe,
|
||||
QuotedToken,
|
||||
RawInputReadChar,
|
||||
ReadTermFromChars,
|
||||
ResetBlock,
|
||||
ReturnFromVerifyAttr,
|
||||
@@ -309,6 +309,7 @@ impl SystemClauseType {
|
||||
clause_name!("$fetch_global_var_with_offset")
|
||||
}
|
||||
&SystemClauseType::GetChar => clause_name!("$get_char"),
|
||||
&SystemClauseType::GetSingleChar => clause_name!("$get_single_char"),
|
||||
&SystemClauseType::ResetAttrVarState => clause_name!("$reset_attr_var_state"),
|
||||
&SystemClauseType::TruncateIfNoLiftedHeapGrowth => {
|
||||
clause_name!("$truncate_if_no_lh_growth")
|
||||
@@ -364,7 +365,6 @@ impl SystemClauseType {
|
||||
&SystemClauseType::QuotedToken => {
|
||||
clause_name!("$quoted_token")
|
||||
}
|
||||
&SystemClauseType::RawInputReadChar => clause_name!("$raw_input_read_char"),
|
||||
&SystemClauseType::RedoAttrVarBinding => clause_name!("$redo_attr_var_binding"),
|
||||
&SystemClauseType::RemoveCallPolicyCheck => clause_name!("$remove_call_policy_check"),
|
||||
&SystemClauseType::RemoveInferenceCounter => clause_name!("$remove_inference_counter"),
|
||||
@@ -455,6 +455,7 @@ impl SystemClauseType {
|
||||
("$fetch_global_var", 2) => Some(SystemClauseType::FetchGlobalVar),
|
||||
("$fetch_global_var_with_offset", 3) => Some(SystemClauseType::FetchGlobalVarWithOffset),
|
||||
("$get_char", 1) => Some(SystemClauseType::GetChar),
|
||||
("$get_single_char", 1) => Some(SystemClauseType::GetSingleChar),
|
||||
("$points_to_cont_reset_marker", 1) => {
|
||||
Some(SystemClauseType::PointsToContinuationResetMarker)
|
||||
}
|
||||
@@ -506,7 +507,6 @@ impl SystemClauseType {
|
||||
("$get_cp", 1) => Some(SystemClauseType::GetCutPoint),
|
||||
("$install_new_block", 1) => Some(SystemClauseType::InstallNewBlock),
|
||||
("$quoted_token", 1) => Some(SystemClauseType::QuotedToken),
|
||||
("$raw_input_read_char", 1) => Some(SystemClauseType::RawInputReadChar),
|
||||
("$nextEP", 3) => Some(SystemClauseType::NextEP),
|
||||
("$read_query_term", 2) => Some(SystemClauseType::ReadQueryTerm),
|
||||
("$read_term", 2) => Some(SystemClauseType::ReadTerm),
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
:- module(charsio, [read_term_from_chars/2,
|
||||
:- module(charsio, [get_single_char/1,
|
||||
read_term_from_chars/2,
|
||||
write_term_to_chars/3]).
|
||||
|
||||
:- use_module(library(iso_ext)).
|
||||
@@ -56,6 +57,13 @@ extend_var_list_([V|Vs], N, VarList, NewVarList, VarType) :-
|
||||
).
|
||||
|
||||
|
||||
get_single_char(C) :-
|
||||
( var(C) -> '$get_single_char'(C)
|
||||
; atom_length(C, 1) -> '$get_single_char'(C)
|
||||
; throw(error(domain_error(in_character, C), get_single_char/1))
|
||||
).
|
||||
|
||||
|
||||
read_term_from_chars(Chars, Term) :-
|
||||
( var(Chars) ->
|
||||
throw(error(instantiation_error, read_term_from_chars/2))
|
||||
|
||||
@@ -31,40 +31,30 @@ use std::rc::Rc;
|
||||
use crate::crossterm::event::{read, Event, KeyCode, KeyEvent};
|
||||
use crate::crossterm::terminal::{enable_raw_mode, disable_raw_mode};
|
||||
|
||||
pub enum ContinueResult {
|
||||
ContinueQuery,
|
||||
Conclude,
|
||||
Help,
|
||||
PrintWithoutMaxDepth,
|
||||
PrintWithMaxDepth
|
||||
}
|
||||
|
||||
pub fn next_keypress() -> ContinueResult {
|
||||
pub fn get_single_char() -> char {
|
||||
let c;
|
||||
enable_raw_mode().expect("failed to enable raw mode");
|
||||
loop {
|
||||
match read() {
|
||||
Ok(Event::Key(KeyEvent { code, .. })) => {
|
||||
match code {
|
||||
KeyCode::Char('w') => {
|
||||
return ContinueResult::PrintWithoutMaxDepth;
|
||||
}
|
||||
KeyCode::Char('p') => {
|
||||
return ContinueResult::PrintWithMaxDepth;
|
||||
}
|
||||
KeyCode::Char(' ') | KeyCode::Char(';') | KeyCode::Char('n') => {
|
||||
return ContinueResult::ContinueQuery;
|
||||
}
|
||||
KeyCode::Char('.') => {
|
||||
return ContinueResult::Conclude;
|
||||
}
|
||||
KeyCode::Char('h') => {
|
||||
return ContinueResult::Help;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
if let Ok(Event::Key(KeyEvent { code, .. })) = read() {
|
||||
match code {
|
||||
KeyCode::Char(ch) => {
|
||||
c = ch;
|
||||
break;
|
||||
},
|
||||
KeyCode::Enter => {
|
||||
c = '\n';
|
||||
break;
|
||||
},
|
||||
KeyCode::Tab => {
|
||||
c = '\t';
|
||||
break;
|
||||
},
|
||||
_ => ()
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
disable_raw_mode().expect("failed to disable raw mode");
|
||||
c
|
||||
}
|
||||
|
||||
struct BrentAlgState {
|
||||
@@ -1463,6 +1453,13 @@ impl MachineState {
|
||||
}
|
||||
}
|
||||
}
|
||||
&SystemClauseType::GetSingleChar => {
|
||||
let c = get_single_char();
|
||||
|
||||
let a1 = self[temp_v!(1)];
|
||||
|
||||
self.unify(Addr::Char(c), a1);
|
||||
}
|
||||
&SystemClauseType::GetModuleClause => {
|
||||
let module = self[temp_v!(3)];
|
||||
let head = self[temp_v!(1)];
|
||||
@@ -2880,26 +2877,6 @@ impl MachineState {
|
||||
&SystemClauseType::InstallNewBlock => {
|
||||
self.install_new_block(temp_v!(1));
|
||||
}
|
||||
&SystemClauseType::RawInputReadChar => {
|
||||
let keypress = {
|
||||
enable_raw_mode().expect("failed to transition into raw mode");
|
||||
let result = next_keypress();
|
||||
disable_raw_mode().expect("failed to transition out of raw mode");
|
||||
|
||||
result
|
||||
};
|
||||
|
||||
let c = match keypress {
|
||||
ContinueResult::ContinueQuery => ';',
|
||||
ContinueResult::Conclude => '.',
|
||||
ContinueResult::Help => 'h',
|
||||
ContinueResult::PrintWithoutMaxDepth => 'w',
|
||||
ContinueResult::PrintWithMaxDepth => 'p',
|
||||
};
|
||||
|
||||
let target = self[temp_v!(1)];
|
||||
self.unify(Addr::Char(c), target);
|
||||
}
|
||||
&SystemClauseType::NextEP => {
|
||||
let first_arg = self.store(self.deref(self[temp_v!(1)]));
|
||||
|
||||
|
||||
@@ -145,30 +145,31 @@
|
||||
).
|
||||
|
||||
'$read_input'(ThreadedGoals, NewVarList) :-
|
||||
'$raw_input_read_char'(C),
|
||||
( C == w ->
|
||||
get_single_char(C),
|
||||
( C = w ->
|
||||
nl,
|
||||
write(' '),
|
||||
'$write_eq'(ThreadedGoals, NewVarList, 0),
|
||||
'$read_input'(ThreadedGoals, NewVarList)
|
||||
; C == p ->
|
||||
; C = p ->
|
||||
nl,
|
||||
write(' '),
|
||||
'$write_eq'(ThreadedGoals, NewVarList, 20),
|
||||
'$read_input'(ThreadedGoals, NewVarList)
|
||||
; C == (';') ->
|
||||
; member(C, [';', ' ', n]) ->
|
||||
nl, write('; '), false
|
||||
; C == h ->
|
||||
; C = h ->
|
||||
'$help_message',
|
||||
'$read_input'(ThreadedGoals, NewVarList)
|
||||
; C == '.',
|
||||
; member(C, ['\n', .]) ->
|
||||
nl, write('; ...'), nl
|
||||
; '$read_input'(ThreadedGoals, NewVarList)
|
||||
).
|
||||
|
||||
'$help_message' :-
|
||||
nl, nl,
|
||||
write('SPACE, "n" or ";": next solution, if any\n'),
|
||||
write('".": stop enumeration\n'),
|
||||
write('RETURN or ".": stop enumeration\n'),
|
||||
write('"h": display this help message\n'),
|
||||
write('"w": write terms without depth limit\n'),
|
||||
write('"p": print terms with depth limit\n\n').
|
||||
|
||||
Reference in New Issue
Block a user