]> Repositorios git - scryer-prolog.git/commitdiff
clone in situ compiled terms
authorMark Thom <[email protected]>
Sun, 20 Jan 2019 00:05:29 +0000 (17:05 -0700)
committerMark Thom <[email protected]>
Sun, 20 Jan 2019 00:05:29 +0000 (17:05 -0700)
src/prolog/codegen.rs
src/prolog/compile.rs
src/prolog/debray_allocator.rs
src/prolog/fixtures.rs
src/prolog/instructions.rs
src/prolog/lib/builtins.pl
src/prolog/machine/machine_state.rs
src/prolog/machine/mod.rs
src/prolog/machine/term_expansion.rs
src/prolog/toplevel.rs

index 4846c728473164a2929110a7295d6dd802c6bc9b..66e94f1ee97c9ffa31feba51f50ca37b64684b75 100644 (file)
@@ -405,6 +405,46 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
         evaluator.eval(term)
     }
 
+    fn compile_is_call(&mut self, terms: &'a Vec<Box<Term>>, code: &mut Code,
+                       term_loc: GenContext, use_default_call_policy: bool)
+                       -> Result<(), ParserError>
+    {
+        let (mut acode, at) = self.call_arith_eval(terms[1].as_ref(), 1)?;
+        code.append(&mut acode);
+
+        Ok(match terms[0].as_ref() {
+            &Term::Var(ref vr, ref name) => {
+                let mut target = Vec::new();
+
+                self.marker.reset_arg(2);
+                self.marker.mark_var(name.clone(), Level::Shallow, vr,
+                                     term_loc, &mut target);
+
+                if !target.is_empty() {
+                    code.push(Line::Query(target));
+                }
+
+                if use_default_call_policy {
+                    code.push(is_call_by_default!(temp_v!(1), at.unwrap_or(interm!(1))))
+                } else {
+                    code.push(is_call!(temp_v!(1), at.unwrap_or(interm!(1))))
+                }
+            },
+            &Term::Constant(_, ref c @ Constant::Number(_)) => {
+                code.push(query![put_constant!(Level::Shallow,
+                                               c.clone(),
+                                               temp_v!(1))]);
+
+                if use_default_call_policy {
+                    code.push(is_call_by_default!(temp_v!(1), at.unwrap_or(interm!(1))))
+                } else {
+                    code.push(is_call!(temp_v!(1), at.unwrap_or(interm!(1))))
+                }
+            },
+            _ => code.push(fail!())
+        })
+    }
+
     fn compile_seq(&mut self, iter: ChunkedIterator<'a>, conjunct_info: &ConjunctInfo<'a>,
                    code: &mut Code, is_exposed: bool)
                    -> Result<(), ParserError>
@@ -441,47 +481,9 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
                         }),
                     &QueryTerm::Clause(_, ClauseType::BuiltIn(BuiltInClauseType::Is(..)),
                                        ref terms, use_default_call_policy)
-                        =>
-                    {
-                        let (mut acode, at) = self.call_arith_eval(terms[1].as_ref(), 1)?;
-                        code.append(&mut acode);
-
-                        match terms[0].as_ref() {
-                            &Term::Var(ref vr, ref name) => {
-                                let mut target = Vec::new();
-
-                                self.marker.reset_arg(2);
-                                self.marker.mark_var(name.clone(), Level::Shallow, vr,
-                                                     term_loc, &mut target);
-
-                                if !target.is_empty() {
-                                    code.push(Line::Query(target));
-                                }
-
-                                if use_default_call_policy {
-                                    code.push(is_call_by_default!(temp_v!(1), at.unwrap_or(interm!(1))));
-                                } else {
-                                    code.push(is_call!(temp_v!(1), at.unwrap_or(interm!(1))));
-                                }
-                            },
-                            &Term::Constant(_, ref c @ Constant::Number(_)) => {
-                                code.push(query![put_constant!(Level::Shallow,
-                                                               c.clone(),
-                                                               temp_v!(1))]);
-
-                                if use_default_call_policy {
-                                    code.push(is_call_by_default!(temp_v!(1), at.unwrap_or(interm!(1))));
-                                } else {
-                                    code.push(is_call!(temp_v!(1), at.unwrap_or(interm!(1))));
-                                }
-                            },
-                            _ => {
-                                code.push(fail!());
-                            }
-                        }
-                    },                    
-                    &QueryTerm::Clause(_, ClauseType::Inlined(ref ct), ref terms, _) =>
-                        try!(self.compile_inlined(ct, terms, term_loc, code)),
+                      => self.compile_is_call(terms, code, term_loc, use_default_call_policy)?,
+                    &QueryTerm::Clause(_, ClauseType::Inlined(ref ct), ref terms, _)
+                      => self.compile_inlined(ct, terms, term_loc, code)?,
                     _ => {
                         let num_perm_vars = if chunk_num == 0 {
                             conjunct_info.perm_vars()
@@ -491,7 +493,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
 
                         self.compile_query_line(term, term_loc, code, num_perm_vars, is_exposed);
                     },
-                };
+                }
             }
 
             self.marker.reset_contents();
@@ -518,7 +520,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
         // add a proceed to bookend any trailing cuts.
         match toc {
             &QueryTerm::BlockedCut | &QueryTerm::UnblockedCut(..) => code.push(proceed!()),
-            &QueryTerm::Clause(_, ClauseType::Inlined(..), ..) => code.push(proceed!()),            
+            &QueryTerm::Clause(_, ClauseType::Inlined(..), ..) => code.push(proceed!()),
             _ => {}
         };
 
index 89976ffea368eb82f17382761f3b195e17bcc165..6cd23f92601ef0c50f615301ffad3e6a0ed7d72b 100644 (file)
@@ -250,15 +250,15 @@ impl ListingCompiler {
                 let arity = cl.arity();
                 cl.name().map(|name| (name, arity))
             }).ok_or(SessionError::NamelessEntry)?;
-
+            
             let non_counted_bt = self.non_counted_bt_preds.contains(&(name.clone(), arity));
 
-            let p = code.len() + wam.code_size();
+            let p = code.len() + wam.code_size();                                    
             let mut decl_code = compile_relation(&TopLevel::Predicate(decl), non_counted_bt,
                                                  wam.machine_flags())?;
 
             compile_appendix(&mut decl_code, &queue, non_counted_bt, wam.machine_flags())?;
-
+            
             let idx = code_dir.entry((name, arity)).or_insert(CodeIndex::default());
             set_code_index!(idx, IndexPtr::Index(p), self.get_module_name());
 
@@ -489,7 +489,6 @@ fn setup_indices(wam: &mut Machine, indices: &mut IndexStore) -> Result<(), Sess
 
 pub fn compile_user_module<R: Read>(wam: &mut Machine, src: R) -> EvalSession {
     let mut indices = default_index_store!(wam.indices.atom_tbl.clone());
-    try_eval_session!(setup_indices(wam, &mut indices));
-    
+    try_eval_session!(setup_indices(wam, &mut indices));    
     compile_listing(wam, src, indices)
 }
index e94b8fc66080a321bf02af81b2192f18cbdd6bdc..9efb17e68632b90ab5f92214781dbb66a5301b19 100644 (file)
@@ -231,15 +231,15 @@ impl<'a> Allocator<'a> for DebrayAllocator
         where Target: CompilationTarget<'a>
     {
         let r = cell.get();
-        
+
         let r = match lvl {
             Level::Shallow => {
                 let k = self.arg_c;
-                
+
                 if let GenContext::Last(chunk_num) = term_loc {
                     self.evacuate_arg(chunk_num, target);
                 }
-                
+
                 self.arg_c += 1;
                 RegType::Temp(k)
             },
@@ -247,7 +247,7 @@ impl<'a> Allocator<'a> for DebrayAllocator
             _ => r
         };
 
-        cell.set(r);        
+        cell.set(r);
     }
 
     fn mark_var<Target>(&mut self, var: Rc<Var>, lvl: Level, cell: &'a Cell<VarReg>,
@@ -258,15 +258,14 @@ impl<'a> Allocator<'a> for DebrayAllocator
             RegType::Temp(0) => {
                 // here, r is temporary *and* unassigned.
                 let o = self.alloc_reg_to_var(&var, lvl, term_loc, target);
-
                 cell.set(VarReg::Norm(RegType::Temp(o)));
-
+                
                 (RegType::Temp(o), true)
             },
             RegType::Perm(0) => {
                 let pr = cell.get().norm();
                 self.record_register(var.clone(), pr);
-
+                
                 (pr, true)
             },
             r => (r, false)
index ffdf8da5726738bae395c3ad3f4eea2437f896f9..1cbcd713d2be14c241341cd71c262dc1d61a0831 100644 (file)
@@ -109,8 +109,8 @@ impl<'a> VariableFixtures<'a>
         var_count
     }
 
-    pub fn mark_vars_in_chunk<Iter>(&mut self, iter: Iter, lt_arity: usize, term_loc: GenContext)
-        where Iter: Iterator<Item=TermRef<'a>>
+    pub fn mark_vars_in_chunk<I>(&mut self, iter: I, lt_arity: usize, term_loc: GenContext)
+        where I: Iterator<Item=TermRef<'a>>
     {
         let chunk_num = term_loc.chunk_num();
         let mut arg_c = 1;
index 9a84037c68e60a1b2502a1db236632d062a3d9c3..bd5e2f2cf09d062f582c00a2d4ee3ac97be97a7b 100644 (file)
@@ -140,7 +140,7 @@ impl QueryTerm {
         match self {
             &mut QueryTerm::Clause(_, _, _, ref mut use_default_cp) => *use_default_cp = true,
             _ => {}
-        };
+        }
     }
 
     pub fn arity(&self) -> usize {
@@ -1140,7 +1140,7 @@ impl Module {
         {
             let ge = code_repo.term_dir.entry((clause_name!("goal_expansion"), 2))
                 .or_insert((Predicate::new(), VecDeque::from(vec![])));
-            
+
             (ge.0).0.extend((self.goal_expansions.0).0.iter().cloned());
             ge.1.extend(self.goal_expansions.1.iter().cloned());
         }
index 4f35ac657bcf03f985903bfd8e4c38a6f4f56157..1260f642a4a54889e43b6914071f2fcd4a5fe119 100644 (file)
@@ -1,12 +1,12 @@
 :- op(400, yfx, /).
 
-:- module(builtins, [(=)/2, (+)/2, (**)/2, (*)/2, (-)/2, (/)/2,
-       (/\)/2, (\/)/2, (is)/2, (xor)/2, (div)/2, (//)/2, (rdiv)/2,
-       (<<)/2, (>>)/2, (mod)/2, (rem)/2, (>)/2, (<)/2, (=\=)/2,
-       (=:=)/2, (-)/1, (>=)/2, (=<)/2, (,)/2, (->)/2, (;)/2, (=..)/2,
-       (==)/2, (\==)/2, (@=<)/2, (@>=)/2, (@<)/2, (@>)/2, (=@=)/2,
-       (\=@=)/2, (:)/2, call_with_inference_limit/3, catch/3,
-       current_prolog_flag/2, expand_goal/2, expand_term/2,
+:- module(builtins, [(=)/2, (+)/1, (+)/2, (**)/2, (*)/2, (-)/1, (-)/2,
+       (/)/2, (/\)/2, (\/)/2, (is)/2, (xor)/2, (div)/2, (//)/2,
+       (rdiv)/2, (<<)/2, (>>)/2, (mod)/2, (rem)/2, (>)/2, (<)/2,
+       (=\=)/2, (=:=)/2, (-)/1, (>=)/2, (=<)/2, (,)/2, (->)/2, (;)/2,
+       (=..)/2, (==)/2, (\==)/2, (@=<)/2, (@>=)/2, (@<)/2, (@>)/2,
+       (=@=)/2, (\=@=)/2, (:)/2, call_with_inference_limit/3,
+       catch/3, current_prolog_flag/2, expand_goal/2, expand_term/2,
        set_prolog_flag/2, setup_call_cleanup/3, term_variables/2,
        throw/1, true/0, false/0, write/1, write_canonical/1,
        writeq/1, write_term/2]).
@@ -34,7 +34,7 @@ expand_op_list([Op | OtherOps], Pred, Spec, [(:- op(Pred, Spec, Op)) | OtherResu
 :- op(500, yfx, [/\, \/, xor]).
 :- op(400, yfx, [div, //, rdiv]).
 :- op(400, yfx, [<<, >>, mod, rem]).
-:- op(200, fy, -).
+:- op(200, fy, [+, -]).
 
 % arithmetic comparison operators.
 :- op(700, xfx, [>, <, =\=, =:=, >=, =<]).
index e7366ac0a838d91f73f3571341558201a9435535..376d588bd7ca0eae39ae0d6045ed6c199fba9465 100644 (file)
@@ -268,8 +268,7 @@ impl MachineState {
     }
 }
 
-fn try_in_situ_lookup(name: ClauseName, arity: usize, indices: &IndexStore)
-                      -> Option<usize>
+fn try_in_situ_lookup(name: ClauseName, arity: usize, indices: &IndexStore) -> Option<usize>
 {
     match indices.in_situ_code_dir.get(&(name.clone(), arity)) {
         Some(p) => Some(*p),
index 3da31e29af4aa29eebefa119549e7583b67a7617..cc3e0b061b39bf6c250bafd8256d30801ea27a02 100644 (file)
@@ -149,14 +149,15 @@ impl CodeRepo {
             cl.name().map(|name| (name, arity))
         }).ok_or(SessionError::NamelessEntry)?;
 
-        let p   = self.in_situ_code.len();
+        let p = self.in_situ_code.len();
         in_situ_code_dir.insert((name, arity), p);
 
         let mut cg = CodeGenerator::<DebrayAllocator>::new(true, flags);
-        let mut decl_code = cg.compile_predicate(&decl.0)?;
-
+        // clone the decl to avoid the need to wipe its register cells later.
+        let mut decl_code = cg.compile_predicate(&decl.0.clone())?;        
+        
         compile_appendix(&mut decl_code, queue, true, flags)?;
-
+                
         self.in_situ_code.extend(decl_code.into_iter());
         Ok(())
     }
index 19d1576035101c049bcc0f1ee9e2ce24e7e661a9..e6fe42444a650b577d324cd9ec1d52ec318425fa 100644 (file)
@@ -104,7 +104,7 @@ impl ExpansionAdditionResult {
 impl<'a, R: Read> Drop for TermStream<'a, R> {
     fn drop(&mut self) {
         self.indices.in_situ_code_dir.clear();
-        self.code_repo.in_situ_code.clear();        
+        self.code_repo.in_situ_code.clear();
         discard_result!(self.rollback_expansion_code());
     }
 }
@@ -322,7 +322,6 @@ impl MachineState {
             };
 
             output.push_char('.');
-
             self.reset();
             Some(output.result())
         }
index eed2c01ae17a8cd14a880bf8cc024ff94e40c75a..ee1fe25f2f2ff70be29ecff5055c325e7d3b225f 100644 (file)
@@ -487,12 +487,12 @@ impl RelationWorker {
     fn to_query_term(&mut self, indices: &mut CompositeIndices, term: Term) -> Result<QueryTerm, ParserError>
     {
         match term {
-            Term::Constant(r, Constant::Atom(name, fixity)) =>
+            Term::Constant(_, Constant::Atom(name, fixity)) =>
                 if name.as_str() == "!" || name.as_str() == "blocked_!" {
                     Ok(QueryTerm::BlockedCut)
                 } else {
                     let ct = indices.get_clause_type(name, 0, fixity);
-                    Ok(QueryTerm::Clause(r, ct, vec![], false))
+                    Ok(QueryTerm::Clause(Cell::default(), ct, vec![], false))
                 },
             Term::Var(_, ref v) if v.as_str() == "!" =>
                 Ok(QueryTerm::UnblockedCut(Cell::default())),