Ground,
#[strum_discriminants(strum(props(Arity = "2", Name = "is")))]
Is(RegType, ArithmeticTerm),
+ #[strum_discriminants(strum(props(Arity = "1", Name = "$get_number")))]
+ GetNumber(ArithmeticTerm),
#[strum_discriminants(strum(props(Arity = "2", Name = "keysort")))]
KeySort,
#[strum_discriminants(strum(props(Arity = "2", Name = "sort")))]
&Instruction::CallFunctor |
&Instruction::CallGround |
&Instruction::CallKeySort |
- &Instruction::CallSort => {
+ &Instruction::CallSort |
+ &Instruction::CallGetNumber(_) => {
let (name, arity) = self.to_name_and_arity();
functor!(atom!("call"), [atom(name), fixnum(arity)])
}
&Instruction::ExecuteGround |
&Instruction::ExecuteIs(..) |
&Instruction::ExecuteKeySort |
- &Instruction::ExecuteSort => {
+ &Instruction::ExecuteSort |
+ &Instruction::ExecuteGetNumber(_) => {
let (name, arity) = self.to_name_and_arity();
functor!(atom!("execute"), [atom(name), fixnum(arity)])
}
&Instruction::DefaultCallGround |
&Instruction::DefaultCallIs(..) |
&Instruction::DefaultCallKeySort |
- &Instruction::DefaultCallSort => {
+ &Instruction::DefaultCallSort |
+ &Instruction::DefaultCallGetNumber(_) => {
let (name, arity) = self.to_name_and_arity();
functor!(atom!("call_default"), [atom(name), fixnum(arity)])
}
&Instruction::DefaultExecuteGround |
&Instruction::DefaultExecuteIs(..) |
&Instruction::DefaultExecuteKeySort |
- &Instruction::DefaultExecuteSort => {
+ &Instruction::DefaultExecuteSort |
+ &Instruction::DefaultExecuteGetNumber(_) => {
let (name, arity) = self.to_name_and_arity();
functor!(atom!("execute_default"), [atom(name), fixnum(arity)])
}
);
self.marker.mark_safe_var_unconditionally(var_num);
+ compile_expr!(self, &terms[1], term_loc, code)
} else {
- if self.marker.in_tail_position {
- if self.marker.var_data.allocates {
- code.push_back(instr!("deallocate"));
+ if let Term::Var(ref vr, ref var) = &terms[1] {
+ let var_num = var.to_var_num().unwrap();
+
+ // if var is an anonymous variable, insert
+ // is/2 call so that an instantiation error is
+ // thrown when the predicate is run.
+ if self.marker.var_data.records[var_num].num_occurrences > 1 {
+ self.marker.mark_var::<QueryInstruction>(
+ var_num,
+ Level::Shallow,
+ vr,
+ term_loc,
+ code,
+ );
+
+ self.marker.mark_safe_var_unconditionally(var_num);
+
+ let at = ArithmeticTerm::Reg(vr.get().norm());
+ self.add_call(code, instr!("$get_number", at), call_policy);
+
+ return Ok(());
}
-
- code.push_back(instr!("proceed"));
}
- return Ok(());
+ compile_expr!(self, &terms[1], term_loc, code)
}
-
- compile_expr!(self, &terms[1], term_loc, code)
}
&Term::Literal(_, c @ Literal::Integer(_) |
c @ Literal::Float(_) |
try_or_throw!(self.machine_st, self.machine_st.is(r, at));
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
}
+ Instruction::DefaultCallGetNumber(at) => {
+ try_or_throw!(self.machine_st, self.machine_st.get_number(at));
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ Instruction::DefaultExecuteGetNumber(at) => {
+ try_or_throw!(self.machine_st, self.machine_st.get_number(at));
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
&Instruction::CallAcyclicTerm => {
let addr = self.machine_st.registers[1];
self.machine_st.p = self.machine_st.cp;
}
}
+ Instruction::CallGetNumber(at) => {
+ try_or_throw!(self.machine_st, self.machine_st.get_number(at));
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p += 1;
+ }
+ }
+ Instruction::ExecuteGetNumber(at) => {
+ try_or_throw!(self.machine_st, self.machine_st.get_number(at));
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p = self.machine_st.cp;
+ }
+ }
&Instruction::CallN(arity) => {
let pred = self.machine_st.registers[1];