]> Repositorios git - scryer-prolog.git/commitdiff
add more type predicates.
authorMark Thom <[email protected]>
Tue, 6 Feb 2018 03:10:41 +0000 (20:10 -0700)
committerMark Thom <[email protected]>
Tue, 6 Feb 2018 03:10:41 +0000 (20:10 -0700)
README.md
src/prolog/ast.rs
src/prolog/builtins.rs
src/prolog/codegen.rs
src/prolog/io.rs
src/prolog/iterators.rs
src/prolog/machine/machine_state_impl.rs
src/prolog/macros.rs
src/prolog/parser
src/tests.rs

index 3e609d35679452450770aa2f7d2bd58540a4856c..1fbeb7ca7a10392bff844fb61f06a5bc0f282525 100644 (file)
--- a/README.md
+++ b/README.md
@@ -88,19 +88,24 @@ The following predicates are built-in to rusty-wam.
 * `between/3`
 * `call/1..63`
 * `catch/3`
+* `compound/1`
 * `display/1`
 * `duplicate_term/2`
 * `false/0`
+* `float/1`
 * `functor/3`
 * `integer/1`
 * `length/2`
 * `maplist/1..8`
 * `member/2`
 * `memberchk/2`
+* `nonvar/1`
 * `once/1`
+* `rational/1`
 * `reverse/2`
 * `select/3`
 * `setup_call_cleanup/3`
+* `string/1`
 * `throw/1`
 * `true/0`
 * `var/1`
index dc31d649a969ba4e413b5a73af88454824122edb..386c83b57c744787f45f4b521291653c1d81de6c 100644 (file)
@@ -341,8 +341,13 @@ pub enum Term {
 pub enum InlinedQueryTerm {
     CompareNumber(CompareNumberQT, Vec<Box<Term>>),    
     IsAtomic(Vec<Box<Term>>),
-    IsVar(Vec<Box<Term>>),
-    IsInteger(Vec<Box<Term>>)    
+    IsCompound(Vec<Box<Term>>),
+    IsInteger(Vec<Box<Term>>),
+    IsRational(Vec<Box<Term>>),
+    IsString(Vec<Box<Term>>),
+    IsFloat(Vec<Box<Term>>),
+    IsNonVar(Vec<Box<Term>>),
+    IsVar(Vec<Box<Term>>),    
 }
 
 impl InlinedQueryTerm {
@@ -350,6 +355,11 @@ impl InlinedQueryTerm {
         match self {
             &InlinedQueryTerm::CompareNumber(_, _) => 2,            
             &InlinedQueryTerm::IsAtomic(_) => 1,
+            &InlinedQueryTerm::IsCompound(_) => 1,
+            &InlinedQueryTerm::IsFloat(_) => 1,
+            &InlinedQueryTerm::IsRational(_) => 1,
+            &InlinedQueryTerm::IsString(_) => 1,
+            &InlinedQueryTerm::IsNonVar(_) => 1,
             &InlinedQueryTerm::IsInteger(_) => 1,
             &InlinedQueryTerm::IsVar(_) => 1,            
         }
@@ -800,7 +810,12 @@ pub enum BuiltInInstruction {
     InstallNewBlock,
     InternalCallN,
     IsAtomic(RegType),
-    IsInteger(RegType),    
+    IsCompound(RegType),
+    IsFloat(RegType),
+    IsInteger(RegType),
+    IsNonVar(RegType),
+    IsRational(RegType),
+    IsString(RegType),
     IsVar(RegType),
     ResetBlock,
     SetBall,
index c9555b2648641e0aabe84cf3ae3e1c3093d77693..5d2c89bd94b5a5e6f5048187c91c8c42789bac6c 100644 (file)
@@ -524,7 +524,17 @@ fn get_builtins(atom_tbl: TabledData<Atom>) -> Code {
          reset_block!(),
          cut!(perm_v!(1)),
          deallocate!(),
-         proceed!()
+         proceed!(),
+         is_compound!(temp_v!(1)), // compound/1, 370.
+         proceed!(),
+         is_rational!(temp_v!(1)), // rational/1, 372.
+         proceed!(),
+         is_string!(temp_v!(1)), // string/1, 374.
+         proceed!(),
+         is_float!(temp_v!(1)), // float/1, 376.
+         proceed!(),
+         is_nonvar!(temp_v!(1)), // nonvar/1, 378.
+         proceed!(),
     ]
 }
 
@@ -611,6 +621,11 @@ pub fn build_code_dir(atom_tbl: TabledData<Atom>) -> (Code, CodeDir, OpDir)
 
     code_dir.insert((tabled_rc!("length", atom_tbl), 2), (PredicateKeyType::BuiltIn, 261));
     code_dir.insert((tabled_rc!("setup_call_cleanup", atom_tbl), 3), (PredicateKeyType::BuiltIn, 294));
-
+    code_dir.insert((tabled_rc!("compound", atom_tbl), 1), (PredicateKeyType::BuiltIn, 370));
+    code_dir.insert((tabled_rc!("rational", atom_tbl), 1), (PredicateKeyType::BuiltIn, 372));
+    code_dir.insert((tabled_rc!("string", atom_tbl), 1), (PredicateKeyType::BuiltIn, 374));
+    code_dir.insert((tabled_rc!("float", atom_tbl), 1), (PredicateKeyType::BuiltIn, 376));
+    code_dir.insert((tabled_rc!("nonvar", atom_tbl), 1), (PredicateKeyType::BuiltIn, 378));
+    
     (builtin_code, code_dir, op_dir)
 }
index ac6ce83e66464af1dde5370add2ebffa5c03c339..8e5f0c41cfb90dc06cbc1edf0cc67b52bdf639e0 100644 (file)
@@ -350,6 +350,71 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
                         code.push(is_atomic!(r));
                     }
                 },
+            &InlinedQueryTerm::IsCompound(ref inner_term) =>
+                match inner_term[0].as_ref() {
+                    &Term::Clause(..) => {
+                        code.push(succeed!());
+                    },
+                    &Term::Var(ref vr, ref name) => {
+                        let r = self.mark_non_callable(name, 1, term_loc, vr, code);
+                        code.push(is_compound!(r));
+                    },
+                    _ => {
+                        code.push(fail!());
+                    }
+                },
+            &InlinedQueryTerm::IsRational(ref inner_term) =>
+                match inner_term[0].as_ref() {
+                    &Term::Constant(_, Constant::Number(Number::Rational(_))) => {
+                        code.push(succeed!());
+                    },
+                    &Term::Var(ref vr, ref name) => {
+                        let r = self.mark_non_callable(name, 1, term_loc, vr, code);
+                        code.push(is_rational!(r));
+                    },
+                    _ => {
+                        code.push(fail!());
+                    }
+                },
+            &InlinedQueryTerm::IsFloat(ref inner_term) =>
+                match inner_term[0].as_ref() {
+                    &Term::Constant(_, Constant::Number(Number::Float(_))) => {
+                        code.push(succeed!());
+                    },
+                    &Term::Var(ref vr, ref name) => {
+                        let r = self.mark_non_callable(name, 1, term_loc, vr, code);
+                        code.push(is_float!(r));
+                    },
+                    _ => {
+                        code.push(fail!());
+                    }
+                },
+            &InlinedQueryTerm::IsString(ref inner_term) =>
+                match inner_term[0].as_ref() {
+                    &Term::Constant(_, Constant::String(_)) => {
+                        code.push(succeed!());
+                    },
+                    &Term::Var(ref vr, ref name) => {
+                        let r = self.mark_non_callable(name, 1, term_loc, vr, code);
+                        code.push(is_string!(r));
+                    },
+                    _ => {
+                        code.push(fail!());
+                    }
+                },
+            &InlinedQueryTerm::IsNonVar(ref inner_term) =>
+                match inner_term[0].as_ref() {
+                    &Term::AnonVar => {
+                        code.push(fail!());
+                    },                    
+                    &Term::Var(ref vr, ref name) => {
+                        let r = self.mark_non_callable(name, 1, term_loc, vr, code);
+                        code.push(is_nonvar!(r));
+                    },
+                    _ => {
+                        code.push(succeed!());
+                    }
+                },
             &InlinedQueryTerm::IsInteger(ref inner_term) =>
                 match inner_term[0].as_ref() {
                     &Term::Constant(_, Constant::Number(Number::Integer(_))) => {
index 5d467db6e494adede1a367e1f2c0d091f06886e1..3119ad2dd2fa8a4152ff80562e3cf07d0df8b70f 100644 (file)
@@ -201,8 +201,18 @@ impl fmt::Display for BuiltInInstruction {
                 write!(f, "internal_call_N"),
             &BuiltInInstruction::IsAtomic(r) =>
                 write!(f, "is_atomic {}", r),
+            &BuiltInInstruction::IsCompound(r) =>
+                write!(f, "is_compound {}", r),
+            &BuiltInInstruction::IsFloat(r) =>
+                write!(f, "is_float {}", r),
+            &BuiltInInstruction::IsRational(r) =>
+                write!(f, "is_rational {}", r),
+            &BuiltInInstruction::IsNonVar(r) =>
+                write!(f, "is_non_var {}", r),
+            &BuiltInInstruction::IsString(r) =>
+                write!(f, "is_string {}", r),
             &BuiltInInstruction::IsInteger(r) =>
-                write!(f, "is_integer {}", r),
+                write!(f, "is_integer {}", r),            
             &BuiltInInstruction::DynamicIs =>
                 write!(f, "call_is"),
             &BuiltInInstruction::IsVar(r) =>
index 80146fc170173a3b3cdf6d7bd5a1358a86754f95..ab63e2ddf403145f0f29a0232b0d16b5982a1a25 100644 (file)
@@ -67,7 +67,12 @@ impl<'a> QueryIterator<'a> {
             },
             &QueryTerm::Inlined(InlinedQueryTerm::IsAtomic(ref terms))
           | &QueryTerm::Inlined(InlinedQueryTerm::IsInteger(ref terms))
-          | &QueryTerm::Inlined(InlinedQueryTerm::IsVar(ref terms)) =>
+          | &QueryTerm::Inlined(InlinedQueryTerm::IsVar(ref terms))
+          | &QueryTerm::Inlined(InlinedQueryTerm::IsNonVar(ref terms))
+          | &QueryTerm::Inlined(InlinedQueryTerm::IsFloat(ref terms))
+          | &QueryTerm::Inlined(InlinedQueryTerm::IsRational(ref terms))
+          | &QueryTerm::Inlined(InlinedQueryTerm::IsCompound(ref terms))
+          | &QueryTerm::Inlined(InlinedQueryTerm::IsString(ref terms)) =>      
                 Self::from_term(terms[0].as_ref()),
             &QueryTerm::Term(ref term) =>
                 Self::from_term(term),
index 9ff1225070afa9f3862073fa84804f173132c330..57c1f094d09ea81525bc4e71c1097dc852231238 100644 (file)
@@ -1283,6 +1283,46 @@ impl MachineState {
                     _ => self.fail = true
                 };
             },
+            &BuiltInInstruction::IsCompound(r) => {
+                let d = self.store(self.deref(self[r].clone()));
+
+                match d {
+                    Addr::Str(_) => self.p += 1,
+                    _ => self.fail = true
+                };
+            },
+            &BuiltInInstruction::IsFloat(r) => {
+                let d = self.store(self.deref(self[r].clone()));
+
+                match d {
+                    Addr::Con(Constant::Number(Number::Float(_))) => self.p += 1,
+                    _ => self.fail = true
+                };
+            },
+            &BuiltInInstruction::IsRational(r) => {
+                let d = self.store(self.deref(self[r].clone()));
+
+                match d {
+                    Addr::Con(Constant::Number(Number::Rational(_))) => self.p += 1,
+                    _ => self.fail = true
+                };
+            },
+            &BuiltInInstruction::IsString(r) => {
+                let d = self.store(self.deref(self[r].clone()));
+
+                match d {
+                    Addr::Con(Constant::String(_)) => self.p += 1,
+                    _ => self.fail = true
+                };
+            },
+            &BuiltInInstruction::IsNonVar(r) => {
+                let d = self.store(self.deref(self[r].clone()));
+
+                match d {
+                    Addr::HeapCell(_) | Addr::StackCell(..) => self.fail = true,
+                    _ => self.p += 1
+                };
+            },
             &BuiltInInstruction::IsVar(r) => {
                 let d = self.store(self.deref(self[r].clone()));
 
index 2195a24563a9d8f7c7369cf628b73af565edec7c..2220a669b02f4ce805d1a4fe5e9de1c08bf93497 100644 (file)
@@ -168,6 +168,37 @@ macro_rules! is_integer {
     )
 }
 
+macro_rules! is_compound {
+    ($r:expr) => (
+        Line::BuiltIn(BuiltInInstruction::IsCompound($r))
+    )
+}
+
+macro_rules! is_float {
+    ($r:expr) => (
+        Line::BuiltIn(BuiltInInstruction::IsFloat($r))
+    )
+}
+
+macro_rules! is_rational {
+    ($r:expr) => (
+        Line::BuiltIn(BuiltInInstruction::IsRational($r))
+    )
+}
+
+
+macro_rules! is_nonvar {
+    ($r:expr) => (
+        Line::BuiltIn(BuiltInInstruction::IsNonVar($r))
+    )
+}
+
+macro_rules! is_string {
+    ($r:expr) => (
+        Line::BuiltIn(BuiltInInstruction::IsString($r))
+    )
+}
+
 macro_rules! is_var {
     ($reg:expr) => (
         Line::BuiltIn(BuiltInInstruction::IsVar($reg))
index 87d0d493e69e5cde80f454d21f8caa33cbffca3e..7687a367636a79972788b2633de8fbba7778eb10 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 87d0d493e69e5cde80f454d21f8caa33cbffca3e
+Subproject commit 7687a367636a79972788b2633de8fbba7778eb10
index bf0df94b6529f62ad64d9778bb0d3e31710e8a25..64c7573f0e263a7eee05ad5c0e322f5fb516f259 100644 (file)
@@ -1290,6 +1290,44 @@ fn test_queries_on_builtins()
     assert_prolog_failure!(&mut wam, "?- duplicate_term(g(X), f(X)).");
     assert_prolog_success!(&mut wam, "?- duplicate_term(f(X), f(X)).",
                            [["X = _1"]]);
+
+    assert_prolog_success!(&mut wam, "?- float(3.14159269).");
+    assert_prolog_failure!(&mut wam, "?- float(3).");
+    assert_prolog_failure!(&mut wam, "?- float(\"sdfsa\").");
+    assert_prolog_failure!(&mut wam, "?- float(atom).");
+    assert_prolog_failure!(&mut wam, "?- float(structure(functor)).");
+    assert_prolog_failure!(&mut wam, "?- float([1,2,3]).");
+    assert_prolog_failure!(&mut wam, "?- X is 3 rdiv 4, float(X).");
+
+    assert_prolog_success!(&mut wam, "?- X is 3 rdiv 4, rational(X).");
+    assert_prolog_failure!(&mut wam, "?- rational(3).");
+    assert_prolog_failure!(&mut wam, "?- rational(\"sdfsa\").");
+    assert_prolog_failure!(&mut wam, "?- rational(atom).");
+    assert_prolog_failure!(&mut wam, "?- rational(structure(functor)).");
+    assert_prolog_failure!(&mut wam, "?- rational([1,2,3]).");
+
+    assert_prolog_success!(&mut wam, "?- compound(functor(compound)).");
+    assert_prolog_failure!(&mut wam, "?- compound(3.14159269).");
+    assert_prolog_failure!(&mut wam, "?- compound(3).");
+    assert_prolog_failure!(&mut wam, "?- compound(\"sdfsa\").");
+    assert_prolog_failure!(&mut wam, "?- compound(atom).");
+    assert_prolog_failure!(&mut wam, "?- compound([1,2,3]).");
+
+    assert_prolog_failure!(&mut wam, "?- string(functor(string)).");
+    assert_prolog_failure!(&mut wam, "?- string(3.14159269).");
+    assert_prolog_failure!(&mut wam, "?- string(3).");
+    assert_prolog_success!(&mut wam, "?- string(\"sdfsa\").");
+    assert_prolog_failure!(&mut wam, "?- string(atom).");
+    assert_prolog_failure!(&mut wam, "?- string([1,2,3]).");
+    
+    assert_prolog_success!(&mut wam, "?- X = nonvar, nonvar(X).");
+    assert_prolog_failure!(&mut wam, "?- nonvar(X).");
+    assert_prolog_success!(&mut wam, "?- nonvar(functor(nonvar)).");
+    assert_prolog_success!(&mut wam, "?- nonvar(3.14159269).");
+    assert_prolog_success!(&mut wam, "?- nonvar(3).");
+    assert_prolog_success!(&mut wam, "?- nonvar(\"sdfsa\").");
+    assert_prolog_success!(&mut wam, "?- nonvar(atom).");
+    assert_prolog_success!(&mut wam, "?- nonvar([1,2,3]).");
 }
 
 #[test]