add more type predicates.
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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(_))) => {
|
||||
|
||||
@@ -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) =>
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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()));
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
Submodule src/prolog/parser updated: 87d0d493e6...7687a36763
38
src/tests.rs
38
src/tests.rs
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user