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.
|
; What = pure_world.
|
||||||
```
|
```
|
||||||
|
|
||||||
Press `SPACE` to show further answers, if any exist. Press `.` to
|
Press `SPACE` to show further answers, if any exist. Press `RETURN` or
|
||||||
abort the search and return to the toplevel prompt.
|
`.` to abort the search and return to the toplevel prompt.
|
||||||
Press `h` to show a help message.
|
Press `h` to show a help message.
|
||||||
|
|
||||||
To quit Scryer Prolog, use the standard predicate `halt/0`:
|
To quit Scryer Prolog, use the standard predicate `halt/0`:
|
||||||
|
|||||||
@@ -178,6 +178,7 @@ pub enum SystemClauseType {
|
|||||||
FetchGlobalVar,
|
FetchGlobalVar,
|
||||||
FetchGlobalVarWithOffset,
|
FetchGlobalVarWithOffset,
|
||||||
GetChar,
|
GetChar,
|
||||||
|
GetSingleChar,
|
||||||
ResetAttrVarState,
|
ResetAttrVarState,
|
||||||
TruncateIfNoLiftedHeapGrowthDiff,
|
TruncateIfNoLiftedHeapGrowthDiff,
|
||||||
TruncateIfNoLiftedHeapGrowth,
|
TruncateIfNoLiftedHeapGrowth,
|
||||||
@@ -241,7 +242,6 @@ pub enum SystemClauseType {
|
|||||||
InstallNewBlock,
|
InstallNewBlock,
|
||||||
Maybe,
|
Maybe,
|
||||||
QuotedToken,
|
QuotedToken,
|
||||||
RawInputReadChar,
|
|
||||||
ReadTermFromChars,
|
ReadTermFromChars,
|
||||||
ResetBlock,
|
ResetBlock,
|
||||||
ReturnFromVerifyAttr,
|
ReturnFromVerifyAttr,
|
||||||
@@ -309,6 +309,7 @@ impl SystemClauseType {
|
|||||||
clause_name!("$fetch_global_var_with_offset")
|
clause_name!("$fetch_global_var_with_offset")
|
||||||
}
|
}
|
||||||
&SystemClauseType::GetChar => clause_name!("$get_char"),
|
&SystemClauseType::GetChar => clause_name!("$get_char"),
|
||||||
|
&SystemClauseType::GetSingleChar => clause_name!("$get_single_char"),
|
||||||
&SystemClauseType::ResetAttrVarState => clause_name!("$reset_attr_var_state"),
|
&SystemClauseType::ResetAttrVarState => clause_name!("$reset_attr_var_state"),
|
||||||
&SystemClauseType::TruncateIfNoLiftedHeapGrowth => {
|
&SystemClauseType::TruncateIfNoLiftedHeapGrowth => {
|
||||||
clause_name!("$truncate_if_no_lh_growth")
|
clause_name!("$truncate_if_no_lh_growth")
|
||||||
@@ -364,7 +365,6 @@ impl SystemClauseType {
|
|||||||
&SystemClauseType::QuotedToken => {
|
&SystemClauseType::QuotedToken => {
|
||||||
clause_name!("$quoted_token")
|
clause_name!("$quoted_token")
|
||||||
}
|
}
|
||||||
&SystemClauseType::RawInputReadChar => clause_name!("$raw_input_read_char"),
|
|
||||||
&SystemClauseType::RedoAttrVarBinding => clause_name!("$redo_attr_var_binding"),
|
&SystemClauseType::RedoAttrVarBinding => clause_name!("$redo_attr_var_binding"),
|
||||||
&SystemClauseType::RemoveCallPolicyCheck => clause_name!("$remove_call_policy_check"),
|
&SystemClauseType::RemoveCallPolicyCheck => clause_name!("$remove_call_policy_check"),
|
||||||
&SystemClauseType::RemoveInferenceCounter => clause_name!("$remove_inference_counter"),
|
&SystemClauseType::RemoveInferenceCounter => clause_name!("$remove_inference_counter"),
|
||||||
@@ -455,6 +455,7 @@ impl SystemClauseType {
|
|||||||
("$fetch_global_var", 2) => Some(SystemClauseType::FetchGlobalVar),
|
("$fetch_global_var", 2) => Some(SystemClauseType::FetchGlobalVar),
|
||||||
("$fetch_global_var_with_offset", 3) => Some(SystemClauseType::FetchGlobalVarWithOffset),
|
("$fetch_global_var_with_offset", 3) => Some(SystemClauseType::FetchGlobalVarWithOffset),
|
||||||
("$get_char", 1) => Some(SystemClauseType::GetChar),
|
("$get_char", 1) => Some(SystemClauseType::GetChar),
|
||||||
|
("$get_single_char", 1) => Some(SystemClauseType::GetSingleChar),
|
||||||
("$points_to_cont_reset_marker", 1) => {
|
("$points_to_cont_reset_marker", 1) => {
|
||||||
Some(SystemClauseType::PointsToContinuationResetMarker)
|
Some(SystemClauseType::PointsToContinuationResetMarker)
|
||||||
}
|
}
|
||||||
@@ -506,7 +507,6 @@ impl SystemClauseType {
|
|||||||
("$get_cp", 1) => Some(SystemClauseType::GetCutPoint),
|
("$get_cp", 1) => Some(SystemClauseType::GetCutPoint),
|
||||||
("$install_new_block", 1) => Some(SystemClauseType::InstallNewBlock),
|
("$install_new_block", 1) => Some(SystemClauseType::InstallNewBlock),
|
||||||
("$quoted_token", 1) => Some(SystemClauseType::QuotedToken),
|
("$quoted_token", 1) => Some(SystemClauseType::QuotedToken),
|
||||||
("$raw_input_read_char", 1) => Some(SystemClauseType::RawInputReadChar),
|
|
||||||
("$nextEP", 3) => Some(SystemClauseType::NextEP),
|
("$nextEP", 3) => Some(SystemClauseType::NextEP),
|
||||||
("$read_query_term", 2) => Some(SystemClauseType::ReadQueryTerm),
|
("$read_query_term", 2) => Some(SystemClauseType::ReadQueryTerm),
|
||||||
("$read_term", 2) => Some(SystemClauseType::ReadTerm),
|
("$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]).
|
write_term_to_chars/3]).
|
||||||
|
|
||||||
:- use_module(library(iso_ext)).
|
:- 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) :-
|
read_term_from_chars(Chars, Term) :-
|
||||||
( var(Chars) ->
|
( var(Chars) ->
|
||||||
throw(error(instantiation_error, read_term_from_chars/2))
|
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::event::{read, Event, KeyCode, KeyEvent};
|
||||||
use crate::crossterm::terminal::{enable_raw_mode, disable_raw_mode};
|
use crate::crossterm::terminal::{enable_raw_mode, disable_raw_mode};
|
||||||
|
|
||||||
pub enum ContinueResult {
|
pub fn get_single_char() -> char {
|
||||||
ContinueQuery,
|
let c;
|
||||||
Conclude,
|
enable_raw_mode().expect("failed to enable raw mode");
|
||||||
Help,
|
|
||||||
PrintWithoutMaxDepth,
|
|
||||||
PrintWithMaxDepth
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn next_keypress() -> ContinueResult {
|
|
||||||
loop {
|
loop {
|
||||||
match read() {
|
if let Ok(Event::Key(KeyEvent { code, .. })) = read() {
|
||||||
Ok(Event::Key(KeyEvent { code, .. })) => {
|
match code {
|
||||||
match code {
|
KeyCode::Char(ch) => {
|
||||||
KeyCode::Char('w') => {
|
c = ch;
|
||||||
return ContinueResult::PrintWithoutMaxDepth;
|
break;
|
||||||
}
|
},
|
||||||
KeyCode::Char('p') => {
|
KeyCode::Enter => {
|
||||||
return ContinueResult::PrintWithMaxDepth;
|
c = '\n';
|
||||||
}
|
break;
|
||||||
KeyCode::Char(' ') | KeyCode::Char(';') | KeyCode::Char('n') => {
|
},
|
||||||
return ContinueResult::ContinueQuery;
|
KeyCode::Tab => {
|
||||||
}
|
c = '\t';
|
||||||
KeyCode::Char('.') => {
|
break;
|
||||||
return ContinueResult::Conclude;
|
},
|
||||||
}
|
_ => ()
|
||||||
KeyCode::Char('h') => {
|
|
||||||
return ContinueResult::Help;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
disable_raw_mode().expect("failed to disable raw mode");
|
||||||
|
c
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BrentAlgState {
|
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 => {
|
&SystemClauseType::GetModuleClause => {
|
||||||
let module = self[temp_v!(3)];
|
let module = self[temp_v!(3)];
|
||||||
let head = self[temp_v!(1)];
|
let head = self[temp_v!(1)];
|
||||||
@@ -2880,26 +2877,6 @@ impl MachineState {
|
|||||||
&SystemClauseType::InstallNewBlock => {
|
&SystemClauseType::InstallNewBlock => {
|
||||||
self.install_new_block(temp_v!(1));
|
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 => {
|
&SystemClauseType::NextEP => {
|
||||||
let first_arg = self.store(self.deref(self[temp_v!(1)]));
|
let first_arg = self.store(self.deref(self[temp_v!(1)]));
|
||||||
|
|
||||||
|
|||||||
@@ -145,30 +145,31 @@
|
|||||||
).
|
).
|
||||||
|
|
||||||
'$read_input'(ThreadedGoals, NewVarList) :-
|
'$read_input'(ThreadedGoals, NewVarList) :-
|
||||||
'$raw_input_read_char'(C),
|
get_single_char(C),
|
||||||
( C == w ->
|
( C = w ->
|
||||||
nl,
|
nl,
|
||||||
write(' '),
|
write(' '),
|
||||||
'$write_eq'(ThreadedGoals, NewVarList, 0),
|
'$write_eq'(ThreadedGoals, NewVarList, 0),
|
||||||
'$read_input'(ThreadedGoals, NewVarList)
|
'$read_input'(ThreadedGoals, NewVarList)
|
||||||
; C == p ->
|
; C = p ->
|
||||||
nl,
|
nl,
|
||||||
write(' '),
|
write(' '),
|
||||||
'$write_eq'(ThreadedGoals, NewVarList, 20),
|
'$write_eq'(ThreadedGoals, NewVarList, 20),
|
||||||
'$read_input'(ThreadedGoals, NewVarList)
|
'$read_input'(ThreadedGoals, NewVarList)
|
||||||
; C == (';') ->
|
; member(C, [';', ' ', n]) ->
|
||||||
nl, write('; '), false
|
nl, write('; '), false
|
||||||
; C == h ->
|
; C = h ->
|
||||||
'$help_message',
|
'$help_message',
|
||||||
'$read_input'(ThreadedGoals, NewVarList)
|
'$read_input'(ThreadedGoals, NewVarList)
|
||||||
; C == '.',
|
; member(C, ['\n', .]) ->
|
||||||
nl, write('; ...'), nl
|
nl, write('; ...'), nl
|
||||||
|
; '$read_input'(ThreadedGoals, NewVarList)
|
||||||
).
|
).
|
||||||
|
|
||||||
'$help_message' :-
|
'$help_message' :-
|
||||||
nl, nl,
|
nl, nl,
|
||||||
write('SPACE, "n" or ";": next solution, if any\n'),
|
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('"h": display this help message\n'),
|
||||||
write('"w": write terms without depth limit\n'),
|
write('"w": write terms without depth limit\n'),
|
||||||
write('"p": print terms with depth limit\n\n').
|
write('"p": print terms with depth limit\n\n').
|
||||||
|
|||||||
Reference in New Issue
Block a user