eliminate QueryTermRef.

This commit is contained in:
Mark Thom
2017-11-11 18:57:23 -07:00
parent 1f19d5de95
commit e5a235cf80
6 changed files with 170 additions and 198 deletions

View File

@@ -181,8 +181,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
let mut vs = VariableFixtures::new();
let at_rule_head = iter.at_rule_head();
while let Some((chunk_num, last_term_arity, terms)) = iter.next() {
for (i, term_or_cut_ref) in terms.iter().enumerate() {
while let Some((chunk_num, lt_arity, terms)) = iter.next() {
for (i, query_term) in terms.iter().enumerate() {
let term_loc = if chunk_num == 0 && i == 0 && at_rule_head {
GenContext::Head
} else if i < terms.len() - 1 {
@@ -191,10 +191,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
GenContext::Last(chunk_num)
};
self.update_var_count(term_or_cut_ref.post_order_iter());
vs.mark_vars_in_chunk(term_or_cut_ref.post_order_iter(),
last_term_arity,
term_loc);
self.update_var_count(query_term.post_order_iter());
vs.mark_vars_in_chunk(query_term.post_order_iter(), lt_arity, term_loc);
}
}
@@ -209,26 +207,26 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
ConjunctInfo::new(vs, num_of_chunks, has_deep_cut)
}
fn add_conditional_call(compiled_query: &mut Code, qt: QueryTermRef, pvs: usize)
fn add_conditional_call(compiled_query: &mut Code, qt: &QueryTerm, pvs: usize)
{
match qt {
QueryTermRef::CallN(terms) => {
&QueryTerm::CallN(ref terms) => {
let call = ControlInstruction::CallN(terms.len());
compiled_query.push(Line::Control(call));
},
QueryTermRef::Catch(_) =>
&QueryTerm::Catch(_) =>
compiled_query.push(Line::Control(ControlInstruction::CatchCall)),
QueryTermRef::IsAtomic(_) | QueryTermRef::IsVar(_) =>
&QueryTerm::IsAtomic(_) | &QueryTerm::IsVar(_) =>
compiled_query.push(proceed!()),
QueryTermRef::Term(&Term::Constant(_, Constant::Atom(ref atom))) => {
&QueryTerm::Term(Term::Constant(_, Constant::Atom(ref atom))) => {
let call = ControlInstruction::Call(atom.clone(), 0, pvs);
compiled_query.push(Line::Control(call));
},
QueryTermRef::Term(&Term::Clause(_, ref atom, ref terms)) => {
&QueryTerm::Term(Term::Clause(_, ref atom, ref terms)) => {
let call = ControlInstruction::Call(atom.clone(), terms.len(), pvs);
compiled_query.push(Line::Control(call));
},
QueryTermRef::Throw(_) =>
&QueryTerm::Throw(_) =>
compiled_query.push(Line::Control(ControlInstruction::ThrowCall)),
_ => {}
}
@@ -276,22 +274,21 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
GenContext::Last(chunk_num)
};
match term {
&QueryTermRef::Cut if i + 1 < terms.len() => {
code.push(if chunk_num == 0 {
Line::Cut(CutInstruction::NeckCut(Terminal::Non))
match *term {
&QueryTerm::Cut => {
let term = if i + 1 < terms.len() {
Terminal::Non
} else {
Line::Cut(CutInstruction::Cut(Terminal::Non))
Terminal::Terminal
};
code.push(if chunk_num == 0 {
Line::Cut(CutInstruction::NeckCut(term))
} else {
Line::Cut(CutInstruction::Cut(term))
});
},
&QueryTermRef::Cut => {
code.push(if chunk_num == 0 {
Line::Cut(CutInstruction::NeckCut(Terminal::Terminal))
} else {
Line::Cut(CutInstruction::Cut(Terminal::Terminal))
});
},
&QueryTermRef::Is(terms) => {
&QueryTerm::Is(ref terms) => {
let mut arith_code = {
let mut evaluator = ArithmeticEvaluator::new(self.marker.bindings());
evaluator.eval(terms[1].as_ref())?
@@ -335,8 +332,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
}
}
},
&QueryTermRef::IsAtomic(inner_term) =>
match inner_term {
&QueryTerm::IsAtomic(ref inner_term) =>
match inner_term[0].as_ref() {
&Term::AnonVar | &Term::Clause(_, _, _) | &Term::Cons(_, _, _) => {
code.push(fail!());
},
@@ -361,8 +358,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
}
},
},
&QueryTermRef::IsVar(inner_term) =>
match inner_term {
&QueryTerm::IsVar(ref inner_term) =>
match inner_term[0].as_ref() {
&Term::Constant(_, _) | &Term::Clause(_, _, _) | &Term::Cons(_, _, _) => {
code.push(fail!());
},
@@ -392,11 +389,11 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
let iter = term.post_order_iter();
code.push(Line::Query(self.compile_target(iter, term_loc, is_exposed)));
Self::add_conditional_call(code, *term, conjunct_info.perm_vars());
Self::add_conditional_call(code, term, conjunct_info.perm_vars());
},
_ => {
let num_vars = conjunct_info.perm_vs.vars_above_threshold(i + 1);
self.compile_query_line(*term, term_loc, code, num_vars, is_exposed);
self.compile_query_line(term, term_loc, code, num_vars, is_exposed);
},
};
@@ -420,11 +417,11 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
}
}
fn compile_cleanup(code: &mut Code, conjunct_info: &ConjunctInfo, toc: QueryTermRef<'a>)
fn compile_cleanup(code: &mut Code, conjunct_info: &ConjunctInfo, toc: &'a QueryTerm)
{
//TODO: temporary workaround for inlined builtins.
match toc {
QueryTermRef::IsAtomic(_) | QueryTermRef::IsVar(_) =>
&QueryTerm::IsAtomic(_) | &QueryTerm::IsVar(_) =>
code.push(proceed!()),
_ => {}
}
@@ -447,28 +444,32 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
self.marker.advance(GenContext::Head, p0.arity());
self.compile_seq_prelude(&conjunct_info, &mut code);
if p0.is_clause() {
let iter = FactInstruction::iter(p0);
code.push(Line::Fact(self.compile_target(iter, GenContext::Head, false)));
}
let iter = ChunkedIterator::from_rule_body(p1, clauses);
try!(self.compile_seq(iter, &conjunct_info, &mut code, false));
if conjunct_info.allocates() {
let index = if let &Line::Control(_) = code.last().unwrap() {
code.len() - 2
} else {
code.len() - 1
};
if let &mut Line::Query(ref mut query) = &mut code[index] {
conjunct_info.perm_vs.mark_unsafe_vars_in_rule(p0, query);
if let &QueryTerm::Term(ref term) = p0 {
if let &Term::Clause(_, _, _) = term {
let iter = FactInstruction::iter(term);
code.push(Line::Fact(self.compile_target(iter, GenContext::Head, false)));
}
}
let iter = ChunkedIterator::from_rule_body(p1, clauses);
try!(self.compile_seq(iter, &conjunct_info, &mut code, false));
Self::compile_cleanup(&mut code, &conjunct_info, clauses.last().unwrap_or(p1).to_ref());
Ok(code)
if conjunct_info.allocates() {
let index = if let &Line::Control(_) = code.last().unwrap() {
code.len() - 2
} else {
code.len() - 1
};
if let &mut Line::Query(ref mut query) = &mut code[index] {
conjunct_info.perm_vs.mark_unsafe_vars_in_rule(term, query);
}
}
Self::compile_cleanup(&mut code, &conjunct_info, clauses.last().unwrap_or(p1));
Ok(code)
} else {
Err(ParserError::InvalidRuleHead)
}
}
fn mark_unsafe_fact_vars(&self, fact: &mut CompiledFact)
@@ -512,7 +513,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
let mut code = Vec::new();
if term.is_clause() {
if let &Term::Clause(_, _, _) = term {
let iter = FactInstruction::iter(term);
let mut compiled_fact = self.compile_target(iter, GenContext::Head, false);
@@ -525,7 +526,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
}
fn compile_query_line(&mut self,
term: QueryTermRef<'a>,
term: &'a QueryTerm,
term_loc: GenContext,
code: &mut Code,
index: usize,
@@ -564,7 +565,10 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
}
}
Self::compile_cleanup(&mut code, &conjunct_info, query.last().unwrap().to_ref());
if let Some(query_term) = query.last() {
Self::compile_cleanup(&mut code, &conjunct_info, query_term);
}
Ok(code)
}