use crate::forms::*;
use crate::instructions::*;
use crate::iterators::*;
+use crate::targets::QueryInstruction;
use crate::types::*;
use crate::parser::ast::*;
subterms,
));
- self.push_subterm(lvl, &subterms[child_num]);
+ self.push_subterm(lvl.child_level(), &subterms[child_num]);
}
}
TermIterState::Literal(_, _, c) => return Some(Ok(ArithTermRef::Literal(c))),
TermIterState::Var(lvl, cell, var) => {
- // the expression is the second argument of an
- // is/2 but the iterator can't see that, so the
- // level needs to be demoted manually.
- return Some(Ok(ArithTermRef::Var(lvl.child_level(), cell, var.clone())));
+ return Some(Ok(ArithTermRef::Var(lvl, cell, var.clone())));
}
_ => {
return Some(Err(ArithmeticError::NonEvaluableFunctor(
}
}
- pub(crate) fn eval(
+ pub(crate) fn compile_is(
&mut self,
src: &'a Term,
term_loc: GenContext,
match term_ref? {
ArithTermRef::Literal(c) => push_literal(&mut self.interm, c)?,
ArithTermRef::Var(lvl, cell, name) => {
- let r = if cell.get().norm().reg_num() == 0 {
- let mut getter = || {
- use crate::targets::QueryInstruction;
-
- loop {
- match self.marker.bindings().get(&name) {
- Some(&VarData::Temp(_, t, _)) if t != 0 =>
- return RegType::Temp(t),
- Some(&VarData::Perm(p)) if p != 0 =>
- return RegType::Perm(p),
- _ => {
- self.marker.mark_var::<QueryInstruction>(
- name.clone(),
- lvl,
- cell,
- term_loc,
- &mut code,
- );
- }
- }
+ let r = if lvl == Level::Shallow && term_loc.is_last() {
+ self.marker.mark_var::<QueryInstruction>(
+ name.clone(),
+ lvl,
+ cell,
+ term_loc,
+ &mut code,
+ );
+
+ self.interm.push(ArithmeticTerm::Reg(temp_v!(2)));
+ continue;
+ } else if cell.get().norm().reg_num() == 0 {
+ self.marker.mark_var::<QueryInstruction>(
+ name.clone(),
+ lvl,
+ cell,
+ term_loc,
+ &mut code,
+ );
+
+ match self.marker.bindings().get(&name) {
+ Some(&VarData::Temp(_, t, _)) if t != 0 =>
+ RegType::Temp(t),
+ Some(&VarData::Perm(p)) if p != 0 =>
+ RegType::Perm(p),
+ _ => {
+ unreachable!()
}
- };
-
- getter()
- /*
- _ => return Err(ArithmeticError::UninstantiatedVar),
- */
+ }
} else {
cell.get().norm()
};
perm_v!(1),
false,
);
+
continue;
}
}
};
self.update_var_count(chunked_term.post_order_iter());
-
vs.mark_vars_in_chunk(chunked_term.post_order_iter(), lt_arity, term_loc);
}
}
term_loc: GenContext,
) -> Result<ArithCont, ArithmeticError> {
let mut evaluator = ArithmeticEvaluator::new(&mut self.marker, target_int);
- evaluator.eval(term, term_loc)
+ evaluator.compile_is(term, term_loc)
}
fn compile_is_call(
// the peculiar condition of this block, when false,
// anticipates code.pop_front() being called about a
// dozen lines below.
- debug_assert_eq!(code.len(), 1);
self.increment_jmp_by_locs_by(code.len());
}
}
}))
}
- /*
- pub(crate) fn from_term_sequence(terms: &'a [QueryTerm]) -> Self {
- ChunkedIterator {
- chunk_num: 0,
- iter: Box::new(terms.iter().map(|t| ChunkedTerm::BodyTerm(t))),
- deep_cut_encountered: false,
- cut_var_in_head: false,
- }
- }
- */
+
pub(crate) fn from_rule_body(p1: &'a QueryTerm, clauses: &'a Vec<QueryTerm>) -> Self {
let inner_iter = Box::new(once(ChunkedTerm::BodyTerm(p1)));
let iter = inner_iter.chain(clauses.iter().map(|t| ChunkedTerm::BodyTerm(t)));