]> Repositorios git - scryer-prolog.git/commitdiff
change arithmetic evaluation iterator to new target type
authorMark Thom <[email protected]>
Thu, 18 Jan 2018 04:39:59 +0000 (21:39 -0700)
committerMark Thom <[email protected]>
Thu, 18 Jan 2018 04:39:59 +0000 (21:39 -0700)
src/prolog/arithmetic.rs
src/prolog/machine/machine_state.rs
src/tests.rs

index b6cc97cf59de2c054075e5e13239e3b741b39aea..aebbc90ce55c51541be17b164081497874e9233b 100644 (file)
@@ -1,6 +1,7 @@
 use prolog::ast::*;
 use prolog::fixtures::*;
 
+use std::cell::Cell;
 use std::cmp::{min, max};
 use std::vec::Vec;
 
@@ -39,33 +40,34 @@ impl Term {
     }
 }
 
+pub enum ArithTermRef<'a> {
+    Constant(&'a Constant),
+    Op(ClauseType<'a>, &'a Vec<Box<Term>>),
+    Var(&'a Cell<VarReg>, &'a Var)
+}
+
 impl<'a> Iterator for ArithExprIterator<'a> {
-    type Item = TermRef<'a>;
+    type Item = Result<ArithTermRef<'a>, ArithmeticError>;
 
     fn next(&mut self) -> Option<Self::Item> {
         while let Some(iter_state) = self.state_stack.pop() {
             match iter_state {
-                TermIterState::AnonVar(lvl) =>
-                    return Some(TermRef::AnonVar(lvl)),
+                TermIterState::AnonVar(_) =>
+                    return Some(Err(ArithmeticError::UninstantiatedVar)),
                 TermIterState::Clause(child_num, ct, child_terms) => {
                     if child_num == child_terms.len() {
-                        return Some(TermRef::Clause(ct, child_terms));
+                        return Some(Ok(ArithTermRef::Op(ct, child_terms)));
                     } else {
                         self.state_stack.push(TermIterState::Clause(child_num + 1, ct, child_terms));
                         self.push_subterm(ct.level_of_subterms(), child_terms[child_num].as_ref());
                     }
                 },
-                TermIterState::InitialCons(lvl, cell, head, tail) => {
-                    self.state_stack.push(TermIterState::FinalCons(lvl, cell, head, tail));
-                    self.push_subterm(Level::Deep, tail);
-                    self.push_subterm(Level::Deep, head);
-                },
-                TermIterState::FinalCons(lvl, cell, head, tail) =>
-                    return Some(TermRef::Cons(lvl, cell, head, tail)),
-                TermIterState::Constant(lvl, cell, constant) =>
-                    return Some(TermRef::Constant(lvl, cell, constant)),
-                TermIterState::Var(lvl, cell, var) =>
-                    return Some(TermRef::Var(lvl, cell, var))
+                TermIterState::Constant(_, _, c) =>
+                    return Some(Ok(ArithTermRef::Constant(c))),
+                TermIterState::Var(_, cell, var) =>
+                    return Some(Ok(ArithTermRef::Var(cell, var))),
+                _ =>
+                    return Some(Err(ArithmeticError::InvalidTerm))
             };
         }
 
@@ -183,26 +185,25 @@ impl<'a> ArithmeticEvaluator<'a> {
         let mut code = Vec::new();
 
         for term_ref in term.arith_expr_iter()? {
-            match term_ref {
-                TermRef::Constant(_, _, c) =>
-                    try!(self.push_constant(c)),
-                TermRef::Var(_, vr, name) => {
-                    let r = if vr.get().norm().reg_num() == 0 {
+            match term_ref? {
+                ArithTermRef::Constant(c) => self.push_constant(c)?,
+                ArithTermRef::Var(cell, name) => {
+                    let r = if cell.get().norm().reg_num() == 0 {
                         match self.bindings.get(name) {
                             Some(&VarData::Temp(_, t, _)) if t != 0 => RegType::Temp(t),
                             Some(&VarData::Perm(p)) if p != 0 => RegType::Perm(p),
                             _ => return Err(ArithmeticError::UninstantiatedVar)
                         }
                     } else {
-                        vr.get().norm()
+                        cell.get().norm()
                     };
 
                     self.interm.push(ArithmeticTerm::Reg(r));
                 },
-                TermRef::Clause(ClauseType::Deep(_, _, name, _), terms) => {
+                ArithTermRef::Op(ClauseType::Deep(_, _, name, _), terms) => {
                     code.push(Line::Arithmetic(self.instr_from_clause(&*name, terms)?));
                 },
-                TermRef::Clause(ClauseType::Root, terms) => {
+                ArithTermRef::Op(ClauseType::Root, terms) => {
                     let name = term.name().unwrap();
                     code.push(Line::Arithmetic(self.instr_from_clause(&*name, terms)?));
                 },
index 0bf516f270a50b1412b840449b7684f4d331f071..aae89b190055cb1bc606ebdcc19b3ff28c6ba949 100644 (file)
@@ -1139,15 +1139,14 @@ impl MachineState {
         self.p  = CodePtr::DirEntry(59);
     }
 
-    fn throw_exception
-        (&mut self, hcv: Vec<HeapCellValue>) {
-            let h = self.heap.h;
-
-            self.registers[1] = Addr::HeapCell(h);
-
-            self.heap.append(hcv);
-            self.goto_throw();
-        }
+    fn throw_exception(&mut self, hcv: Vec<HeapCellValue>) {
+        let h = self.heap.h;
+        
+        self.registers[1] = Addr::HeapCell(h);
+        
+        self.heap.append(hcv);
+        self.goto_throw();
+    }
 
     fn setup_call_n(&mut self, arity: usize) -> Option<PredicateKey>
     {
index dba7b0b0a24a0f8b96770dad10ce7cbb918c7f9b..11119a35fb8aa5576b52c197abc1e0c4a8e4f5f7 100644 (file)
@@ -164,7 +164,7 @@ fn test_queries_on_predicates() {
     submit(&mut wam, "p(X) :- q(X). p(X) :- r(X).");
     submit(&mut wam, "q(X) :- a.");
     submit(&mut wam, "r(X) :- s(X, t). r(X) :- t(X, u).");
-    
+
     submit(&mut wam, "s(x, t).");
     submit(&mut wam, "t(y, u).");
 
@@ -260,13 +260,13 @@ fn test_queries_on_predicates() {
     assert_prolog_success!(&mut wam, "?- p(X).", ["X = f(a)",
                                                   "X = f(b)",
                                                   "X = f(c)"]);
-    
+
     submit(&mut wam, "p(X) :- f(f(Y)), g(Y, f(Y)), i(X, f(Y)).");
     submit(&mut wam, "g(Y, f(Y)) :- g(f(Y)).");
 
     assert_prolog_success!(&mut wam, "?- p(X).", ["X = f(a)",
                                                   "X = f(b)",
-                                                  "X = f(c)"]);    
+                                                  "X = f(c)"]);
 }
 
 #[test]
@@ -389,7 +389,7 @@ fn test_queries_on_lists()
     assert_prolog_failure!(&mut wam, "?- member(a, [c, [X, Y]]).");
     assert_prolog_failure!(&mut wam, "?- member(c, [a, [X, Y]]).");
     assert_prolog_success!(&mut wam, "?- member(a, [a, [X, Y]]).", ["X = _2", "Y = _0"]);
-    
+
     assert_prolog_success!(&mut wam, "?- member(a, [X, Y, Z]).", ["Y = _2", "X = a",  "Z = _0",
                                                                   "Y = a",  "X = _4", "Z = _0",
                                                                   "Y = _2",  "X = _4", "Z = a"]);
@@ -466,7 +466,7 @@ fn test_queries_on_indexed_predicates()
     assert_prolog_success!(&mut wam, "?- p(f(a)).");
     assert_prolog_success!(&mut wam, "?- p(g(b, X)).", ["X = c"]);
     assert_prolog_success!(&mut wam, "?- p(g(Y, X)).", ["X = c", "Y = b"]);
-    assert_prolog_success!(&mut wam, "?- p(g(Y, c)).", ["Y = b"]);    
+    assert_prolog_success!(&mut wam, "?- p(g(Y, c)).", ["Y = b"]);
     assert_prolog_success!(&mut wam, "?- p(g(b)).");
     assert_prolog_success!(&mut wam, "?- p([]).");
     assert_prolog_success!(&mut wam, "?- p([c, d, e]).");
@@ -502,18 +502,18 @@ fn test_queries_on_indexed_predicates()
     assert_eq!(submit(&mut wam, "?- p(b)."), true);
     assert_eq!(submit(&mut wam, "?- p(c)."), true);
     assert_eq!(submit(&mut wam, "?- p(true(a))."), true);
-    
+
     assert_prolog_success!(&mut wam, "?- p(g(b, X)).", ["X = c",
                                                         "X = _2"]);
     assert_prolog_success!(&mut wam, "?- p(g(Y, X)).", ["X = c", "Y = b",
                                                         "X = _2", "Y = _1"]);
     assert_prolog_success!(&mut wam, "?- p(g(Y, c)).", ["Y = b",
                                                         "Y = _1"]);
-    
+
     assert_eq!(submit(&mut wam, "?- p(g(b))."), true);
     assert_eq!(submit(&mut wam, "?- p([])."), true);
     assert_eq!(submit(&mut wam, "?- p([c, d, e])."), true);
-    
+
     assert_prolog_success!(&mut wam, "?- p([c, d | X]).", ["X = _1",
                                                            "X = [e]"]);
     assert_prolog_success!(&mut wam, "?- p([c|X]).", ["X = [d, e]",
@@ -523,7 +523,7 @@ fn test_queries_on_indexed_predicates()
                                                       "X = _1", "Y = _0"]);
     assert_prolog_success!(&mut wam, "?- p([Y|[d|Xs]]).", ["Xs = [e]", "Y = c",
                                                            "Xs = _1", "Y = _2"]);
-    
+
     assert_prolog_success!(&mut wam, "?- p(blah).");
 
     submit(&mut wam, "ind_call(or(X, Y)) :- ind_call(X).
@@ -599,7 +599,7 @@ fn test_queries_on_conjuctive_queries() {
                            ["X = b",
                             "X = c"]);
     assert_prolog_success!(&mut wam, "?- member(X, [a,c]), member(X, [b,c]).",
-                           ["X = c"]);    
+                           ["X = c"]);
     assert_prolog_success!(&mut wam, "?- member(X, [a,b,c,d]), !, member(X, [a,d]).",
                            ["X = a"]);
     assert_prolog_failure!(&mut wam, "?- member(X, [a,b,c,d]), !, member(X, [e]).");
@@ -701,7 +701,7 @@ fn test_queries_on_call_n()
                             "X = c", "Y = c", "Z = a",
                             "X = c", "Y = c", "Z = b",
                             "X = c", "Y = c", "Z = c"]);
-                            
+
     assert_prolog_success!(&mut wam, "?- maplist(f, [a,Y,Z]).",
                            ["Z = a", "Y = a",
                             "Z = a", "Y = b",
@@ -712,7 +712,7 @@ fn test_queries_on_call_n()
                             "Z = c", "Y = a",
                             "Z = c", "Y = b",
                             "Z = c", "Y = c"]);
-                            
+
     assert_prolog_success!(&mut wam, "?- maplist(f, [X,a,b]).",
                            ["X = a",
                             "X = b",
@@ -760,21 +760,21 @@ fn test_queries_on_call_n()
     submit(&mut wam, "r(f(X)) :- p(X). r(g(Y)) :- p(Y).");
 
     assert_prolog_success!(&mut wam, "?- f(r, X, Y).",
-                           ["X = f(x)", "Y = f(x)", 
-                            "X = f(x)", "Y = f(y)", 
-                            "X = f(x)", "Y = g(x)", 
-                            "X = f(x)", "Y = g(y)", 
-                            "X = f(y)", "Y = f(x)", 
-                            "X = f(y)", "Y = f(y)", 
-                            "X = f(y)", "Y = g(x)", 
-                            "X = f(y)", "Y = g(y)", 
-                            "X = g(x)", "Y = f(x)", 
-                            "X = g(x)", "Y = f(y)", 
-                            "X = g(x)", "Y = g(x)", 
-                            "X = g(x)", "Y = g(y)", 
-                            "X = g(y)", "Y = f(x)",                            
-                            "X = g(y)", "Y = f(y)",                            
-                            "X = g(y)", "Y = g(x)",                             
+                           ["X = f(x)", "Y = f(x)",
+                            "X = f(x)", "Y = f(y)",
+                            "X = f(x)", "Y = g(x)",
+                            "X = f(x)", "Y = g(y)",
+                            "X = f(y)", "Y = f(x)",
+                            "X = f(y)", "Y = f(y)",
+                            "X = f(y)", "Y = g(x)",
+                            "X = f(y)", "Y = g(y)",
+                            "X = g(x)", "Y = f(x)",
+                            "X = g(x)", "Y = f(y)",
+                            "X = g(x)", "Y = g(x)",
+                            "X = g(x)", "Y = g(y)",
+                            "X = g(y)", "Y = f(x)",
+                            "X = g(y)", "Y = f(y)",
+                            "X = g(y)", "Y = g(x)",
                             "X = g(y)", "Y = g(y)"]);
     assert_prolog_success!(&mut wam, "?- f(r, X, X).",
                            ["X = f(x)",
@@ -1006,7 +1006,7 @@ fn test_queries_on_exceptions()
                             "X = y", "E = _2",
                             "X = z", "E = _2",
                             "X = _1", "E = handle_top(an_error_1)",
-                            "X = _1", "E = handle_top(an_error_2)"]);    
+                            "X = _1", "E = handle_top(an_error_2)"]);
 
     submit(&mut wam, "handle(x). handle(y). handle(z). handle(v) :- throw(X).");
 
@@ -1052,17 +1052,17 @@ fn test_queries_on_arithmetic()
 
     assert_prolog_success!(&mut wam, "?- catch(f(X), evaluation_error(E), true), E = zero_divisor.",
                            ["E = zero_divisor", "X = _1"]);
-    
+
     submit(&mut wam, "f(X) :- X is (5 rdiv 1) / 0.");
 
     assert_prolog_success!(&mut wam, "?- catch(f(X), evaluation_error(E), true), E = zero_divisor.",
                            ["E = zero_divisor", "X = _1"]);
-    
+
     submit(&mut wam, "f(X) :- X is 5.0 / 0.");
 
     assert_prolog_success!(&mut wam, "?- catch(f(X), evaluation_error(E), true), E = zero_divisor.",
                            ["E = zero_divisor", "X = _1"]);
-    
+
     assert_prolog_success!(&mut wam, "?- X is ((3 + 4) // 2) + 2 - 1 // 1, Y is 2+2, Z is X+Y.",
                            ["Y = 4", "X = 4", "Z = 8"]);
 
@@ -1075,7 +1075,7 @@ fn test_queries_on_arithmetic()
     assert_prolog_success!(&mut wam, "?- X is 10 xor -4, X is -10.", ["X = -10"]);
     assert_prolog_success!(&mut wam, "?- X is 4 xor -7, X is -3.", ["X = -3"]);
     assert_prolog_success!(&mut wam, "?- X is 10 xor 5 + 55, X = 70.", ["X = 70"]);
-    
+
     assert_prolog_success!(&mut wam, "?- X is 10 rem -3, X = 1.", ["X = 1"]);
     assert_prolog_success!(&mut wam, "?- X is 10 mod -3, X is -2.", ["X = -2"]);
 }