From 66075bf45b85112f99169f2510efc66c859d4fa6 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Sun, 17 Apr 2022 17:33:09 -0600 Subject: [PATCH] mark unsafe variables and substitute temporary variables in is/2 when appropriate (#1430) --- src/arithmetic.rs | 64 +++++++++++++++++++++++------------------------ src/codegen.rs | 5 ++-- src/forms.rs | 2 +- src/iterators.rs | 11 +------- src/parser/ast.rs | 10 ++++++++ 5 files changed, 46 insertions(+), 46 deletions(-) diff --git a/src/arithmetic.rs b/src/arithmetic.rs index d4fa8e38..70188ab8 100644 --- a/src/arithmetic.rs +++ b/src/arithmetic.rs @@ -5,6 +5,7 @@ use crate::fixtures::*; use crate::forms::*; use crate::instructions::*; use crate::iterators::*; +use crate::targets::QueryInstruction; use crate::types::*; use crate::parser::ast::*; @@ -121,15 +122,12 @@ impl<'a> Iterator for ArithInstructionIterator<'a> { 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( @@ -315,7 +313,7 @@ impl<'a, TermMarker: Allocator> ArithmeticEvaluator<'a, TermMarker> { } } - pub(crate) fn eval( + pub(crate) fn compile_is( &mut self, src: &'a Term, term_loc: GenContext, @@ -328,33 +326,35 @@ impl<'a, TermMarker: Allocator> ArithmeticEvaluator<'a, TermMarker> { 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::( - name.clone(), - lvl, - cell, - term_loc, - &mut code, - ); - } - } + let r = if lvl == Level::Shallow && term_loc.is_last() { + self.marker.mark_var::( + 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::( + 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() }; diff --git a/src/codegen.rs b/src/codegen.rs index c0d4bd02..0b89e9e8 100644 --- a/src/codegen.rs +++ b/src/codegen.rs @@ -397,6 +397,7 @@ impl<'b, TermMarker: Allocator> CodeGenerator<'b, TermMarker> { perm_v!(1), false, ); + continue; } } @@ -430,7 +431,6 @@ impl<'b, TermMarker: Allocator> CodeGenerator<'b, TermMarker> { }; self.update_var_count(chunked_term.post_order_iter()); - vs.mark_vars_in_chunk(chunked_term.post_order_iter(), lt_arity, term_loc); } } @@ -663,7 +663,7 @@ impl<'b, TermMarker: Allocator> CodeGenerator<'b, TermMarker> { term_loc: GenContext, ) -> Result { 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( @@ -1080,7 +1080,6 @@ impl<'b, TermMarker: Allocator> CodeGenerator<'b, TermMarker> { // 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()); } diff --git a/src/forms.rs b/src/forms.rs index e183a522..bdcb86dc 100644 --- a/src/forms.rs +++ b/src/forms.rs @@ -58,7 +58,7 @@ impl AppendOrPrepend { } } -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Level { Deep, Root, diff --git a/src/iterators.rs b/src/iterators.rs index 4f255584..422ad667 100644 --- a/src/iterators.rs +++ b/src/iterators.rs @@ -407,16 +407,7 @@ impl<'a> ChunkedIterator<'a> { } })) } - /* - 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) -> Self { let inner_iter = Box::new(once(ChunkedTerm::BodyTerm(p1))); let iter = inner_iter.chain(clauses.iter().map(|t| ChunkedTerm::BodyTerm(t))); diff --git a/src/parser/ast.rs b/src/parser/ast.rs index c2890459..6f73fd55 100644 --- a/src/parser/ast.rs +++ b/src/parser/ast.rs @@ -234,12 +234,22 @@ pub enum GenContext { } impl GenContext { + #[inline] pub fn chunk_num(self) -> usize { match self { GenContext::Head => 0, GenContext::Mid(cn) | GenContext::Last(cn) => cn, } } + + #[inline] + pub fn is_last(self) -> bool { + if let GenContext::Last(_) = self { + true + } else { + false + } + } } #[bitfield] -- 2.54.0