From: Mark Thom Date: Sun, 10 May 2020 21:46:51 +0000 (-0600) Subject: use heap_pstr_iter in AtomChars (#482) X-Git-Tag: v0.8.123~44 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=540bc71873631c1c7474e831ca0b2da80651ede1;p=scryer-prolog.git use heap_pstr_iter in AtomChars (#482) --- diff --git a/src/prolog/lib/builtins.pl b/src/prolog/lib/builtins.pl index 798e201a..0cf39457 100644 --- a/src/prolog/lib/builtins.pl +++ b/src/prolog/lib/builtins.pl @@ -932,7 +932,7 @@ atom_chars(Atom, List) :- ), ( var(Atom) -> ( var(Tail) -> throw(error(instantiation_error, atom_chars/2)) - ; ground(List), Tail == [] -> '$atom_chars'(Atom, List) + ; ground(List) -> '$atom_chars'(Atom, List) ; throw(error(instantiation_error, atom_chars/2)) ) ; atom(Atom) -> can_be_chars_or_vars(List, atom_chars/2), '$atom_chars'(Atom, List) diff --git a/src/prolog/machine/system_calls.rs b/src/prolog/machine/system_calls.rs index b1abfdd2..02599716 100644 --- a/src/prolog/machine/system_calls.rs +++ b/src/prolog/machine/system_calls.rs @@ -864,30 +864,34 @@ impl MachineState { self.unify(a2, list_of_chars); } addr if addr.is_ref() => { - let stub = MachineError::functor_stub(clause_name!("atom_chars"), 2); + let mut iter = self.heap_pstr_iter(self[temp_v!(2)]); + let string = iter.to_string(); + + match iter.focus() { + Addr::EmptyList => { + let chars = clause_name!(string, indices.atom_tbl); + let atom = self.heap.to_unifiable( + HeapCellValue::Atom(chars, None) + ); - match self.try_from_list(temp_v!(2), stub) { - Err(e) => { - return Err(e); + self.unify(addr, atom); } - Ok(addrs) => { - match self.try_char_list(addrs) { - Ok(string) => { - let chars = clause_name!(string, indices.atom_tbl); - let atom = self.heap.to_unifiable( - HeapCellValue::Atom(chars, None) - ); - - self.unify(addr, atom); - } - Err(err) => { - let stub = MachineError::functor_stub( - clause_name!("atom_chars"), - 2, - ); + focus => { + let stub = MachineError::functor_stub( + clause_name!("atom_chars"), + 2, + ); - return Err(self.error_form(err, stub)); - } + if let Addr::Lis(l) = focus { + let err = MachineError::type_error( + self.heap.h(), + ValidType::Character, + Addr::HeapCell(l), + ); + + return Err(self.error_form(err, stub)); + } else { + unreachable!() } } }