]> Repositorios git - scryer-prolog.git/commitdiff
Added predicate for reading a single character
authornotoria <[email protected]>
Sat, 18 Apr 2020 09:49:28 +0000 (11:49 +0200)
committernotoria <[email protected]>
Sat, 18 Apr 2020 09:49:28 +0000 (11:49 +0200)
src/prolog/clause_types.rs
src/prolog/lib/builtins.pl
src/prolog/machine/system_calls.rs

index 7100855e238591dbc582c0617256b07877fa3076..37c8f612f52d197ce6e59dc90e055f4d5f79e916 100644 (file)
@@ -178,6 +178,7 @@ pub enum SystemClauseType {
     FetchGlobalVar,
     FetchGlobalVarWithOffset,
     GetChar,
+    GetSingleChar,
     ResetAttrVarState,
     TruncateIfNoLiftedHeapGrowthDiff,
     TruncateIfNoLiftedHeapGrowth,
@@ -309,6 +310,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")
@@ -455,6 +457,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)
             }
index 17235d3bd56bf442ba5574847a7b75ae8004d3f7..15c81403c98363121bfa7ea00b168ee00a2e2575 100644 (file)
@@ -47,8 +47,8 @@ user:term_expansion((:- op(Pred, Spec, [Op | OtherOps])), OpResults) :-
                      current_input/1, current_output/1, current_op/3,
                      current_predicate/1, current_prolog_flag/2,
                      expand_goal/2, expand_term/2, fail/0, false/0,
-                     findall/3, findall/4, get_char/1, halt/0,
-                     max_arity/1, number_chars/2, number_codes/2,
+                     findall/3, findall/4, get_char/1, get_single_char/1,
+                     halt/0, max_arity/1, number_chars/2, number_codes/2,
                      once/1, op/3, read_term/2, repeat/0, retract/1,
                      set_prolog_flag/2, set_input/1, set_output/1,
                      setof/3, sub_atom/5, subsumes_term/2,
@@ -933,6 +933,13 @@ get_char(C) :-
     ;  throw(error(type_error(in_character, C), get_char/1))
     ).
 
+get_single_char(C) :-
+    (  var(C) -> '$get_single_char'(C)
+    ;  C == end_of_file  -> '$get_single_char'(C)
+    ;  atom_length(C, 1) -> '$get_single_char'(C)
+    ;  throw(error(type_error(in_character, C), get_char/1))
+    ).
+
 can_be_number(N, PI) :-
     (  var(N) -> true
     ;  must_be_number(N, PI)
index cd9cc86f16aa0e117ff944d1cc837a435a726788..bd35d6e6f06b461301c125cf6742765b2a51b6b2 100644 (file)
@@ -67,6 +67,24 @@ pub fn next_keypress() -> ContinueResult {
     }
 }
 
+pub fn get_single_char() -> char {
+    let c;
+    enable_raw_mode().expect("failed to enable raw mode");
+    loop {
+        if let Ok(Event::Key(KeyEvent { code, .. })) = read() {
+            match code {
+                KeyCode::Char(ch) => {
+                    c = ch;
+                    break;
+                },
+                _ => ()
+            }
+        }
+    }
+    disable_raw_mode().expect("failed to disable raw mode");
+    c
+}
+
 struct BrentAlgState {
     hare: Addr,
     tortoise: Addr,
@@ -1463,6 +1481,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)];