From 4a51496981cda339f97b8703b0010fdd180d38d3 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Mon, 13 Nov 2017 13:35:34 -0700 Subject: [PATCH] remove is from inlined terms. --- src/prolog/ast.rs | 7 ++- src/prolog/codegen.rs | 121 ++++++++++++++++++---------------------- src/prolog/iterators.rs | 7 +-- src/prolog/parser | 2 +- 4 files changed, 61 insertions(+), 76 deletions(-) diff --git a/src/prolog/ast.rs b/src/prolog/ast.rs index e834a4b7..0f7c993e 100644 --- a/src/prolog/ast.rs +++ b/src/prolog/ast.rs @@ -310,7 +310,6 @@ pub enum Term { } pub enum InlinedQueryTerm { - Is(Vec>), IsAtomic(Vec>), IsVar(Vec>) } @@ -318,8 +317,8 @@ pub enum InlinedQueryTerm { impl InlinedQueryTerm { pub fn arity(&self) -> usize { match self { - &InlinedQueryTerm::Is(_) => 2, - _ => 1 + &InlinedQueryTerm::IsAtomic(_) => 1, + &InlinedQueryTerm::IsVar(_) => 1 } } } @@ -328,6 +327,7 @@ pub enum QueryTerm { CallN(Vec>), Catch(Vec>), Cut, + Is(Vec>), Inlined(InlinedQueryTerm), Term(Term), Throw(Vec>) @@ -339,6 +339,7 @@ impl QueryTerm { &QueryTerm::Catch(_) => 3, &QueryTerm::Throw(_) => 1, &QueryTerm::Inlined(ref term) => term.arity(), + &QueryTerm::Is(_) => 2, &QueryTerm::CallN(ref terms) => terms.len(), &QueryTerm::Cut => 0, &QueryTerm::Term(ref term) => term.arity(), diff --git a/src/prolog/codegen.rs b/src/prolog/codegen.rs index 9e332f3d..c2576160 100644 --- a/src/prolog/codegen.rs +++ b/src/prolog/codegen.rs @@ -235,8 +235,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker> { match term { &InlinedQueryTerm::IsAtomic(_) | &InlinedQueryTerm::IsVar(_) => - code.push(proceed!()), - _ => {} + code.push(proceed!()) }; } @@ -290,65 +289,23 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker> dealloc_index } - + fn compile_inlined(&mut self, term: &'a InlinedQueryTerm, term_loc: GenContext, code: &mut Code) - -> Result<(), ParserError> { match term { - &InlinedQueryTerm::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)); - } - } - }, &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)); - } + 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) => match inner_term[0].as_ref() { &Term::Constant(_, _) | &Term::Clause(_, _, _) | &Term::Cons(_, _, _) => { @@ -358,26 +315,19 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker> code.push(succeed!()); }, &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, 1, term_loc, vr, code); code.push(is_var!(r)); } } } - - Ok(()) } - + fn compile_seq(&mut self, iter: ChunkedIterator<'a>, conjunct_info: &ConjunctInfo<'a>, code: &mut Code, is_exposed: bool) - -> Result<(), ParserError> + -> Result<(), ParserError> { for (chunk_num, _, terms) in iter { for (i, term) in terms.iter().enumerate() @@ -403,7 +353,43 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker> }); }, &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 => { self.marker.reset_arg(term.arity()); @@ -423,7 +409,6 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker> Ok(()) } - fn compile_seq_prelude(&mut self, conjunct_info: &ConjunctInfo, body: &mut Code) { if conjunct_info.allocates() { diff --git a/src/prolog/iterators.rs b/src/prolog/iterators.rs index f8545cf9..190dd1f8 100644 --- a/src/prolog/iterators.rs +++ b/src/prolog/iterators.rs @@ -40,7 +40,7 @@ impl<'a> QueryIterator<'a> { let state = IteratorState::Clause(0, ClauseType::Catch, terms); QueryIterator { state_stack: vec![state] } }, - &QueryTerm::Inlined(InlinedQueryTerm::Is(ref terms)) => { + &QueryTerm::Is(ref terms) => { let state = IteratorState::Clause(0, ClauseType::Is, terms); QueryIterator { state_stack: vec![state] } }, @@ -270,13 +270,12 @@ impl<'a> ChunkedIterator<'a> arity = child_terms.len(); break; }, - &QueryTerm::Inlined(InlinedQueryTerm::Is(_)) => { + &QueryTerm::Is(_) => { result.push(term); arity = 2; break; }, - &QueryTerm::Inlined(InlinedQueryTerm::IsAtomic(_)) - | &QueryTerm::Inlined(InlinedQueryTerm::IsVar(_)) => + &QueryTerm::Inlined(_) => result.push(term), &QueryTerm::Cut => { result.push(term); diff --git a/src/prolog/parser b/src/prolog/parser index 41d2d7d2..ae1e2b15 160000 --- a/src/prolog/parser +++ b/src/prolog/parser @@ -1 +1 @@ -Subproject commit 41d2d7d26fd855bcb4f486411333d3671c648aaa +Subproject commit ae1e2b153e9f63a966837bddb5a297f75f09ecfb -- 2.54.0