]> Repositorios git - scryer-prolog.git/commitdiff
support number/1
authorMark Thom <[email protected]>
Wed, 4 Nov 2020 06:38:55 +0000 (23:38 -0700)
committerMark Thom <[email protected]>
Wed, 4 Nov 2020 06:38:55 +0000 (23:38 -0700)
src/clause_types.rs
src/codegen.rs
src/machine/machine_state_impl.rs
src/macros.rs

index 339c7d38804bb27e87123fac3c599134b17b10b8..dbaefb6962ded0ce751790caa5f9d37c4c7fa636 100644 (file)
@@ -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",
index f23e4c93d5db6a2a8901b7726cd9e3acf291de64..a1811985f7b486d2023cbee89b64c3697eb299eb 100644 (file)
@@ -474,6 +474,23 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
                     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<TermMarker> {
             },
             &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) => {
index ed5deb81894f315152fa68837da8fda330e12153..849e18f59fc77e81dbe4a229e40c986b172642ac 100644 (file)
@@ -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]));
 
index dabdb3ded7ee09c3b8a32591db3a09987d6f042c..7de7da2f8795ce8129d8510b09c861f44d74109d 100644 (file)
@@ -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)