From 1ea6ae9fd90ff0067e47a3e1190cbe112c9e5700 Mon Sep 17 00:00:00 2001 From: notoria Date: Sat, 18 Apr 2020 11:49:28 +0200 Subject: [PATCH] Added predicate for reading a single character --- src/prolog/clause_types.rs | 3 +++ src/prolog/lib/builtins.pl | 11 +++++++++-- src/prolog/machine/system_calls.rs | 25 +++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/prolog/clause_types.rs b/src/prolog/clause_types.rs index 7100855e..37c8f612 100644 --- a/src/prolog/clause_types.rs +++ b/src/prolog/clause_types.rs @@ -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) } diff --git a/src/prolog/lib/builtins.pl b/src/prolog/lib/builtins.pl index 17235d3b..15c81403 100644 --- a/src/prolog/lib/builtins.pl +++ b/src/prolog/lib/builtins.pl @@ -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) diff --git a/src/prolog/machine/system_calls.rs b/src/prolog/machine/system_calls.rs index cd9cc86f..bd35d6e6 100644 --- a/src/prolog/machine/system_calls.rs +++ b/src/prolog/machine/system_calls.rs @@ -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)]; -- 2.54.0