From: Mark Thom Date: Thu, 18 Jan 2018 04:39:59 +0000 (-0700) Subject: change arithmetic evaluation iterator to new target type X-Git-Tag: v0.8.110~618 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=f95901a6d09a50e2327408ee160ba03b673b99d1;p=scryer-prolog.git change arithmetic evaluation iterator to new target type --- diff --git a/src/prolog/arithmetic.rs b/src/prolog/arithmetic.rs index b6cc97cf..aebbc90c 100644 --- a/src/prolog/arithmetic.rs +++ b/src/prolog/arithmetic.rs @@ -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>), + Var(&'a Cell, &'a Var) +} + impl<'a> Iterator for ArithExprIterator<'a> { - type Item = TermRef<'a>; + type Item = Result, ArithmeticError>; fn next(&mut self) -> Option { 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)?)); }, diff --git a/src/prolog/machine/machine_state.rs b/src/prolog/machine/machine_state.rs index 0bf516f2..aae89b19 100644 --- a/src/prolog/machine/machine_state.rs +++ b/src/prolog/machine/machine_state.rs @@ -1139,15 +1139,14 @@ impl MachineState { self.p = CodePtr::DirEntry(59); } - fn throw_exception - (&mut self, hcv: Vec) { - 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) { + 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 { diff --git a/src/tests.rs b/src/tests.rs index dba7b0b0..11119a35 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -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"]); }