From 540bc71873631c1c7474e831ca0b2da80651ede1 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Sun, 10 May 2020 15:46:51 -0600 Subject: [PATCH] use heap_pstr_iter in AtomChars (#482) --- src/prolog/lib/builtins.pl | 2 +- src/prolog/machine/system_calls.rs | 46 ++++++++++++++++-------------- 2 files changed, 26 insertions(+), 22 deletions(-) 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!() } } } -- 2.54.0