From 72a7765b5885ca578cf5ef8f1d6617465b7690d3 Mon Sep 17 00:00:00 2001 From: Regan-Koopmans Date: Thu, 17 Jun 2021 12:10:25 +0200 Subject: [PATCH] 981 Reimplement as library system call --- src/clause_types.rs | 3 +++ src/lib/arithmetic.pl | 6 +++++- src/machine/system_calls.rs | 13 +++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/clause_types.rs b/src/clause_types.rs index d45fdf5a..e6559417 100644 --- a/src/clause_types.rs +++ b/src/clause_types.rs @@ -310,6 +310,7 @@ pub(crate) enum SystemClauseType { SetSTOWithErrorAsUnify, HomeDirectory, DebugHook, + PopCount } impl SystemClauseType { @@ -603,6 +604,7 @@ impl SystemClauseType { clause_name!("$set_sto_with_error_as_unify") } &SystemClauseType::DebugHook => clause_name!("$debug_hook"), + &SystemClauseType::PopCount => clause_name!("$popcount"), } } @@ -854,6 +856,7 @@ impl SystemClauseType { ("$set_sto_with_error_as_unify", 0) => Some(SystemClauseType::SetSTOWithErrorAsUnify), ("$home_directory", 1) => Some(SystemClauseType::HomeDirectory), ("$debug_hook", 0) => Some(SystemClauseType::DebugHook), + ("$popcount", 2) => Some(SystemClauseType::PopCount), _ => None, } } diff --git a/src/lib/arithmetic.pl b/src/lib/arithmetic.pl index f0d2b58e..3d3a6625 100644 --- a/src/lib/arithmetic.pl +++ b/src/lib/arithmetic.pl @@ -1,5 +1,5 @@ :- module(arithmetic, [expmod/4, lsb/2, msb/2, number_to_rational/2, - number_to_rational/3, + number_to_rational/3, popcount/2, rational_numerator_denominator/3]). :- use_module(library(charsio), [write_term_to_chars/3]). @@ -121,3 +121,7 @@ rational_numerator_denominator(R, N, D) :- append(Ns, [' ', r, d, i, v, ' '|Ds], Cs), number_chars(N, Ns), number_chars(D, Ds). + +popcount(X, N) :- + integer(X), + '$popcount'(X, N). diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index 29c4fbff..ade423a1 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -5539,6 +5539,19 @@ impl MachineState { &SystemClauseType::DebugHook => { self.fail = false; } + &SystemClauseType::PopCount => { + let number = self.store(self.deref(self[temp_v!(1)])); + let count = match Number::try_from((number, &self.heap)) { + Ok(Number::Fixnum(n)) => Integer::from(n.count_ones()), + Ok(Number::Integer(n)) => Integer::from((&*n).count_ones().unwrap()), + _ => { + unreachable!() + } + }; + + let pop_count = self.heap.to_unifiable(HeapCellValue::Integer(Rc::new(count))); + (self.unify_fn)(self, self[temp_v!(2)], pop_count); + } }; return_from_clause!(self.last_call, self) -- 2.54.0