From b9a53e441ea8ced7ffe3c1974421fc961c8ba746 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Tue, 3 Nov 2020 23:38:55 -0700 Subject: [PATCH] support number/1 --- src/clause_types.rs | 3 +++ src/codegen.rs | 20 +++++++++++++++++++- src/machine/machine_state_impl.rs | 23 +++++++++++++++++++++++ src/macros.rs | 6 ++++++ 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/clause_types.rs b/src/clause_types.rs index 339c7d38..dbaefb69 100644 --- a/src/clause_types.rs +++ b/src/clause_types.rs @@ -74,6 +74,7 @@ pub enum InlinedClauseType { IsAtomic(RegType), IsCompound(RegType), IsInteger(RegType), + IsNumber(RegType), IsRational(RegType), IsFloat(RegType), IsNonVar(RegType), @@ -103,6 +104,7 @@ ref_thread_local! { m.insert(("atomic", 1), ClauseType::Inlined(InlinedClauseType::IsAtomic(r1))); m.insert(("compound", 1), ClauseType::Inlined(InlinedClauseType::IsCompound(r1))); m.insert(("integer", 1), ClauseType::Inlined(InlinedClauseType::IsInteger(r1))); + m.insert(("number", 1), ClauseType::Inlined(InlinedClauseType::IsNumber(r1))); m.insert(("rational", 1), ClauseType::Inlined(InlinedClauseType::IsRational(r1))); m.insert(("float", 1), ClauseType::Inlined(InlinedClauseType::IsFloat(r1))); m.insert(("nonvar", 1), ClauseType::Inlined(InlinedClauseType::IsNonVar(r1))); @@ -136,6 +138,7 @@ impl InlinedClauseType { &InlinedClauseType::IsAtom(..) => "atom", &InlinedClauseType::IsAtomic(..) => "atomic", &InlinedClauseType::IsCompound(..) => "compound", + &InlinedClauseType::IsNumber(..) => "number", &InlinedClauseType::IsInteger(..) => "integer", &InlinedClauseType::IsRational(..) => "rational", &InlinedClauseType::IsFloat(..) => "float", diff --git a/src/codegen.rs b/src/codegen.rs index f23e4c93..a1811985 100644 --- a/src/codegen.rs +++ b/src/codegen.rs @@ -474,6 +474,23 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator { code.push(fail!()); } }, + &InlinedClauseType::IsNumber(..) => match terms[0].as_ref() { + &Term::Constant(_, Constant::Float(_)) | + &Term::Constant(_, Constant::Rational(_)) | + &Term::Constant(_, Constant::Integer(_)) | + &Term::Constant(_, Constant::Fixnum(_)) | + &Term::Constant(_, Constant::Usize(_)) => { + code.push(succeed!()); + } + &Term::Var(ref vr, ref name) => { + self.marker.reset_arg(1); + let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code); + code.push(is_number!(r)); + } + _ => { + code.push(fail!()); + } + }, &InlinedClauseType::IsNonVar(..) => match terms[0].as_ref() { &Term::AnonVar => { code.push(fail!()); @@ -489,7 +506,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator { }, &InlinedClauseType::IsInteger(..) => match terms[0].as_ref() { &Term::Constant(_, Constant::Integer(_)) | - &Term::Constant(_, Constant::Fixnum(_)) => { + &Term::Constant(_, Constant::Fixnum(_)) | + &Term::Constant(_, Constant::Usize(_)) => { code.push(succeed!()); } &Term::Var(ref vr, ref name) => { diff --git a/src/machine/machine_state_impl.rs b/src/machine/machine_state_impl.rs index ed5deb81..849e18f5 100644 --- a/src/machine/machine_state_impl.rs +++ b/src/machine/machine_state_impl.rs @@ -2390,6 +2390,29 @@ impl MachineState { _ => self.fail = true, }; } + &InlinedClauseType::IsNumber(r1) => { + match self.store(self.deref(self[r1])) { + Addr::Float(_) => self.p += 1, + d => match Number::try_from((d, &self.heap)) { + Ok(Number::Fixnum(_)) => { + self.p += 1; + } + Ok(Number::Integer(_)) => { + self.p += 1; + } + Ok(Number::Rational(n)) => { + if n.denom() == &1 { + self.p += 1; + } else { + self.fail = true; + } + } + _ => { + self.fail = true; + } + } + } + } &InlinedClauseType::IsRational(r1) => { let d = self.store(self.deref(self[r1])); diff --git a/src/macros.rs b/src/macros.rs index dabdb3de..7de7da2f 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -219,6 +219,12 @@ macro_rules! is_rational { }; } +macro_rules! is_number { + ($r:expr) => { + call_clause!(ClauseType::Inlined(InlinedClauseType::IsNumber($r)), 1, 0) + }; +} + macro_rules! is_nonvar { ($r:expr) => { call_clause!(ClauseType::Inlined(InlinedClauseType::IsNonVar($r)), 1, 0) -- 2.54.0