]> Repositorios git - scryer-prolog.git/commitdiff
transition to debray allocation
authorMark Thom <[email protected]>
Sun, 30 Apr 2017 19:53:15 +0000 (13:53 -0600)
committerMark Thom <[email protected]>
Sun, 30 Apr 2017 19:53:15 +0000 (13:53 -0600)
Cargo.lock
Cargo.toml
README.md
src/prolog/ast.rs
src/prolog/codegen.rs
src/prolog/debray_allocator.rs [new file with mode: 0644]
src/prolog/fixtures.rs
src/prolog/io.rs
src/prolog/machine.rs
src/prolog/mod.rs
src/prolog/targets.rs

index 3d66e8458e85deb86cf282d882dfa02b27d00fcb..ea28ff07c69de22cb9888443f87fa84ad72ed50d 100644 (file)
@@ -1,6 +1,6 @@
 [root]
 name = "rusty-wam"
-version = "0.5.7"
+version = "0.6.0"
 dependencies = [
  "lalrpop 0.12.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "lalrpop-util 0.12.5 (registry+https://github.com/rust-lang/crates.io-index)",
index a750dbc3dc8082c36e2e87fdd3c3a6ff4e41e6e2..ae6ad2cf859284b5e762950e3b4494002cd5456d 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "rusty-wam"
-version = "0.5.7"
+version = "0.6.0"
 authors = ["Mark Thom"]
 
 build = "build.rs"
index 834bfb01131792e10026e8c7456e539e28d36897..5364911ac432d2610656e4a0f770bf246da25e3c 100644 (file)
--- a/README.md
+++ b/README.md
@@ -10,14 +10,9 @@ pure Prolog.
 
 Prolog is implemented as a simple REPL. It is without without meta- or
 extra-logical operators, or side effects of any kind, with the lone
-exception of cut. In terms of the tutorial pacing, the work has
-progressed to the end of section 5.11, skipping past 5.4. Atoms and
-lists are the only two data types currently supported.
-
-While proper environment trimming code is emitted by the code
-generator, it has no effect on the bytecode WAM, which lacks
-fine-grained control over the alignment and allocation of stack
-frames.
+exception of cut. In terms of the tutorial pacing, the work covers in
+some form all of the WAM book, including lists, cuts, Debray
+allocation, and indexing.
 
 ## Tutorial
 To enter a multi-clause predicate, the brackets ":{" and "}:" are used
index ee81b3f0730a3a1f9bd0f4d80938d0790ba66052..e8b17a417890b89bfd0d1e18bf74b5f7f23f5026 100644 (file)
@@ -9,7 +9,7 @@ pub type Atom = String;
 
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
 pub enum GenContext {
-    Head, Mid(usize), Last(usize) // Mid/Last: chunk_num
+    Head, Mid(usize), Last(usize) // Mid & Last: chunk_num
 }
 
 pub enum PredicateClause {
@@ -70,7 +70,7 @@ impl RegType {
             RegType::Perm(reg_num) | RegType::Temp(reg_num) => reg_num
         }
     }
-
+    
     pub fn is_perm(self) -> bool {
         match self {
             RegType::Perm(_) => true,
@@ -91,7 +91,7 @@ impl VarReg {
             VarReg::ArgAndNorm(reg, _) | VarReg::Norm(reg) => reg
         }
     }
-
+    
     pub fn is_temp(self) -> bool {
         !self.norm().is_perm()
     }
@@ -242,6 +242,7 @@ pub enum FactInstruction {
 }
 
 pub enum QueryInstruction {
+    GetVariable(RegType, usize),
     PutConstant(Level, Constant, RegType),
     PutList(Level, RegType),
     PutStructure(Level, Atom, usize, RegType),
@@ -433,13 +434,6 @@ impl Term {
         }
     }
 
-    pub fn subterms(&self) -> usize {
-        match self {
-            &Term::Clause(_, _, ref terms) => terms.len(),
-            _ => 1
-        }
-    }
-
     pub fn name(&self) -> Option<&Atom> {
         match self {
             &Term::Constant(_, Constant::Atom(ref atom))
index aaf95b717938b7bffd5a0144b40a8fa809be1653..bfef6a2e4e307f1e891525bfd675236bc6aa0aba 100644 (file)
@@ -1,8 +1,8 @@
 use prolog::ast::*;
+use prolog::debray_allocator::*;
 use prolog::fixtures::*;
 use prolog::indexing::*;
 use prolog::iterators::*;
-use prolog::naive_allocator::*;
 use prolog::targets::*;
 
 use std::cell::Cell;
@@ -69,30 +69,39 @@ impl<'a> CodeGenerator<'a> {
     fn to_structure<Target>(&mut self,
                             lvl: Level,
                             cell: &'a Cell<RegType>,
+                            term_loc: GenContext,
                             name: &'a Atom,
-                            arity: usize)
+                            arity: usize,
+                            target: &mut Vec<Target>)
                             -> Target
         where Target: CompilationTarget<'a>
     {
-        self.marker.mark_non_var(lvl, cell);
+        self.marker.mark_non_var(lvl, term_loc, cell, target);
         Target::to_structure(lvl, name.clone(), arity, cell.get())
     }
 
     fn to_constant<Target>(&mut self,
                            lvl: Level,
                            cell: &'a Cell<RegType>,
-                           constant: &'a Constant)
+                           term_loc: GenContext,                           
+                           constant: &'a Constant,
+                           target: &mut Vec<Target>)
                            -> Target
         where Target: CompilationTarget<'a>
     {
-        self.marker.mark_non_var(lvl, cell);
+        self.marker.mark_non_var(lvl, term_loc, cell, target);
         Target::to_constant(lvl, constant.clone(), cell.get())
     }
 
-    fn to_list<Target>(&mut self, lvl: Level, cell: &'a Cell<RegType>) -> Target
+    fn to_list<Target>(&mut self,
+                       lvl: Level,
+                       term_loc: GenContext,
+                       cell: &'a Cell<RegType>,
+                       target: &mut Vec<Target>)
+                       -> Target
         where Target: CompilationTarget<'a>
     {
-        self.marker.mark_non_var(lvl, cell);
+        self.marker.mark_non_var(lvl, term_loc, cell, target);
         Target::to_list(lvl, cell.get())
     }
 
@@ -102,56 +111,15 @@ impl<'a> CodeGenerator<'a> {
         Target::constant_subterm(constant.clone())
     }
 
-    fn anon_var_term<Target>(&mut self, lvl: Level, target: &mut Vec<Target>)
+    fn non_var_subterm<Target>(&mut self,
+                               lvl: Level,
+                               term_loc: GenContext,
+                               cell: &'a Cell<RegType>,
+                               target: &mut Vec<Target>)
+                               -> Target
         where Target: CompilationTarget<'a>
     {
-        let reg = self.marker.mark_anon_var(lvl);
-
-        let instr = match reg {
-            VarReg::ArgAndNorm(arg, norm) =>
-                Target::argument_to_variable(arg, norm),
-            VarReg::Norm(norm) =>
-                Target::subterm_to_variable(norm)
-        };
-
-        target.push(instr);
-    }
-
-    fn var_term<Target>(&mut self,
-                        lvl: Level,
-                        cell: &'a Cell<VarReg>,
-                        var: &'a Var,
-                        _: GenContext,
-                        target: &mut Vec<Target>)
-        where Target: CompilationTarget<'a>
-    {
-        if !self.marker.marked_var(var) {
-            let reg = self.marker.mark_new_var(lvl, var, cell.get().norm());
-            cell.set(reg);
-
-            match reg {
-                VarReg::ArgAndNorm(arg, norm) => // if arg.reg_num() != norm =>
-                    target.push(Target::argument_to_variable(arg, norm)),
-                VarReg::Norm(norm) =>
-                    target.push(Target::subterm_to_variable(norm)),
-            };
-        } else {
-            let reg = self.marker.mark_old_var(lvl, var);
-            cell.set(reg);
-
-            match reg {
-                VarReg::ArgAndNorm(arg, norm) => // if arg.reg_num() != norm =>
-                    target.push(Target::argument_to_value(arg, norm)),
-                VarReg::Norm(norm) =>
-                    target.push(Target::subterm_to_value(norm)),
-            };
-        }
-    }
-
-    fn non_var_subterm<Target>(&mut self, cell: &'a Cell<RegType>) -> Target
-        where Target: CompilationTarget<'a>
-    {
-        self.marker.mark_non_var(Level::Deep, cell);
+        self.marker.mark_non_var(lvl, term_loc, cell, target);
         Target::clause_arg_to_instr(cell.get())
     }
 
@@ -163,13 +131,15 @@ impl<'a> CodeGenerator<'a> {
     {
         match subterm {
             &Term::AnonVar =>
-                self.anon_var_term(Level::Deep, target),
-            &Term::Cons(ref cell, _, _) | &Term::Clause(ref cell, _, _) =>
-                target.push(self.non_var_subterm(cell)),
+                self.marker.mark_anon_var(Level::Deep, target),
+            &Term::Cons(ref cell, _, _) | &Term::Clause(ref cell, _, _) => {
+                let instr = self.non_var_subterm(Level::Deep, term_loc, cell, target);
+                target.push(instr);
+            },
             &Term::Constant(_, ref constant) =>
                 target.push(self.constant_subterm(constant)),
             &Term::Var(ref cell, ref var) =>
-                self.var_term(Level::Deep, cell, var, term_loc, target)
+                self.marker.mark_var(var, Level::Deep, cell, term_loc, target)
         };
     }
 
@@ -186,7 +156,14 @@ impl<'a> CodeGenerator<'a> {
         for term in iter {
             match term {
                 TermRef::Clause(lvl, cell, atom, terms) => {
-                    target.push(self.to_structure(lvl, cell, atom, terms.len()));
+                    let str_instr = self.to_structure(lvl,
+                                                      cell,
+                                                      term_loc,
+                                                      atom,
+                                                      terms.len(),
+                                                      &mut target);
+
+                    target.push(str_instr);
 
                     if !has_exposed_vars {
                         if self.all_singleton_vars(terms) {
@@ -200,21 +177,24 @@ impl<'a> CodeGenerator<'a> {
                     }
                 },
                 TermRef::Cons(lvl, cell, head, tail) => {
-                    target.push(self.to_list(lvl, cell));
+                    let list_instr = self.to_list(lvl, term_loc, cell, &mut target);
+                    target.push(list_instr);
 
                     self.subterm_to_instr(head, term_loc, &mut target);
                     self.subterm_to_instr(tail, term_loc, &mut target);
                 },
-                TermRef::Constant(lvl @ Level::Shallow, cell, constant) =>
-                    target.push(self.to_constant(lvl, cell, constant)),
+                TermRef::Constant(lvl @ Level::Shallow, cell, constant) => {
+                    let const_instr = self.to_constant(lvl, cell, term_loc, constant, &mut target);
+                    target.push(const_instr);
+                },
                 TermRef::AnonVar(lvl @ Level::Shallow) =>
                     if has_exposed_vars {
-                        self.anon_var_term(lvl, &mut target);
+                        self.marker.mark_anon_var(lvl, &mut target);
                     } else {
                         self.marker.advance_arg();
                     },
                 TermRef::Var(lvl @ Level::Shallow, ref cell, ref var) =>
-                    self.var_term(lvl, cell, var, term_loc, &mut target),
+                    self.marker.mark_var(var, lvl, cell, term_loc, &mut target),
                 _ => {}
             };
         }
@@ -332,7 +312,7 @@ impl<'a> CodeGenerator<'a> {
                 body.push(Line::Cut(CutInstruction::NeckCut(term)));
             },
             &TermOrCut::Term(ref p1) => {
-                self.marker.advance_at_head(p1);
+                self.marker.advance(p1);
 
                 if p1.is_clause() {
                     let term_loc = if p1.is_callable() {
diff --git a/src/prolog/debray_allocator.rs b/src/prolog/debray_allocator.rs
new file mode 100644 (file)
index 0000000..c5dbd4c
--- /dev/null
@@ -0,0 +1,355 @@
+use prolog::ast::*;
+use prolog::fixtures::*;
+use prolog::targets::*;
+
+use std::cell::Cell;
+use std::collections::{BTreeSet, HashMap};
+
+pub struct TermMarker<'a> {
+    pub bindings: HashMap<&'a Var, VarData>,
+    arg_c:    usize,
+    temp_lb:  usize,
+    contents: HashMap<usize, &'a Var>,
+    in_use:   BTreeSet<usize>,
+}
+
+impl<'a> TermMarker<'a> {
+    pub fn new() -> TermMarker<'a> {
+        TermMarker {
+            arg_c:   1,
+            temp_lb: 1,
+            bindings: HashMap::new(),
+            contents: HashMap::new(),
+            in_use: BTreeSet::new()
+        }
+    }
+
+    fn occurs_shallowly_in_head(&self, var: &'a Var, term_loc: GenContext, r: usize) -> bool
+    {
+        match (term_loc, self.bindings.get(var).unwrap()) {
+            (GenContext::Head, &VarData::Temp(_, _, ref tvd)) =>
+                tvd.use_set.contains(&(GenContext::Head, r)),
+            _ => false
+        }
+    }
+
+    pub fn drain_var_data(&mut self, vs: VariableFixtures<'a>) -> VariableFixtures<'a>
+    {
+        let mut perm_vs = VariableFixtures::new();
+
+        for (var, (var_status, cells)) in vs.into_iter() {
+            match var_status {
+                VarStatus::Temp(chunk_num, tvd) => {
+                    self.bindings.insert(var, VarData::Temp(chunk_num, 0, tvd));
+                },
+                VarStatus::Perm(_) => {
+                    self.bindings.insert(var, VarData::Perm(0));
+                    perm_vs.insert(var, (var_status, cells));
+                }
+            };
+        }
+
+        perm_vs
+    }
+
+    fn alloc_with_cr(&self, var: &'a Var) -> usize
+    {
+        match self.bindings.get(var) {
+            Some(&VarData::Temp(_, _, ref tvd)) => {
+                for &(_, reg) in tvd.use_set.iter() {
+                    if !self.in_use.contains(&reg) {
+                        return reg;
+                    }
+                }
+
+                let mut result = 0;
+
+                for reg in self.temp_lb .. {
+                    if !self.in_use.contains(&reg) {
+                        if !tvd.no_use_set.contains(&reg) {
+                            result = reg;
+                            break;
+                        }
+                    }
+                }
+
+                result
+            },
+            _ => 0
+        }
+    }
+
+    fn alloc_with_ca(&self, var: &'a Var) -> usize
+    {
+        match self.bindings.get(var) {
+            Some(&VarData::Temp(_, _, ref tvd)) => {
+                for &(_, reg) in tvd.use_set.iter() {
+                    if !self.in_use.contains(&reg) {
+                        return reg;
+                    }
+                }
+
+                let mut result = 0;
+
+                for reg in self.temp_lb .. {
+                    if !self.in_use.contains(&reg) {
+                        if !tvd.no_use_set.contains(&reg) {
+                            if !tvd.conflict_set.contains(&reg) {
+                                result = reg;
+                                break;
+                            }
+                        }
+                    }
+                }
+
+                result
+            },
+            _ => 0
+        }
+    }
+
+    fn alloc_in_last_goal_hint(&self, chunk_num: usize) -> Option<(&'a Var, usize)>
+    {
+        // we want to allocate a register to the k^{th} parameter, par_k.
+        // par_k may not be a temporary variable.
+        let k = self.arg_c;
+
+        match self.contents.get(&k) {
+            Some(t_var) => {
+                // suppose this branch fires. then t_var is a
+                // temp. var. belonging to the current chunk.
+                // consider its use set. T == par_k iff
+                // (GenContext::Last(_), k) is in t_var.use_set.
+
+                let tvd = self.bindings.get(t_var).unwrap();
+                if let &VarData::Temp(_, _, ref tvd) = tvd {
+                    if !tvd.use_set.contains(&(GenContext::Last(chunk_num), k)) {
+                        return Some((t_var, self.alloc_with_ca(t_var)));
+                    }
+                }
+
+                None
+            },
+            _ => None
+        }
+    }
+
+    fn evacuate_arg<Target>(&mut self, chunk_num: usize, target: &mut Vec<Target>)
+        where Target: CompilationTarget<'a>
+    {
+        match self.alloc_in_last_goal_hint(chunk_num) {
+            Some((var, r)) => {
+                let k = self.arg_c;
+
+                if r != k {
+                    let r = RegType::Temp(r);
+
+                    if r.reg_num() != k {
+                        target.push(Target::move_to_register(r, k));
+
+                        self.contents.remove(&k);
+                        self.contents.insert(r.reg_num(), var);
+
+                        self.record_register(var, r);
+                        self.in_use.insert(r.reg_num());
+                    }
+                }
+            },
+            _ => {}
+        };
+    }
+
+    fn alloc_reg_to_var<Target>(&mut self,
+                                var: &'a Var,
+                                lvl: Level,
+                                term_loc: GenContext,
+                                target: &mut Vec<Target>)
+                                -> usize
+        where Target: CompilationTarget<'a>
+    {
+        match term_loc {
+            GenContext::Head =>
+                if let Level::Shallow = lvl {
+                    self.alloc_with_cr(var)
+                } else {
+                    self.alloc_with_ca(var)
+                },
+            GenContext::Mid(_) =>
+                self.alloc_with_ca(var),
+            GenContext::Last(chunk_num) =>
+                if let Level::Shallow = lvl {
+                    self.evacuate_arg(chunk_num, target);
+                    self.alloc_with_cr(var)
+                } else {
+                    self.alloc_with_ca(var)
+                }
+        }
+    }
+
+    fn get(&self, var: &'a Var) -> RegType {
+        self.bindings.get(var).unwrap().as_reg_type()
+    }
+
+    fn in_place(&self, var: &'a Var, term_loc: GenContext, r: RegType, k: usize) -> bool
+    {
+        match term_loc {
+            GenContext::Head if !r.is_perm() => r.reg_num() == k,
+            _ => match self.bindings.get(var).unwrap() {
+                     &VarData::Temp(_, o, _) if r.reg_num() == k => o == k,
+                     _ => false
+                 }
+        }
+    }
+
+    // delete after anon_vars are handled by means of *_void stuff.
+    pub fn mark_anon_var<Target>(&mut self, lvl: Level, target: &mut Vec<Target>)
+        where Target: CompilationTarget<'a>
+    {
+        let r = RegType::Temp(self.alloc_reg_to_non_var());
+
+        match lvl {
+            Level::Shallow => {
+                let k = self.arg_c;
+                self.arg_c += 1;
+
+                target.push(Target::argument_to_variable(r, k));
+            },
+            Level::Deep =>
+                target.push(Target::subterm_to_variable(r))
+        };
+    }
+
+    fn alloc_reg_to_non_var(&mut self) -> usize
+    {
+        let mut final_index = 0;
+
+        for index in self.temp_lb .. {
+            if !self.in_use.contains(&index) {
+                final_index = index;
+                break;
+            }
+        }
+
+        self.temp_lb = final_index + 1;
+
+        final_index
+    }
+
+    pub fn mark_non_var<Target>(&mut self,
+                                lvl: Level,
+                                term_loc: GenContext,
+                                cell: &Cell<RegType>,
+                                target: &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;
+
+                    if let GenContext::Last(chunk_num) = term_loc {
+                        self.evacuate_arg(chunk_num, target);
+                    }
+
+                    self.arg_c += 1;
+                    RegType::Temp(k)
+                },
+                _ => RegType::Temp(self.alloc_reg_to_non_var())
+            };
+
+            cell.set(r);
+        }
+    }
+
+    pub fn mark_var<Target>(&mut self,
+                            var: &'a Var,
+                            lvl: Level,
+                            cell: &'a Cell<VarReg>,
+                            term_loc: GenContext,
+                            target: &mut Vec<Target>)
+        where Target: CompilationTarget<'a>
+    {
+        let (r, is_new_var) = match self.get(var) {
+            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, 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 !self.in_place(var, term_loc, 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 if is_new_var =>
+                if self.occurs_shallowly_in_head(var, term_loc, r.reg_num()) {
+                    target.push(Target::subterm_to_value(r));
+                } else {
+                    target.push(Target::subterm_to_variable(r));
+                },
+            Level::Deep =>
+                target.push(Target::subterm_to_value(r))
+        };
+
+        if !r.is_perm() {
+            let o = r.reg_num();
+
+            self.contents.insert(o, var);
+            self.record_register(var, r);
+            self.in_use.insert(o);
+        }
+    }
+
+    pub fn contains_var(&self, var: &'a Var) -> bool {
+        self.bindings.contains_key(var)
+    }
+
+    fn record_register(&mut self, var: &'a Var, r: RegType) {
+        match self.bindings.get_mut(var).unwrap() {
+            &mut VarData::Temp(_, ref mut s, _) => *s = r.reg_num(),
+            &mut VarData::Perm(ref mut s) => *s = r.reg_num()
+        }
+    }
+
+    pub fn advance_arg(&mut self) {
+        self.arg_c += 1;
+    }
+
+    pub fn advance(&mut self, term: &'a Term) {
+        self.arg_c = 1;
+        self.temp_lb = term.arity() + 1;
+    }
+
+    pub fn reset(&mut self) {
+        self.bindings.clear();
+        self.contents.clear();
+        self.in_use.clear();
+    }
+
+    pub fn reset_contents(&mut self) {
+        self.contents.clear();
+        self.in_use.clear();
+    }
+}
index e5637683861e5d1d18465c11054afc893f76d6e9..beebd27b1c3733df883fda867f20075f0d37262c 100644 (file)
@@ -10,14 +10,9 @@ pub type OccurrenceSet = BTreeSet<(GenContext, usize)>;
 
 pub struct TempVarData {
     last_term_arity: usize,
-    use_set: OccurrenceSet,
-    no_use_set: BTreeSet<usize>,
-    conflict_set: BTreeSet<usize>
-}
-
-// labeled with chunk_num and temp offset (unassigned if 0).
-pub enum VarData {
-    Perm(usize), Temp(usize, usize, TempVarData)
+    pub use_set: OccurrenceSet,
+    pub no_use_set: BTreeSet<usize>,
+    pub conflict_set: BTreeSet<usize>
 }
 
 // labeled with chunk numbers.
@@ -25,6 +20,12 @@ pub enum VarStatus {
     Perm(usize), Temp(usize, TempVarData) // Perm(chunk_num) | Temp(chunk_num, _)
 }
 
+// Perm: 0 initially, a stack register once processed.
+// Temp: labeled with chunk_num and temp offset (unassigned if 0), arg (0 if unassigned).
+pub enum VarData {
+    Perm(usize), Temp(usize, usize, TempVarData)
+}
+
 impl VarData {
     pub fn as_reg_type(&self) -> RegType {
         match self {
index 5c0727dbc9da9d6aca0c1e6620942971c5f7650a..9a3c82079a281be4df3d74309881d3e700ca30f3 100644 (file)
@@ -57,6 +57,8 @@ impl fmt::Display for FactInstruction {
 impl fmt::Display for QueryInstruction {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self {
+            &QueryInstruction::GetVariable(ref x, ref a) =>
+                write!(f, "get_variable {}, A{}", x, a),
             &QueryInstruction::PutConstant(Level::Shallow, ref constant, ref r) =>
                 write!(f, "put_constant {}, A{}", constant, r.reg_num()),
             &QueryInstruction::PutConstant(Level::Deep, ref constant, ref r) =>
index 8509083b7536c484077fad58d04155b0e087b227..3abb42f9626c9cc6c9cff069b808ecfa59604f1f 100644 (file)
@@ -111,7 +111,7 @@ impl Machine {
         self.code_dir.insert((name, arity), p);
     }
 
-    fn execute_instr<'b>(&mut self, instr_src: LineOrCodeOffset<'b>) -> bool
+    fn execute_instr<'a>(&mut self, instr_src: LineOrCodeOffset<'a>) -> bool
     {
         let mut instr = match instr_src {
             LineOrCodeOffset::Instruction(instr) => instr,
@@ -251,9 +251,10 @@ impl Machine {
         }
 
         if succeeded {
-            for (var, var_status) in cg.vars() {
-                let r = var_status.as_reg_type().reg_num();
-                let addr = self.ms.registers[r].clone();                
+            for (var, var_data) in cg.vars() {
+                let r = var_data.as_reg_type();
+                
+                let addr = self.ms[r].clone();
                 heap_locs.insert((*var).clone(), addr);
             }
 
@@ -536,7 +537,6 @@ impl MachineState {
                     _ => self.fail = true
                 };
             },
-
             &FactInstruction::GetList(_, reg) => {
                 let addr = self.deref(self[reg].clone());
 
@@ -782,6 +782,8 @@ impl MachineState {
 
     fn execute_query_instr(&mut self, instr: &QueryInstruction) {
         match instr {
+            &QueryInstruction::GetVariable(norm, arg) =>
+                self[norm] = self.registers[arg].clone(),
             &QueryInstruction::PutConstant(_, ref constant, reg) =>
                 self[reg] = Addr::Con(constant.clone()),
             &QueryInstruction::PutList(_, reg) =>
@@ -813,6 +815,7 @@ impl MachineState {
                 match norm {
                     RegType::Perm(n) => {
                         let e = self.e;
+                        
                         self[norm] = Addr::StackCell(e, n);
                         self.registers[arg] = self[norm].clone();
                     },
index 7cfe7cd9e75725d1b06e966ac61a1fa3144bec42..dd2d771eb31e9b70666209767309904a21343c3a 100644 (file)
@@ -1,12 +1,12 @@
 pub mod and_stack;
 pub mod ast;
 pub mod codegen;
+pub mod debray_allocator;
 pub mod fixtures;
 pub mod heapview;
 pub mod indexing;
 pub mod io;
 pub mod iterators;
-pub mod naive_allocator;
 pub mod prolog_parser;
 pub mod machine;
 pub mod or_stack;
index bef3610dfaa0514814a4460b7d223630ea0ae5f2..be041c87deb71a18726a390e3e0f4fd50e33fbfb 100644 (file)
@@ -16,6 +16,8 @@ pub trait CompilationTarget<'a> {
     fn argument_to_variable(RegType, usize) -> Self;
     fn argument_to_value(RegType, usize) -> Self;
 
+    fn move_to_register(RegType, usize) -> Self;
+
     fn subterm_to_variable(RegType) -> Self;
     fn subterm_to_value(RegType) -> Self;
 
@@ -53,6 +55,10 @@ impl<'a> CompilationTarget<'a> for FactInstruction {
         FactInstruction::GetVariable(arg, val)
     }
 
+    fn move_to_register(arg: RegType, val: usize) -> Self {
+        FactInstruction::GetVariable(arg, val)
+    }
+
     fn argument_to_value(arg: RegType, val: usize) -> Self {
         FactInstruction::GetValue(arg, val)
     }
@@ -100,6 +106,10 @@ impl<'a> CompilationTarget<'a> for QueryInstruction {
     fn argument_to_variable(arg: RegType, val: usize) -> Self {
         QueryInstruction::PutVariable(arg, val)
     }
+    
+    fn move_to_register(arg: RegType, val: usize) -> Self {
+        QueryInstruction::GetVariable(arg, val)
+    }
 
     fn argument_to_value(arg: RegType, val: usize) -> Self {
         QueryInstruction::PutValue(arg, val)