add atom predicate.

This commit is contained in:
Mark Thom
2018-03-10 15:26:35 -07:00
parent 2cc5367c52
commit 7500465b38
10 changed files with 248 additions and 205 deletions

View File

@@ -551,6 +551,7 @@ pub enum Term {
#[derive(Clone, Copy)]
pub enum InlinedClauseType {
CompareNumber(CompareNumberQT),
IsAtom,
IsAtomic,
IsCompound,
IsInteger,
@@ -565,6 +566,7 @@ impl InlinedClauseType {
pub fn name(&self) -> &'static str {
match self {
&InlinedClauseType::CompareNumber(qt) => qt.name(),
&InlinedClauseType::IsAtom => "atom",
&InlinedClauseType::IsAtomic => "atomic",
&InlinedClauseType::IsCompound => "compound",
&InlinedClauseType::IsInteger => "integer",
@@ -584,6 +586,7 @@ impl InlinedClauseType {
("<=", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::LessThanOrEqual)),
("=\\=", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::NotEqual)),
("=:=", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::Equal)),
("atom", 1) => Some(InlinedClauseType::IsAtom),
("atomic", 1) => Some(InlinedClauseType::IsAtomic),
("compound", 1) => Some(InlinedClauseType::IsCompound),
("integer", 1) => Some(InlinedClauseType::IsInteger),
@@ -1203,6 +1206,7 @@ pub enum BuiltInInstruction {
InstallInferenceCounter(RegType, RegType, RegType),
InstallNewBlock,
InternalCallN,
IsAtom(RegType),
IsAtomic(RegType),
IsCompound(RegType),
IsFloat(RegType),

View File

@@ -620,7 +620,9 @@ fn get_builtins() -> Code {
query![put_value!(temp_v!(5), 1)],
reset_block!(),
fail!(),
compare_execute!() // compare/3, 464.
compare_execute!(), // compare/3, 464.
is_atom!(temp_v!(1)), // atom/1, 465.
proceed!()
]
}
@@ -733,7 +735,8 @@ pub fn build_code_and_op_dirs() -> (CodeDir, OpDir)
code_dir.insert((clause_name!("=@="), 2), (391, builtin.clone()));
code_dir.insert((clause_name!("\\=@="), 2), (392, builtin.clone()));
code_dir.insert((clause_name!("compare"), 3), (464, builtin.clone()));
code_dir.insert((clause_name!("atom"), 1), (465, builtin.clone()));
(code_dir, op_dir)
}

View File

@@ -320,6 +320,19 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
at_1.unwrap_or(interm!(1)),
at_2.unwrap_or(interm!(2))));
},
InlinedClauseType::IsAtom =>
match terms[0].as_ref() {
&Term::Constant(_, Constant::Atom(_)) => {
code.push(succeed!());
},
&Term::Var(ref vr, ref name) => {
let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
code.push(is_atom!(r));
}
_ => {
code.push(fail!());
}
},
InlinedClauseType::IsAtomic =>
match terms[0].as_ref() {
&Term::AnonVar | &Term::Clause(..) | &Term::Cons(..) => {
@@ -608,12 +621,12 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
vs.populate_restricting_sets();
self.marker.drain_var_data(vs);
let mut code = Vec::new();
if let &Term::Clause(_, _, ref args, _) = term {
self.marker.reset_at_head(args);
let iter = FactInstruction::iter(term);
let mut compiled_fact = self.compile_target(iter, GenContext::Head, false);

View File

@@ -249,6 +249,8 @@ impl fmt::Display for BuiltInInstruction {
write!(f, "unwind_stack"),
&BuiltInInstruction::Unify =>
write!(f, "unify"),
&BuiltInInstruction::IsAtom(r) =>
write!(f, "is_atom {}", r),
&BuiltInInstruction::IsAtomic(r) =>
write!(f, "is_atomic {}", r),
&BuiltInInstruction::IsCompound(r) =>

View File

@@ -1350,6 +1350,14 @@ impl MachineState {
_ => self.throw_exception(functor!("type_error", 1, [heap_atom!("integer_expected")]))
};
},
&BuiltInInstruction::IsAtom(r) => {
let d = self.store(self.deref(self[r].clone()));
match d {
Addr::Con(Constant::Atom(_)) => self.p += 1,
_ => self.fail = true
};
},
&BuiltInInstruction::IsAtomic(r) => {
let d = self.store(self.deref(self[r].clone()));

View File

@@ -167,6 +167,12 @@ macro_rules! retry_me_else {
)
}
macro_rules! is_atom {
($reg:expr) => (
Line::BuiltIn(BuiltInInstruction::IsAtom($reg))
)
}
macro_rules! is_atomic {
($reg:expr) => (
Line::BuiltIn(BuiltInInstruction::IsAtomic($reg))