]> Repositorios git - scryer-prolog.git/commitdiff
add register marking for non-callable/inlined predicates.
authorMark Thom <[email protected]>
Mon, 13 Nov 2017 06:43:42 +0000 (23:43 -0700)
committerMark Thom <[email protected]>
Mon, 13 Nov 2017 06:43:42 +0000 (23:43 -0700)
src/prolog/allocator.rs
src/prolog/arithmetic.rs
src/prolog/codegen.rs
src/prolog/debray_allocator.rs
src/prolog/naive_allocator.rs [deleted file]

index c3a3e79bcac882d3a69c0954f5b71baf1a405e9d..cd9f523b11857978efc625a73244fc4a41d377cd 100644 (file)
@@ -17,8 +17,8 @@ pub trait Allocator<'a>
     
     fn reset(&mut self);
     fn reset_contents(&mut self) {}
-
-    fn advance(&mut self, GenContext, usize);
+    fn reset_arg(&mut self, usize);
+    
     fn advance_arg(&mut self);
 
     fn bindings(&self) -> &AllocVarDict<'a>;
index 52a2a89a87d90c7c2160cb0f3e54ee3359741774..513412308650d29460758a8f28d11914947ab2a5 100644 (file)
@@ -84,8 +84,8 @@ impl<'a> ArithmeticEvaluator<'a> {
         ArithmeticEvaluator { bindings, interm: Vec::new(), interm_c: 1 }
     }
 
-    fn get_un_instr(name: &Atom, a1: ArithmeticTerm, t: usize)
-                    -> Result<ArithmeticInstruction, ArithmeticError>
+    fn get_unary_instr(name: &Atom, a1: ArithmeticTerm, t: usize)
+                       -> Result<ArithmeticInstruction, ArithmeticError>
     {
         match name.as_str() {
             "-" => Ok(ArithmeticInstruction::Neg(a1, t)),
@@ -93,8 +93,8 @@ impl<'a> ArithmeticEvaluator<'a> {
         }
     }
 
-    fn gen_bin_instr(name: &Atom, a1: ArithmeticTerm, a2: ArithmeticTerm, t: usize)
-                     -> Result<ArithmeticInstruction, ArithmeticError>
+    fn gen_binary_instr(name: &Atom, a1: ArithmeticTerm, a2: ArithmeticTerm, t: usize)
+                        -> Result<ArithmeticInstruction, ArithmeticError>
     {
         match name.as_str() {
             "+"   => Ok(ArithmeticInstruction::Add(a1, a2, t)),
@@ -129,7 +129,7 @@ impl<'a> ArithmeticEvaluator<'a> {
                     a1.interm_or(0)
                 };
 
-                Self::get_un_instr(name, a1, ninterm)
+                Self::get_unary_instr(name, a1, ninterm)
             },
             2 => {
                 let a2 = self.interm.pop().unwrap();
@@ -153,7 +153,7 @@ impl<'a> ArithmeticEvaluator<'a> {
                     min_interm
                 };
 
-                Self::gen_bin_instr(name, a1, a2, ninterm)
+                Self::gen_binary_instr(name, a1, a2, ninterm)
             },
             _ => Err(ArithmeticError::InvalidOp)
         }
@@ -221,7 +221,7 @@ impl<'a> ArithmeticEvaluator<'a> {
                 _ => {}
             };
         }
-        
+
         Ok(code)
     }
 }
index 0fb1a53e9867e99065b561ed4e26f8c872a2f827..bafcea3ed5437d924b32ca4f4c19afd75aa7a263 100644 (file)
@@ -6,6 +6,7 @@ use prolog::indexing::*;
 use prolog::iterators::*;
 use prolog::targets::*;
 
+use std::cell::Cell;
 use std::collections::HashMap;
 use std::mem::swap;
 use std::vec::Vec;
@@ -79,6 +80,29 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
         *self.var_count.get(var).unwrap()
     }
 
+    fn mark_non_callable(&mut self,
+                         name: &'a Atom,
+                         arity: usize,
+                         term_loc: GenContext,
+                         vr: &'a Cell<VarReg>,
+                         code: &mut Code)
+                         -> RegType
+    {
+        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),
+            _ => {
+                let mut target = Vec::new();
+                                
+                self.marker.reset_arg(arity);
+                self.marker.mark_var(name, Level::Shallow, vr, term_loc, &mut target);
+                
+                code.push(Line::Query(target));
+                vr.get().norm()
+            }   
+        }
+    }
+    
     fn add_or_increment_void_instr<Target>(target: &mut Vec<Target>)
         where Target: CompilationTarget<'a>
     {
@@ -297,23 +321,15 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
                         code.append(&mut arith_code);
 
                         match terms[0].as_ref() {
-                            &Term::Var(ref vr, ref name) =>
-                                match self.marker.bindings().get(name) {
-                                    Some(&VarData::Temp(_, t, _)) if t != 0 =>
-                                        code.push(is_call!(temp_v!(t))),
-                                    Some(&VarData::Perm(p)) if p != 0 =>
-                                        code.push(is_call!(perm_v!(p))),
-                                    _ => {
-                                        let mut target = Vec::new();
-
-                                        // reset self.marker.arg_c to 1.
-                                        self.marker.advance(term_loc, term.arity());
-                                        self.marker.mark_var(name, Level::Shallow, vr, term_loc, &mut target);
-
-                                        code.push(Line::Query(target));
-                                        code.push(is_call!(vr.get().norm()));
-                                    }
-                                },
+                            &Term::Var(ref vr, ref name) => {
+                                let r = self.mark_non_callable(name,
+                                                               term.arity(),
+                                                               term_loc,
+                                                               vr,
+                                                               code);
+                                
+                                code.push(is_call!(r));
+                            },
                             &Term::Constant(_, Constant::Float(fl)) => {
                                 code.push(query![put_constant!(Level::Shallow,
                                                                Constant::Float(fl),
@@ -340,23 +356,15 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
                             &Term::Constant(_, _) => {
                                 code.push(succeed!());
                             },
-                            &Term::Var(ref vr, ref name) =>
-                                match self.marker.bindings().get(name) {
-                                    Some(&VarData::Temp(_, t, _)) if t != 0 =>
-                                        code.push(is_atomic!(RegType::Temp(t))),
-                                    Some(&VarData::Perm(p)) if p != 0 =>
-                                        code.push(is_atomic!(RegType::Perm(p))),
-                                    _ => {
-                                        let mut target = Vec::new();
-
-                                        // reset self.marker.arg_c to 1.
-                                        self.marker.advance(term_loc, term.arity());
-                                        self.marker.mark_var(name, Level::Shallow, vr, term_loc, &mut target);
-
-                                        code.push(Line::Query(target));
-                                        code.push(is_atomic!(vr.get().norm()));
-                                    }
-                                },
+                            &Term::Var(ref vr, ref name) => {
+                                let r = self.mark_non_callable(name,
+                                                               term.arity(),
+                                                               term_loc,
+                                                               vr,
+                                                               code);
+
+                                code.push(is_atomic!(r));
+                            }
                         },
                     &QueryTerm::IsVar(ref inner_term) =>
                         match inner_term[0].as_ref() {
@@ -366,26 +374,18 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
                             &Term::AnonVar => {
                                 code.push(succeed!());
                             },
-                            &Term::Var(ref vr, ref name) =>
-                                match self.marker.bindings().get(name) {
-                                    Some(&VarData::Temp(_, t, _)) if t != 0 =>
-                                        code.push(is_var!(RegType::Temp(t))),
-                                    Some(&VarData::Perm(p)) if p != 0 =>
-                                        code.push(is_var!(RegType::Perm(p))),
-                                    _ => {
-                                        let mut target = Vec::new();
-
-                                        // reset self.marker.arg_c to 1.
-                                        self.marker.advance(term_loc, term.arity());
-                                        self.marker.mark_var(name, Level::Shallow, vr, term_loc, &mut target);
-
-                                        code.push(Line::Query(target));
-                                        code.push(is_var!(vr.get().norm()));
-                                    }
-                                }
+                            &Term::Var(ref vr, ref name) => {
+                                let r = self.mark_non_callable(name,
+                                                               term.arity(),
+                                                               term_loc,
+                                                               vr,
+                                                               code);
+
+                                code.push(is_var!(r));
+                            }
                         },
                     _ if chunk_num == 0 => {
-                        self.marker.advance(GenContext::Head, term.arity());
+                        self.marker.reset_arg(term.arity());
 
                         let iter = term.post_order_iter();
                         code.push(Line::Query(self.compile_target(iter, term_loc, is_exposed)));
@@ -441,7 +441,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
         let &Rule { head: (ref p0, ref p1), ref clauses } = rule;
         let mut code = Vec::new();
 
-        self.marker.advance(GenContext::Head, p0.arity());
+        self.marker.reset_arg(p0.arity());
         self.compile_seq_prelude(&conjunct_info, &mut code);
 
         if let &QueryTerm::Term(ref term) = p0 {            
@@ -509,7 +509,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
         vs.populate_restricting_sets();
 
         self.marker.drain_var_data(vs);
-        self.marker.advance(GenContext::Head, term.arity());
+        self.marker.reset_arg(term.arity());
 
         let mut code = Vec::new();
 
@@ -532,7 +532,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
                           index: usize,
                           is_exposed: bool)
     {
-        self.marker.advance(term_loc, term.arity());
+        self.marker.reset_arg(term.arity());
 
         let iter = term.post_order_iter();
         let compiled_query = Line::Query(self.compile_target(iter, term_loc, is_exposed));
index 44e3800f4d3612a6940979c16c34e505fb85e360..a7f4a0f2c3105f3fcfa952a036e7bfd65480d4c7 100644 (file)
@@ -348,7 +348,7 @@ impl<'a> Allocator<'a> for DebrayAllocator<'a>
         self.bindings
     }
     
-    fn advance(&mut self, _: GenContext, arity: usize) {
+    fn reset_arg(&mut self, arity: usize) {
         self.arg_c   = 1;
         self.temp_lb = arity + 1;
     }
diff --git a/src/prolog/naive_allocator.rs b/src/prolog/naive_allocator.rs
deleted file mode 100644 (file)
index 4b1f13c..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-use prolog::allocator::*;
-use prolog::ast::*;
-use prolog::fixtures::*;
-use prolog::targets::*;
-
-use std::cell::Cell;
-use std::cmp::max;
-use std::collections::HashMap;
-
-pub struct NaiveAllocator<'a> {    
-    bindings: AllocVarDict<'a>,
-    arg_c:    usize,
-    temp_c:   usize,
-}
-    
-impl<'a> Allocator<'a> for NaiveAllocator<'a>
-{
-    fn new() -> Self {
-        NaiveAllocator {
-            arg_c:    1,
-            temp_c:   1,
-            bindings: HashMap::new(),
-        }
-    }
-    
-    fn mark_anon_var<Target>(&mut self, lvl: Level, target: &mut Vec<Target>)
-        where Target: CompilationTarget<'a>
-    {
-        let r = {
-            let temp = self.temp_c;
-            self.temp_c += 1;
-            RegType::Temp(temp)
-        };
-
-        match lvl {
-            Level::Deep => target.push(Target::subterm_to_variable(r)),
-            Level::Shallow => {
-                let k = self.arg_c;
-                self.arg_c += 1;
-
-                target.push(Target::argument_to_variable(r, k));
-            }
-        }
-    }
-
-    fn mark_non_var<Target>(&mut self,
-                            lvl: Level,
-                            _: GenContext,
-                            cell: &Cell<RegType>,
-                            _: &mut Vec<Target>)
-        where Target: CompilationTarget<'a>
-    {
-        let r = cell.get();
-
-        if r.reg_num() == 0 {
-            let r = match lvl {                
-                Level::Shallow => {
-                    let k = self.arg_c;
-                    self.arg_c += 1;
-                    
-                    RegType::Temp(k)
-                },
-                _ => {
-                    let temp = self.temp_c;
-                    self.temp_c += 1;
-                    
-                    RegType::Temp(temp)
-                }
-            };
-
-            cell.set(r);
-        }
-    }    
-
-    fn mark_var<Target>(&mut self,
-                        var: &'a Var,
-                        lvl: Level,
-                        cell: &'a Cell<VarReg>,
-                        _: GenContext,
-                        target: &mut Vec<Target>)
-        where Target: CompilationTarget<'a>
-    {
-        let (r, is_new_var) = match self.get(var) {
-            RegType::Temp(0) => {
-                let o = self.temp_c;
-                self.temp_c += 1;
-                
-                (RegType::Temp(o), true)
-            },
-            RegType::Perm(0) => {
-                let pr = cell.get().norm();
-                self.record_register(var, pr);
-                
-                (pr, true)
-            },
-            r => (r, false)
-        };
-        
-        match lvl {            
-            Level::Shallow => {
-                let k = self.arg_c;                
-                self.arg_c += 1;                               
-
-                cell.set(VarReg::ArgAndNorm(r, k));
-                
-                if is_new_var {
-                    target.push(Target::argument_to_variable(r, k));
-                } else {
-                    target.push(Target::argument_to_value(r, k));
-                }                
-            },
-            Level::Deep => {
-                cell.set(VarReg::Norm(r));
-
-                if is_new_var {
-                    target.push(Target::subterm_to_variable(r));
-                } else {
-                    target.push(Target::subterm_to_value(r));
-                }
-            }
-        };
-
-        if !r.is_perm() {
-            self.record_register(var, r);
-        }
-    }
-    
-    fn reset(&mut self) {
-        self.bindings.clear();
-    }
-    
-    fn advance(&mut self, term_loc: GenContext, arity: usize) {
-        if let GenContext::Head = term_loc {
-            self.arg_c  = 1;
-            self.temp_c = max(arity + 1, self.temp_c);
-        } else {
-            self.arg_c  = 1;
-            self.temp_c = arity + 1;
-        }
-    }
-
-    fn advance_arg(&mut self) {
-        self.arg_c += 1;
-    }
-
-    fn bindings(&self) -> &AllocVarDict<'a> {
-        &self.bindings
-    }
-    
-    fn bindings_mut(&mut self) -> &mut AllocVarDict<'a> {
-        &mut self.bindings
-    }
-    
-    fn take_bindings(self) -> AllocVarDict<'a> {
-        self.bindings
-    }
-}