]> Repositorios git - scryer-prolog.git/commitdiff
mark unsafe variables and substitute temporary variables in is/2 when appropriate...
authorMark Thom <[email protected]>
Sun, 17 Apr 2022 23:33:09 +0000 (17:33 -0600)
committerMark Thom <[email protected]>
Sun, 17 Apr 2022 23:33:09 +0000 (17:33 -0600)
src/arithmetic.rs
src/codegen.rs
src/forms.rs
src/iterators.rs
src/parser/ast.rs

index d4fa8e380daca392a48ba76cfc23a32178af9c64..70188ab8297ac2e31daed3f254796a0c7776ebc0 100644 (file)
@@ -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::<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()
                     };
index c0d4bd0263b40ac00e6b3476909a1c154a87ee2c..0b89e9e8b890760692c9cb6a4811ee00558e1341 100644 (file)
@@ -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<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(
@@ -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());
             }
 
index e183a522768582f013cc91f2a04840ecc4312e02..bdcb86dc75cb0e15459353082d082228725a5644 100644 (file)
@@ -58,7 +58,7 @@ impl AppendOrPrepend {
     }
 }
 
-#[derive(Debug, Clone, Copy)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 pub enum Level {
     Deep,
     Root,
index 4f255584c32ea423826ad3e80e1ebced1d1afc85..422ad667af345ff987f293b689e7f5869493d96b 100644 (file)
@@ -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<QueryTerm>) -> Self {
         let inner_iter = Box::new(once(ChunkedTerm::BodyTerm(p1)));
         let iter = inner_iter.chain(clauses.iter().map(|t| ChunkedTerm::BodyTerm(t)));
index c289045949c73ddb574e48561a568c25e7b39f5a..6f73fd55f96003393cce48db45b662f96f0c05b7 100644 (file)
@@ -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]