diff --git a/src/lib/builtins.pl b/src/lib/builtins.pl index 786c56f25..bc91180ce 100644 --- a/src/lib/builtins.pl +++ b/src/lib/builtins.pl @@ -1410,24 +1410,34 @@ ). number_chars(N, Chs) :- - ( ground(Chs) - -> can_be_number(N, number_chars/2), - can_be_list(Chs, number_chars/2), - '$chars_to_number'(Chs, Nx), - Nx = N - ; must_be_number(N, number_chars/2), - ( var(Chs) -> true - ; can_be_list(Chs, number_chars/2) - , chars_or_vars(Chs, number_chars/2) - ), - '$number_to_chars'(N, Chsx), - Chsx = Chs + ( ground(Chs) -> + can_be_number(N, number_chars/2), + catch(error:must_be(chars, Chs), + error(E, _), + builtins:throw(error(E, number_chars/2)) + ), + '$chars_to_number'(Chs, Nx), + Nx = N + ; must_be_number(N, number_chars/2), + ( var(Chs) -> true + ; can_be_list(Chs, number_chars/2), + chars_or_vars(Chs, number_chars/2) + ), + '$number_to_chars'(N, Chsx), + Chsx = Chs ). +list_of_ints(Ns) :- + error:must_be(list, Ns), + lists:maplist(error:must_be(integer), Ns). + number_codes(N, Chs) :- - ( ground(Chs) - -> can_be_number(N, number_codes/2), - can_be_list(Chs, number_codes/2), + ( ground(Chs) -> + can_be_number(N, number_codes/2), + catch(builtins:list_of_ints(Chs), + error(E, _), + builtins:throw(error(E, number_codes/2)) + ), '$codes_to_number'(Chs, Nx), Nx = N ; must_be_number(N, number_codes/2), @@ -1437,7 +1447,7 @@ ), '$number_to_codes'(N, Chsx), Chsx = Chs - ). + ). subsumes_term(General, Specific) :- \+ \+ ( diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index 2e016abd6..5f4cc32b9 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -1423,22 +1423,13 @@ impl Machine { pub(crate) fn chars_to_number(&mut self) -> CallResult { let stub_gen = || functor_stub(atom!("number_chars"), 2); let a1 = self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1])); + let atom_or_string = self.machine_st.value_to_str_like(a1).unwrap(); - if let Some(atom_or_string) = self.machine_st.value_to_str_like(a1) { - self.machine_st.parse_number_from_string( - atom_or_string.as_str(), - &self.indices, - stub_gen, - )?; - } else { - // a1 is a ground list at the call site within - // number_chars/2, so failure of value_to_str_like - // means the list contains a non-character. - let err = self.machine_st.type_error(ValidType::Character, a1); - return Err(self.machine_st.error_form(err, stub_gen())); - } - - Ok(()) + self.machine_st.parse_number_from_string( + atom_or_string.as_str(), + &self.indices, + stub_gen, + ) } #[inline(always)]