remove is from inlined terms.

This commit is contained in:
Mark Thom
2017-11-13 13:35:34 -07:00
parent ded701436a
commit 4a51496981
4 changed files with 61 additions and 76 deletions

View File

@@ -310,7 +310,6 @@ pub enum Term {
} }
pub enum InlinedQueryTerm { pub enum InlinedQueryTerm {
Is(Vec<Box<Term>>),
IsAtomic(Vec<Box<Term>>), IsAtomic(Vec<Box<Term>>),
IsVar(Vec<Box<Term>>) IsVar(Vec<Box<Term>>)
} }
@@ -318,8 +317,8 @@ pub enum InlinedQueryTerm {
impl InlinedQueryTerm { impl InlinedQueryTerm {
pub fn arity(&self) -> usize { pub fn arity(&self) -> usize {
match self { match self {
&InlinedQueryTerm::Is(_) => 2, &InlinedQueryTerm::IsAtomic(_) => 1,
_ => 1 &InlinedQueryTerm::IsVar(_) => 1
} }
} }
} }
@@ -328,6 +327,7 @@ pub enum QueryTerm {
CallN(Vec<Box<Term>>), CallN(Vec<Box<Term>>),
Catch(Vec<Box<Term>>), Catch(Vec<Box<Term>>),
Cut, Cut,
Is(Vec<Box<Term>>),
Inlined(InlinedQueryTerm), Inlined(InlinedQueryTerm),
Term(Term), Term(Term),
Throw(Vec<Box<Term>>) Throw(Vec<Box<Term>>)
@@ -339,6 +339,7 @@ impl QueryTerm {
&QueryTerm::Catch(_) => 3, &QueryTerm::Catch(_) => 3,
&QueryTerm::Throw(_) => 1, &QueryTerm::Throw(_) => 1,
&QueryTerm::Inlined(ref term) => term.arity(), &QueryTerm::Inlined(ref term) => term.arity(),
&QueryTerm::Is(_) => 2,
&QueryTerm::CallN(ref terms) => terms.len(), &QueryTerm::CallN(ref terms) => terms.len(),
&QueryTerm::Cut => 0, &QueryTerm::Cut => 0,
&QueryTerm::Term(ref term) => term.arity(), &QueryTerm::Term(ref term) => term.arity(),

View File

@@ -235,8 +235,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
{ {
match term { match term {
&InlinedQueryTerm::IsAtomic(_) | &InlinedQueryTerm::IsVar(_) => &InlinedQueryTerm::IsAtomic(_) | &InlinedQueryTerm::IsVar(_) =>
code.push(proceed!()), code.push(proceed!())
_ => {}
}; };
} }
@@ -292,63 +291,21 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
} }
fn compile_inlined(&mut self, term: &'a InlinedQueryTerm, term_loc: GenContext, code: &mut Code) fn compile_inlined(&mut self, term: &'a InlinedQueryTerm, term_loc: GenContext, code: &mut Code)
-> Result<(), ParserError>
{ {
match term { match term {
&InlinedQueryTerm::Is(ref terms) => { &InlinedQueryTerm::IsAtomic(ref inner_term) =>
let mut arith_code = { match inner_term[0].as_ref() {
let mut evaluator = ArithmeticEvaluator::new(self.marker.bindings()); &Term::AnonVar | &Term::Clause(_, _, _) | &Term::Cons(_, _, _) => {
evaluator.eval(terms[1].as_ref())? code.push(fail!());
}; },
&Term::Constant(_, _) => {
code.append(&mut arith_code); code.push(succeed!());
},
match terms[0].as_ref() { &Term::Var(ref vr, ref name) => {
&Term::Var(ref vr, ref name) => { let r = self.mark_non_callable(name, 1, term_loc, vr, code);
let r = self.mark_non_callable(name, code.push(is_atomic!(r));
2,
term_loc,
vr,
code);
code.push(is_call!(r));
},
&Term::Constant(_, Constant::Float(fl)) => {
code.push(query![put_constant!(Level::Shallow,
Constant::Float(fl),
temp_v!(1))]);
code.push(is_call!(temp_v!(1)));
},
&Term::Constant(_, Constant::Integer(ref bi)) => {
let bi = bi.clone();
code.push(query![put_constant!(Level::Shallow,
Constant::Integer(bi),
temp_v!(1))]);
code.push(is_call!(temp_v!(1)));
},
_ => {
return Err(ParserError::from(ArithmeticError::InvalidTerm));
}
} }
}, },
&InlinedQueryTerm::IsAtomic(ref inner_term) =>
match inner_term[0].as_ref() {
&Term::AnonVar | &Term::Clause(_, _, _) | &Term::Cons(_, _, _) => {
code.push(fail!());
},
&Term::Constant(_, _) => {
code.push(succeed!());
},
&Term::Var(ref vr, ref name) => {
let r = self.mark_non_callable(name,
1,
term_loc,
vr,
code);
code.push(is_atomic!(r));
}
},
&InlinedQueryTerm::IsVar(ref inner_term) => &InlinedQueryTerm::IsVar(ref inner_term) =>
match inner_term[0].as_ref() { match inner_term[0].as_ref() {
&Term::Constant(_, _) | &Term::Clause(_, _, _) | &Term::Cons(_, _, _) => { &Term::Constant(_, _) | &Term::Clause(_, _, _) | &Term::Cons(_, _, _) => {
@@ -358,18 +315,11 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
code.push(succeed!()); code.push(succeed!());
}, },
&Term::Var(ref vr, ref name) => { &Term::Var(ref vr, ref name) => {
let r = self.mark_non_callable(name, let r = self.mark_non_callable(name, 1, term_loc, vr, code);
1,
term_loc,
vr,
code);
code.push(is_var!(r)); code.push(is_var!(r));
} }
} }
} }
Ok(())
} }
fn compile_seq(&mut self, fn compile_seq(&mut self,
@@ -377,7 +327,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
conjunct_info: &ConjunctInfo<'a>, conjunct_info: &ConjunctInfo<'a>,
code: &mut Code, code: &mut Code,
is_exposed: bool) is_exposed: bool)
-> Result<(), ParserError> -> Result<(), ParserError>
{ {
for (chunk_num, _, terms) in iter { for (chunk_num, _, terms) in iter {
for (i, term) in terms.iter().enumerate() for (i, term) in terms.iter().enumerate()
@@ -403,7 +353,43 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
}); });
}, },
&QueryTerm::Inlined(ref term) => &QueryTerm::Inlined(ref term) =>
try!(self.compile_inlined(term, term_loc, code)), self.compile_inlined(term, term_loc, code),
&QueryTerm::Is(ref terms) => {
let mut arith_code = {
let mut evaluator = ArithmeticEvaluator::new(self.marker.bindings());
evaluator.eval(terms[1].as_ref())?
};
code.append(&mut arith_code);
match terms[0].as_ref() {
&Term::Var(ref vr, ref name) => {
let r = self.mark_non_callable(name,
2,
term_loc,
vr,
code);
code.push(is_call!(r));
},
&Term::Constant(_, Constant::Float(fl)) => {
code.push(query![put_constant!(Level::Shallow,
Constant::Float(fl),
temp_v!(1))]);
code.push(is_call!(temp_v!(1)));
},
&Term::Constant(_, Constant::Integer(ref bi)) => {
let bi = bi.clone();
code.push(query![put_constant!(Level::Shallow,
Constant::Integer(bi),
temp_v!(1))]);
code.push(is_call!(temp_v!(1)));
},
_ => {
return Err(ParserError::from(ArithmeticError::InvalidTerm));
}
}
},
_ if chunk_num == 0 => { _ if chunk_num == 0 => {
self.marker.reset_arg(term.arity()); self.marker.reset_arg(term.arity());
@@ -423,7 +409,6 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
Ok(()) Ok(())
} }
fn compile_seq_prelude(&mut self, conjunct_info: &ConjunctInfo, body: &mut Code) fn compile_seq_prelude(&mut self, conjunct_info: &ConjunctInfo, body: &mut Code)
{ {
if conjunct_info.allocates() { if conjunct_info.allocates() {

View File

@@ -40,7 +40,7 @@ impl<'a> QueryIterator<'a> {
let state = IteratorState::Clause(0, ClauseType::Catch, terms); let state = IteratorState::Clause(0, ClauseType::Catch, terms);
QueryIterator { state_stack: vec![state] } QueryIterator { state_stack: vec![state] }
}, },
&QueryTerm::Inlined(InlinedQueryTerm::Is(ref terms)) => { &QueryTerm::Is(ref terms) => {
let state = IteratorState::Clause(0, ClauseType::Is, terms); let state = IteratorState::Clause(0, ClauseType::Is, terms);
QueryIterator { state_stack: vec![state] } QueryIterator { state_stack: vec![state] }
}, },
@@ -270,13 +270,12 @@ impl<'a> ChunkedIterator<'a>
arity = child_terms.len(); arity = child_terms.len();
break; break;
}, },
&QueryTerm::Inlined(InlinedQueryTerm::Is(_)) => { &QueryTerm::Is(_) => {
result.push(term); result.push(term);
arity = 2; arity = 2;
break; break;
}, },
&QueryTerm::Inlined(InlinedQueryTerm::IsAtomic(_)) &QueryTerm::Inlined(_) =>
| &QueryTerm::Inlined(InlinedQueryTerm::IsVar(_)) =>
result.push(term), result.push(term),
&QueryTerm::Cut => { &QueryTerm::Cut => {
result.push(term); result.push(term);