use must_be(chars) in number_chars/2 (#1470)

This commit is contained in:
Mark Thom
2022-05-12 00:00:37 -06:00
parent bfbafd4168
commit cea1353fbb
2 changed files with 32 additions and 31 deletions

View File

@@ -1410,24 +1410,34 @@ codes_or_vars([C|Cs], PI) :-
). ).
number_chars(N, Chs) :- number_chars(N, Chs) :-
( ground(Chs) ( ground(Chs) ->
-> can_be_number(N, number_chars/2), can_be_number(N, number_chars/2),
can_be_list(Chs, number_chars/2), catch(error:must_be(chars, Chs),
'$chars_to_number'(Chs, Nx), error(E, _),
Nx = N builtins:throw(error(E, number_chars/2))
; must_be_number(N, number_chars/2), ),
( var(Chs) -> true '$chars_to_number'(Chs, Nx),
; can_be_list(Chs, number_chars/2) Nx = N
, chars_or_vars(Chs, number_chars/2) ; must_be_number(N, number_chars/2),
), ( var(Chs) -> true
'$number_to_chars'(N, Chsx), ; can_be_list(Chs, number_chars/2),
Chsx = Chs 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) :- number_codes(N, Chs) :-
( ground(Chs) ( ground(Chs) ->
-> can_be_number(N, number_codes/2), can_be_number(N, number_codes/2),
can_be_list(Chs, number_codes/2), catch(builtins:list_of_ints(Chs),
error(E, _),
builtins:throw(error(E, number_codes/2))
),
'$codes_to_number'(Chs, Nx), '$codes_to_number'(Chs, Nx),
Nx = N Nx = N
; must_be_number(N, number_codes/2), ; must_be_number(N, number_codes/2),
@@ -1437,7 +1447,7 @@ number_codes(N, Chs) :-
), ),
'$number_to_codes'(N, Chsx), '$number_to_codes'(N, Chsx),
Chsx = Chs Chsx = Chs
). ).
subsumes_term(General, Specific) :- subsumes_term(General, Specific) :-
\+ \+ ( \+ \+ (

View File

@@ -1423,22 +1423,13 @@ impl Machine {
pub(crate) fn chars_to_number(&mut self) -> CallResult { pub(crate) fn chars_to_number(&mut self) -> CallResult {
let stub_gen = || functor_stub(atom!("number_chars"), 2); 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 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(
self.machine_st.parse_number_from_string( atom_or_string.as_str(),
atom_or_string.as_str(), &self.indices,
&self.indices, stub_gen,
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(())
} }
#[inline(always)] #[inline(always)]