]> Repositorios git - scryer-prolog.git/commitdiff
cleanup of run_query
authorMark Thom <[email protected]>
Mon, 8 May 2017 20:33:27 +0000 (14:33 -0600)
committerMark Thom <[email protected]>
Mon, 8 May 2017 20:33:27 +0000 (14:33 -0600)
Cargo.lock
Cargo.toml
src/main.rs
src/prolog/ast.rs
src/prolog/codegen.rs
src/prolog/io.rs
src/prolog/machine.rs

index f5be324b9eccb33c6669188988158f3a184633b2..c1aa27590ddda4dc96819dd4e7583ecaf595f7d6 100644 (file)
@@ -1,6 +1,6 @@
 [root]
 name = "rusty-wam"
-version = "0.6.1"
+version = "0.6.2"
 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 736bac4ee39dd9dfa785458675aba16e91a4bd09..50bcf612073aac3c58d52c12d79428803aa9c817 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "rusty-wam"
-version = "0.6.1"
+version = "0.6.2"
 authors = ["Mark Thom"]
 
 build = "build.rs"
index d7b46e1fd06194ac514c68286ba0039105e886b3..ea274c4ec7cd8f1b2e4ed59a5cae6b8704e39c6a 100644 (file)
@@ -16,9 +16,9 @@ mod tests {
         match parse_TopLevel(buffer.trim()) {
             Ok(tl) =>
                 match eval(wam, &tl) {
-                    EvalResult::InitialQuerySuccess(_, _) |
-                    EvalResult::EntrySuccess |
-                    EvalResult::SubsequentQuerySuccess =>
+                    EvalSession::InitialQuerySuccess(_, _) |
+                    EvalSession::EntrySuccess |
+                    EvalSession::SubsequentQuerySuccess =>
                         true,
                     _ => false
                 },
index 6674f261051a968e40c21439045089347fd3027c..592c9312b3d77c5576e05c5a956bb9a352341a06 100644 (file)
@@ -213,6 +213,16 @@ pub enum ControlInstruction {
     Proceed
 }
 
+impl ControlInstruction {
+    pub fn is_jump_instr(&self) -> bool {
+        match self {
+            &ControlInstruction::Call(_, _, _) => true,
+            &ControlInstruction::Execute(_, _) => true,
+            _ => false
+        }
+    }
+}
+
 pub enum IndexingInstruction {
     SwitchOnTerm(usize, usize, usize, usize),
     SwitchOnConstant(usize, HashMap<Constant, usize>),
@@ -362,7 +372,7 @@ impl HeapCellValue {
 #[derive(Clone, Copy, PartialEq)]
 pub enum CodePtr {
     DirEntry(usize),
-    TopLevel(usize, usize, usize) // chunk_num, e, offset.
+    TopLevel(usize, usize) // chunk_num, offset.
 }
 
 impl PartialOrd<CodePtr> for CodePtr {
@@ -370,9 +380,9 @@ impl PartialOrd<CodePtr> for CodePtr {
         match (self, other) {
             (&CodePtr::DirEntry(p1), &CodePtr::DirEntry(ref p2)) =>
                 p1.partial_cmp(p2),
-            (&CodePtr::DirEntry(_), &CodePtr::TopLevel(_, _, _)) =>
+            (&CodePtr::DirEntry(_), &CodePtr::TopLevel(_, _)) =>
                 Some(Ordering::Less),
-            (&CodePtr::TopLevel(_, _, p1), &CodePtr::TopLevel(_, _, ref p2)) =>
+            (&CodePtr::TopLevel(_, p1), &CodePtr::TopLevel(_, ref p2)) =>
                 p1.partial_cmp(p2),
             _ => Some(Ordering::Greater)
         }
@@ -381,7 +391,7 @@ impl PartialOrd<CodePtr> for CodePtr {
 
 impl Default for CodePtr {
     fn default() -> Self {
-        CodePtr::TopLevel(0, 0, 0)
+        CodePtr::TopLevel(0, 0)
     }
 }
 
@@ -391,7 +401,7 @@ impl Add<usize> for CodePtr {
     fn add(self, rhs: usize) -> Self::Output {
         match self {
             CodePtr::DirEntry(p) => CodePtr::DirEntry(p + rhs),
-            CodePtr::TopLevel(cn, e, p) => CodePtr::TopLevel(cn, e, p + rhs)
+            CodePtr::TopLevel(cn, p) => CodePtr::TopLevel(cn, p + rhs)
         }
     }
 }
@@ -400,7 +410,7 @@ impl AddAssign<usize> for CodePtr {
     fn add_assign(&mut self, rhs: usize) {
         match self {
             &mut CodePtr::DirEntry(ref mut p) |
-            &mut CodePtr::TopLevel(_, _, ref mut p) => *p += rhs
+            &mut CodePtr::TopLevel(_, ref mut p) => *p += rhs
         }
     }
 }
index 25e0f248047230f28cde45c2199c620bfd78dd5f..193e145ef7a8956deed7adba807c2b1902272cbb 100644 (file)
@@ -14,7 +14,7 @@ pub struct CodeGenerator<'a, TermMarker> {
     var_count: HashMap<&'a Var, usize>
 }
 
-pub enum EvalResult<'a> {
+pub enum EvalSession<'a> {
     EntryFailure,
     EntrySuccess,
     InitialQuerySuccess(AllocVarDict<'a>, HeapVarDict<'a>),
@@ -22,10 +22,10 @@ pub enum EvalResult<'a> {
     SubsequentQuerySuccess,
 }
 
-impl<'a> EvalResult<'a> {
+impl<'a> EvalSession<'a> {
     #[allow(dead_code)]
     pub fn failed_query(&self) -> bool {
-        if let &EvalResult::QueryFailure = self {
+        if let &EvalSession::QueryFailure = self {
             true
         } else {
             false
index 37c872ba6a07e27838e815b75dda81100c6a48d6..5bce6df150dbf939f1d2379ca9b4ebb2057d7b0f 100644 (file)
@@ -257,7 +257,7 @@ pub fn read() -> String {
     result
 }
 
-pub fn eval<'a, 'b: 'a>(wam: &'a mut Machine, tl: &'b TopLevel) -> EvalResult<'b>
+pub fn eval<'a, 'b: 'a>(wam: &'a mut Machine, tl: &'b TopLevel) -> EvalSession<'b>
 {
     match tl {
         &TopLevel::Predicate(ref clauses) => {
@@ -267,13 +267,13 @@ pub fn eval<'a, 'b: 'a>(wam: &'a mut Machine, tl: &'b TopLevel) -> EvalResult<'b
                 let compiled_pred = cg.compile_predicate(clauses);
                 wam.add_predicate(clauses, compiled_pred);
 
-                EvalResult::EntrySuccess
+                EvalSession::EntrySuccess
             } else {
                 let msg = r"Error: predicate is inconsistent.
 Each predicate must have the same name and arity.";
 
                 println!("{}", msg);
-                EvalResult::EntryFailure
+                EvalSession::EntryFailure
             }
         },
         &TopLevel::Fact(ref fact) => {
@@ -282,7 +282,7 @@ Each predicate must have the same name and arity.";
             let compiled_fact = cg.compile_fact(fact);
             wam.add_fact(fact, compiled_fact);
 
-            EvalResult::EntrySuccess
+            EvalSession::EntrySuccess
         },
         &TopLevel::Rule(ref rule) => {
             let mut cg = CodeGenerator::<DebrayAllocator>::new();
@@ -290,7 +290,7 @@ Each predicate must have the same name and arity.";
             let compiled_rule = cg.compile_rule(rule);
             wam.add_rule(rule, compiled_rule);
 
-            EvalResult::EntrySuccess
+            EvalSession::EntrySuccess
         },
         &TopLevel::Query(ref query) => {
             let mut cg = CodeGenerator::<DebrayAllocator>::new();
@@ -301,9 +301,9 @@ Each predicate must have the same name and arity.";
     }
 }
 
-pub fn print(wam: &mut Machine, result: EvalResult) {
+pub fn print(wam: &mut Machine, result: EvalSession) {
     match result {
-        EvalResult::InitialQuerySuccess(alloc_locs, mut heap_locs) => {
+        EvalSession::InitialQuerySuccess(alloc_locs, mut heap_locs) => {
             println!("yes");
 
             if heap_locs.is_empty() {
@@ -311,7 +311,7 @@ pub fn print(wam: &mut Machine, result: EvalResult) {
             }
 
             'outer: loop {
-                let mut result = EvalResult::QueryFailure;
+                let mut result = EvalSession::QueryFailure;
                 let bindings = wam.heap_view(&heap_locs);
 
                 let stdin  = stdin();
@@ -336,7 +336,7 @@ pub fn print(wam: &mut Machine, result: EvalResult) {
                         }
                     }
 
-                    if let &EvalResult::QueryFailure = &result {
+                    if let &EvalSession::QueryFailure = &result {
                         write!(stdout, "no\n\r").unwrap();
                         stdout.flush().unwrap();
                         break;
@@ -346,7 +346,7 @@ pub fn print(wam: &mut Machine, result: EvalResult) {
                 }
             }
         },
-        EvalResult::QueryFailure => println!("no"),
+        EvalSession::QueryFailure => println!("no"),
         _ => {}
     };
 }
index 4af0fdc43e8c7089b0a533ec81089402c23890f0..2e96de5c58488bd22988935f33727ccb99848bdb 100644 (file)
@@ -75,7 +75,7 @@ impl Index<CodePtr> for Machine {
 
     fn index(&self, ptr: CodePtr) -> &Self::Output {
         match ptr {
-            CodePtr::TopLevel(_, _, p) => {
+            CodePtr::TopLevel(_, p) => {
                 match &self.cached_query {
                     &Some(ref cq) => &cq[p],
                     &None => panic!("Out-of-bounds top level index.")
@@ -142,13 +142,13 @@ impl Machine {
         }
     }
 
-    fn execute_instr(&mut self, ptr: CodePtr)
+    fn execute_instr(&mut self)
     {
         // can't use self[ptr] or self.index(ptr) to set the value of
         // instr! instr is then typed as Line, not &Line. WHY????
         // This is a compiler bug. Has to be.
-        let instr = match ptr {
-            CodePtr::TopLevel(_, _, p) => {
+        let instr = match self.ms.p {
+            CodePtr::TopLevel(_, p) => {
                 match &self.cached_query {
                     &Some(ref cq) => &cq[p],
                     &None => return
@@ -203,13 +203,13 @@ impl Machine {
             let b = self.ms.b - 1;
             self.ms.or_stack[b].bp
         } else {
-            self.ms.p = CodePtr::TopLevel(0, 0, 0);
+            self.ms.p = CodePtr::TopLevel(0, 0);
             return;
         };
 
         self.ms.p = p;
 
-        if let CodePtr::TopLevel(_, _, p) = p {
+        if let CodePtr::TopLevel(_, p) = p {
             self.ms.fail = p == 0;
             self.ms.b0 = b0;
 
@@ -219,19 +219,18 @@ impl Machine {
         }
     }
 
-    fn query_stepper<'a>(&mut self, mut ptr: CodePtr)
+    fn query_stepper<'a>(&mut self)
     {
         loop
         {
-            self.execute_instr(ptr);
+            self.execute_instr();
 
             if self.failed() {
                 self.backtrack();
             }
 
             match self.ms.p {
-                CodePtr::DirEntry(p) if p < self.code.len() =>
-                    ptr = self.ms.p,
+                CodePtr::DirEntry(p) if p < self.code.len() => {},
                 _ => break
             };
         }
@@ -239,22 +238,22 @@ impl Machine {
 
     fn record_var_places<'a>(&self,
                              chunk_num: usize,
-                             e: usize,
                              alloc_locs: &AllocVarDict<'a>,
                              heap_locs: &mut HeapVarDict<'a>)
     {
         for (var, var_data) in alloc_locs {
             match var_data {
                 &VarData::Perm(_) => {
+                    let e = self.ms.e;
                     let r = var_data.as_reg_type().reg_num();
                     let addr = self.ms.and_stack[e][r].clone();
-
+                    
                     heap_locs.insert(var, addr);
                 },
                 &VarData::Temp(cn, _, _) if cn == chunk_num => {
                     let r = var_data.as_reg_type();
                     let addr = self.ms[r].clone();
-
+                    
                     heap_locs.insert(var, addr);
                 },
                 _ => {}
@@ -264,38 +263,30 @@ impl Machine {
 
     fn run_query<'a>(&mut self, alloc_locs: &AllocVarDict<'a>, heap_locs: &mut HeapVarDict<'a>)
     {
-        let end_ptr    = CodePtr::TopLevel(0, 0, self.cached_query_size());
-        let mut tl_ptr = self.ms.p;
-
-        while tl_ptr < end_ptr {
-            self.query_stepper(tl_ptr);
-
-            tl_ptr = self.ms.p;
-
-            if let &mut CodePtr::TopLevel(ref mut cn, ref mut e, p) = &mut tl_ptr {
-                if p == 0 {
-                    break;
+        let end_ptr = CodePtr::TopLevel(0, self.cached_query_size());
+
+        while self.ms.p < end_ptr {
+            if let CodePtr::TopLevel(mut cn, p) = self.ms.p {
+                if let &Line::Control(ref ctrl_instr) = &self[CodePtr::TopLevel(cn, p)] {
+                    if ctrl_instr.is_jump_instr() {
+                        self.record_var_places(cn, alloc_locs, heap_locs);
+                        cn += 1;
+                    }
                 }
 
-                match &self[CodePtr::TopLevel(*cn, *e, p)] {
-                    &Line::Control(ControlInstruction::Call(_, _, _))
-                  | &Line::Control(ControlInstruction::Execute(_, _)) => {
-                      self.record_var_places(*cn, *e, alloc_locs, heap_locs);
-                      *cn += 1;
-                  },
-                    &Line::Control(ControlInstruction::Allocate(_)) =>
-                        *e = self.ms.e,
-                    _ => {}
-                };
-
-                self.ms.p = CodePtr::TopLevel(*cn, *e, p);
-            } else {
-                break;
+                self.ms.p = CodePtr::TopLevel(cn, p);
             }
+                
+            self.query_stepper();
+
+            match self.ms.p {
+                CodePtr::TopLevel(_, p) if p > 0 => {},
+                _ => break                    
+            };            
         }
     }
 
-    pub fn submit_query<'a>(&mut self, code: Code, alloc_locs: AllocVarDict<'a>) -> EvalResult<'a>
+    pub fn submit_query<'a>(&mut self, code: Code, alloc_locs: AllocVarDict<'a>) -> EvalSession<'a>
     {
         let mut heap_locs = HashMap::new();
         self.cached_query = Some(code);
@@ -303,38 +294,38 @@ impl Machine {
         self.run_query(&alloc_locs, &mut heap_locs);
 
         if self.failed() {
-            EvalResult::QueryFailure
+            EvalSession::QueryFailure
         } else {
-            EvalResult::InitialQuerySuccess(alloc_locs, heap_locs)
+            EvalSession::InitialQuerySuccess(alloc_locs, heap_locs)
         }
     }
 
     pub fn continue_query<'a>(&mut self,
                               alloc_locs: &AllocVarDict<'a>,
                               heap_locs: &mut HeapVarDict<'a>)
-                              -> EvalResult
+                              -> EvalSession
     {
         if !self.or_stack_is_empty() {
             if self.ms.b == 0 {
-                return EvalResult::QueryFailure;
+                return EvalSession::QueryFailure;
             }
 
             let b = self.ms.b - 1;
             self.ms.p = self.ms.or_stack[b].bp;
 
-            if let CodePtr::TopLevel(_, _, 0) = self.ms.p {
-                return EvalResult::QueryFailure
+            if let CodePtr::TopLevel(_, 0) = self.ms.p {
+                return EvalSession::QueryFailure
             }
 
             self.run_query(alloc_locs, heap_locs);
 
             if self.failed() {
-                EvalResult::QueryFailure
+                EvalSession::QueryFailure
             } else {
-                EvalResult::SubsequentQuerySuccess
+                EvalSession::SubsequentQuerySuccess
             }
         } else {
-            EvalResult::QueryFailure
+            EvalSession::QueryFailure
         }
     }