}
}
-#[derive(Copy, Clone, PartialEq)]
+#[derive(Clone, PartialEq)]
pub enum BuiltInClauseType {
AcyclicTerm,
Arg,
Eq,
Functor,
Ground,
- Is,
+ Is(RegType, ArithmeticTerm),
KeySort,
NotEq,
Sort,
fn fixity(&self) -> Option<Fixity> {
match self {
&BuiltInClauseType::Compare | &BuiltInClauseType::CompareTerm(_)
- | &BuiltInClauseType::NotEq | &BuiltInClauseType::Is | &BuiltInClauseType::Eq
+ | &BuiltInClauseType::NotEq | &BuiltInClauseType::Is(..) | &BuiltInClauseType::Eq
=> Some(Fixity::In),
_ => None
}
&BuiltInClauseType::Eq => clause_name!("=="),
&BuiltInClauseType::Functor => clause_name!("functor"),
&BuiltInClauseType::Ground => clause_name!("ground"),
- &BuiltInClauseType::Is => clause_name!("is"),
+ &BuiltInClauseType::Is(..) => clause_name!("is"),
&BuiltInClauseType::KeySort => clause_name!("keysort"),
&BuiltInClauseType::NotEq => clause_name!("\\=="),
&BuiltInClauseType::Sort => clause_name!("sort"),
&BuiltInClauseType::Eq => 2,
&BuiltInClauseType::Functor => 3,
&BuiltInClauseType::Ground => 1,
- &BuiltInClauseType::Is => 2,
+ &BuiltInClauseType::Is(..) => 2,
&BuiltInClauseType::KeySort => 2,
&BuiltInClauseType::NotEq => 2,
&BuiltInClauseType::Sort => 2,
("==", 2) => Some(BuiltInClauseType::Eq),
("functor", 3) => Some(BuiltInClauseType::Functor),
("ground", 1) => Some(BuiltInClauseType::Ground),
- ("is", 2) => Some(BuiltInClauseType::Is),
+ ("is", 2) => Some(BuiltInClauseType::Is(temp_v!(1), ArithmeticTerm::Reg(temp_v!(2)))),
("keysort", 2) => Some(BuiltInClauseType::KeySort),
("\\==", 2) => Some(BuiltInClauseType::NotEq),
("sort", 2) => Some(BuiltInClauseType::Sort),
pub fn name(&self) -> ClauseName {
match self {
&ClauseType::CallN => clause_name!("call"),
- &ClauseType::BuiltIn(built_in) => built_in.name(),
+ &ClauseType::BuiltIn(ref built_in) => built_in.name(),
&ClauseType::Inlined(ref inlined) => clause_name!(inlined.name()),
&ClauseType::Op(ref name, ..) => name.clone(),
&ClauseType::Named(ref name, ..) => name.clone(),
CheckCpExecute,
Deallocate,
GetCleanerCall,
- IsClause(bool, RegType, ArithmeticTerm), // last call, register of var, term.
JmpBy(usize, usize, usize, bool), // arity, global_offset, perm_vars after threshold, last call.
Proceed
}
match self {
&ControlInstruction::CallClause(..) => true,
&ControlInstruction::GetCleanerCall => true,
- &ControlInstruction::IsClause(..) => true,
&ControlInstruction::JmpBy(..) => true,
_ => false
}
GenContext::Last(chunk_num)
}
};
-
+
self.update_var_count(chunked_term.post_order_iter());
vs.mark_vars_in_chunk(chunked_term.post_order_iter(), lt_arity, term_loc);
}
*ctrl = ControlInstruction::CallClause(ct, arity, pvs, true),
ControlInstruction::JmpBy(arity, offset, pvs, false) =>
*ctrl = ControlInstruction::JmpBy(arity, offset, pvs, true),
- ControlInstruction::IsClause(false, r, at) =>
- *ctrl = ControlInstruction::IsClause(true, r, at),
ControlInstruction::Proceed => {},
_ => dealloc_index += 1
},
code.append(&mut lcode);
code.append(&mut rcode);
-
+
code.push(compare_number_instr!(cmp,
at_1.unwrap_or(interm!(1)),
at_2.unwrap_or(interm!(2))));
} else {
Line::Cut(CutInstruction::Cut(perm_v!(1)))
}),
- &QueryTerm::Clause(_, ClauseType::BuiltIn(BuiltInClauseType::Is), ref terms) =>
+ &QueryTerm::Clause(_, ClauseType::BuiltIn(BuiltInClauseType::Is(..)), ref terms)
+ =>
{
let (mut acode, at) = self.call_arith_eval(terms[1].as_ref(), 1)?;
code.append(&mut acode);
write!(f, "deallocate"),
&ControlInstruction::GetCleanerCall =>
write!(f, "get_cleaner_call"),
- &ControlInstruction::IsClause(false, r, ref at) =>
- write!(f, "is_call {}, {}", r, at),
- &ControlInstruction::IsClause(true, r, ref at) =>
- write!(f, "is_execute {}, {}", r, at),
&ControlInstruction::JmpBy(arity, offset, pvs, false) =>
write!(f, "jmp_by_call {}/{}, {}", offset, arity, pvs),
&ControlInstruction::JmpBy(arity, offset, pvs, true) =>
let b = machine_st.b - 1;
let n = machine_st.or_stack[b].num_args();
- for i in 1 .. n + 1 {
+ for i in 1 .. n + 1 {
machine_st.registers[i] = machine_st.or_stack[b][i].clone();
}
return_from_clause!(machine_st.last_call, machine_st)
},
- &BuiltInClauseType::Is => {
- let a = machine_st[temp_v!(1)].clone();
- let result = machine_st.arith_eval_by_metacall(temp_v!(2))?;
+ &BuiltInClauseType::Is(r, ref at) => {
+ let a1 = machine_st[r].clone();
+ let a2 = machine_st.get_number(at)?;
- machine_st.unify(a, Addr::Con(Constant::Number(result)));
+ machine_st.unify(a1, Addr::Con(Constant::Number(a2)));
return_from_clause!(machine_st.last_call, machine_st)
},
}
};
}
- fn get_number(&self, at: &ArithmeticTerm) -> Result<Number, MachineError> {
+ pub(super) fn get_number(&self, at: &ArithmeticTerm) -> Result<Number, MachineError> {
match at {
&ArithmeticTerm::Reg(r) => self.arith_eval_by_metacall(r),
&ArithmeticTerm::Interm(i) => Ok(self.interms[i-1].clone()),
self.fail = true;
},
- &ControlInstruction::IsClause(lco, r, ref at) => {
- self.last_call = lco;
-
- let a1 = self[r].clone();
- let a2 = try_or_fail!(self, self.get_number(at));
-
- self.unify(a1, Addr::Con(Constant::Number(a2)));
- try_or_fail!(self, return_from_clause!(self.last_call, self));
- },
&ControlInstruction::JmpBy(arity, offset, _, lco) => {
if !lco {
self.cp.assign_if_local(self.p.clone() + 1);
CodePtr::Local(LocalCodePtr::DirEntry(p, _)) =>
Some(self.code[p].clone()),
CodePtr::BuiltInClause(built_in, _) =>
- Some(call_clause!(ClauseType::BuiltIn(built_in), built_in.arity(),
+ Some(call_clause!(ClauseType::BuiltIn(built_in.clone()), built_in.arity(),
0, self.ms.last_call)),
CodePtr::CallN(arity, _) =>
Some(call_clause!(ClauseType::CallN, arity, 0, self.ms.last_call))
}
macro_rules! is_call {
- ($r:expr, $at:expr) => (
- Line::Control(ControlInstruction::IsClause(false, $r, $at))
+ ($r:expr, $at:expr) => (
+ call_clause!(ClauseType::BuiltIn(BuiltInClauseType::Is($r, $at)), 2, 0)
)
}