change arithmetic evaluation iterator to new target type

This commit is contained in:
Mark Thom
2018-01-17 21:39:59 -07:00
parent d8be7b5b49
commit f95901a6d0
3 changed files with 64 additions and 64 deletions

View File

@@ -1,6 +1,7 @@
use prolog::ast::*; use prolog::ast::*;
use prolog::fixtures::*; use prolog::fixtures::*;
use std::cell::Cell;
use std::cmp::{min, max}; use std::cmp::{min, max};
use std::vec::Vec; 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> { impl<'a> Iterator for ArithExprIterator<'a> {
type Item = TermRef<'a>; type Item = Result<ArithTermRef<'a>, ArithmeticError>;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
while let Some(iter_state) = self.state_stack.pop() { while let Some(iter_state) = self.state_stack.pop() {
match iter_state { match iter_state {
TermIterState::AnonVar(lvl) => TermIterState::AnonVar(_) =>
return Some(TermRef::AnonVar(lvl)), return Some(Err(ArithmeticError::UninstantiatedVar)),
TermIterState::Clause(child_num, ct, child_terms) => { TermIterState::Clause(child_num, ct, child_terms) => {
if child_num == child_terms.len() { if child_num == child_terms.len() {
return Some(TermRef::Clause(ct, child_terms)); return Some(Ok(ArithTermRef::Op(ct, child_terms)));
} else { } else {
self.state_stack.push(TermIterState::Clause(child_num + 1, ct, child_terms)); 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()); self.push_subterm(ct.level_of_subterms(), child_terms[child_num].as_ref());
} }
}, },
TermIterState::InitialCons(lvl, cell, head, tail) => { TermIterState::Constant(_, _, c) =>
self.state_stack.push(TermIterState::FinalCons(lvl, cell, head, tail)); return Some(Ok(ArithTermRef::Constant(c))),
self.push_subterm(Level::Deep, tail); TermIterState::Var(_, cell, var) =>
self.push_subterm(Level::Deep, head); return Some(Ok(ArithTermRef::Var(cell, var))),
}, _ =>
TermIterState::FinalCons(lvl, cell, head, tail) => return Some(Err(ArithmeticError::InvalidTerm))
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))
}; };
} }
@@ -183,26 +185,25 @@ impl<'a> ArithmeticEvaluator<'a> {
let mut code = Vec::new(); let mut code = Vec::new();
for term_ref in term.arith_expr_iter()? { for term_ref in term.arith_expr_iter()? {
match term_ref { match term_ref? {
TermRef::Constant(_, _, c) => ArithTermRef::Constant(c) => self.push_constant(c)?,
try!(self.push_constant(c)), ArithTermRef::Var(cell, name) => {
TermRef::Var(_, vr, name) => { let r = if cell.get().norm().reg_num() == 0 {
let r = if vr.get().norm().reg_num() == 0 {
match self.bindings.get(name) { match self.bindings.get(name) {
Some(&VarData::Temp(_, t, _)) if t != 0 => RegType::Temp(t), Some(&VarData::Temp(_, t, _)) if t != 0 => RegType::Temp(t),
Some(&VarData::Perm(p)) if p != 0 => RegType::Perm(p), Some(&VarData::Perm(p)) if p != 0 => RegType::Perm(p),
_ => return Err(ArithmeticError::UninstantiatedVar) _ => return Err(ArithmeticError::UninstantiatedVar)
} }
} else { } else {
vr.get().norm() cell.get().norm()
}; };
self.interm.push(ArithmeticTerm::Reg(r)); 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)?)); 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(); let name = term.name().unwrap();
code.push(Line::Arithmetic(self.instr_from_clause(&*name, terms)?)); code.push(Line::Arithmetic(self.instr_from_clause(&*name, terms)?));
}, },

View File

@@ -1139,15 +1139,14 @@ impl MachineState {
self.p = CodePtr::DirEntry(59); self.p = CodePtr::DirEntry(59);
} }
fn throw_exception fn throw_exception(&mut self, hcv: Vec<HeapCellValue>) {
(&mut self, hcv: Vec<HeapCellValue>) { let h = self.heap.h;
let h = self.heap.h;
self.registers[1] = Addr::HeapCell(h);
self.registers[1] = Addr::HeapCell(h);
self.heap.append(hcv);
self.heap.append(hcv); self.goto_throw();
self.goto_throw(); }
}
fn setup_call_n(&mut self, arity: usize) -> Option<PredicateKey> fn setup_call_n(&mut self, arity: usize) -> Option<PredicateKey>
{ {

View File

@@ -164,7 +164,7 @@ fn test_queries_on_predicates() {
submit(&mut wam, "p(X) :- q(X). p(X) :- r(X)."); submit(&mut wam, "p(X) :- q(X). p(X) :- r(X).");
submit(&mut wam, "q(X) :- a."); submit(&mut wam, "q(X) :- a.");
submit(&mut wam, "r(X) :- s(X, t). r(X) :- t(X, u)."); submit(&mut wam, "r(X) :- s(X, t). r(X) :- t(X, u).");
submit(&mut wam, "s(x, t)."); submit(&mut wam, "s(x, t).");
submit(&mut wam, "t(y, u)."); 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)", assert_prolog_success!(&mut wam, "?- p(X).", ["X = f(a)",
"X = f(b)", "X = f(b)",
"X = f(c)"]); "X = f(c)"]);
submit(&mut wam, "p(X) :- f(f(Y)), g(Y, f(Y)), i(X, f(Y))."); 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))."); submit(&mut wam, "g(Y, f(Y)) :- g(f(Y)).");
assert_prolog_success!(&mut wam, "?- p(X).", ["X = f(a)", assert_prolog_success!(&mut wam, "?- p(X).", ["X = f(a)",
"X = f(b)", "X = f(b)",
"X = f(c)"]); "X = f(c)"]);
} }
#[test] #[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(a, [c, [X, Y]]).");
assert_prolog_failure!(&mut wam, "?- member(c, [a, [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, [a, [X, Y]]).", ["X = _2", "Y = _0"]);
assert_prolog_success!(&mut wam, "?- member(a, [X, Y, Z]).", ["Y = _2", "X = a", "Z = _0", assert_prolog_success!(&mut wam, "?- member(a, [X, Y, Z]).", ["Y = _2", "X = a", "Z = _0",
"Y = a", "X = _4", "Z = _0", "Y = a", "X = _4", "Z = _0",
"Y = _2", "X = _4", "Z = a"]); "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(f(a)).");
assert_prolog_success!(&mut wam, "?- p(g(b, X)).", ["X = c"]); 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, 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(g(b)).");
assert_prolog_success!(&mut wam, "?- p([])."); assert_prolog_success!(&mut wam, "?- p([]).");
assert_prolog_success!(&mut wam, "?- p([c, d, e])."); 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(b)."), true);
assert_eq!(submit(&mut wam, "?- p(c)."), true); assert_eq!(submit(&mut wam, "?- p(c)."), true);
assert_eq!(submit(&mut wam, "?- p(true(a))."), true); assert_eq!(submit(&mut wam, "?- p(true(a))."), true);
assert_prolog_success!(&mut wam, "?- p(g(b, X)).", ["X = c", assert_prolog_success!(&mut wam, "?- p(g(b, X)).", ["X = c",
"X = _2"]); "X = _2"]);
assert_prolog_success!(&mut wam, "?- p(g(Y, X)).", ["X = c", "Y = b", assert_prolog_success!(&mut wam, "?- p(g(Y, X)).", ["X = c", "Y = b",
"X = _2", "Y = _1"]); "X = _2", "Y = _1"]);
assert_prolog_success!(&mut wam, "?- p(g(Y, c)).", ["Y = b", assert_prolog_success!(&mut wam, "?- p(g(Y, c)).", ["Y = b",
"Y = _1"]); "Y = _1"]);
assert_eq!(submit(&mut wam, "?- p(g(b))."), true); assert_eq!(submit(&mut wam, "?- p(g(b))."), true);
assert_eq!(submit(&mut wam, "?- p([])."), true); assert_eq!(submit(&mut wam, "?- p([])."), true);
assert_eq!(submit(&mut wam, "?- p([c, d, e])."), true); assert_eq!(submit(&mut wam, "?- p([c, d, e])."), true);
assert_prolog_success!(&mut wam, "?- p([c, d | X]).", ["X = _1", assert_prolog_success!(&mut wam, "?- p([c, d | X]).", ["X = _1",
"X = [e]"]); "X = [e]"]);
assert_prolog_success!(&mut wam, "?- p([c|X]).", ["X = [d, 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"]); "X = _1", "Y = _0"]);
assert_prolog_success!(&mut wam, "?- p([Y|[d|Xs]]).", ["Xs = [e]", "Y = c", assert_prolog_success!(&mut wam, "?- p([Y|[d|Xs]]).", ["Xs = [e]", "Y = c",
"Xs = _1", "Y = _2"]); "Xs = _1", "Y = _2"]);
assert_prolog_success!(&mut wam, "?- p(blah)."); assert_prolog_success!(&mut wam, "?- p(blah).");
submit(&mut wam, "ind_call(or(X, Y)) :- ind_call(X). submit(&mut wam, "ind_call(or(X, Y)) :- ind_call(X).
@@ -599,7 +599,7 @@ fn test_queries_on_conjuctive_queries() {
["X = b", ["X = b",
"X = c"]); "X = c"]);
assert_prolog_success!(&mut wam, "?- member(X, [a,c]), member(X, [b,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]).", assert_prolog_success!(&mut wam, "?- member(X, [a,b,c,d]), !, member(X, [a,d]).",
["X = a"]); ["X = a"]);
assert_prolog_failure!(&mut wam, "?- member(X, [a,b,c,d]), !, member(X, [e])."); 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 = a",
"X = c", "Y = c", "Z = b", "X = c", "Y = c", "Z = b",
"X = c", "Y = c", "Z = c"]); "X = c", "Y = c", "Z = c"]);
assert_prolog_success!(&mut wam, "?- maplist(f, [a,Y,Z]).", assert_prolog_success!(&mut wam, "?- maplist(f, [a,Y,Z]).",
["Z = a", "Y = a", ["Z = a", "Y = a",
"Z = a", "Y = b", "Z = a", "Y = b",
@@ -712,7 +712,7 @@ fn test_queries_on_call_n()
"Z = c", "Y = a", "Z = c", "Y = a",
"Z = c", "Y = b", "Z = c", "Y = b",
"Z = c", "Y = c"]); "Z = c", "Y = c"]);
assert_prolog_success!(&mut wam, "?- maplist(f, [X,a,b]).", assert_prolog_success!(&mut wam, "?- maplist(f, [X,a,b]).",
["X = a", ["X = a",
"X = b", "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)."); submit(&mut wam, "r(f(X)) :- p(X). r(g(Y)) :- p(Y).");
assert_prolog_success!(&mut wam, "?- f(r, X, Y).", assert_prolog_success!(&mut wam, "?- f(r, X, Y).",
["X = f(x)", "Y = f(x)", ["X = f(x)", "Y = f(x)",
"X = f(x)", "Y = f(y)", "X = f(x)", "Y = f(y)",
"X = f(x)", "Y = g(x)", "X = f(x)", "Y = g(x)",
"X = f(x)", "Y = g(y)", "X = f(x)", "Y = g(y)",
"X = f(y)", "Y = f(x)", "X = f(y)", "Y = f(x)",
"X = f(y)", "Y = f(y)", "X = f(y)", "Y = f(y)",
"X = f(y)", "Y = g(x)", "X = f(y)", "Y = g(x)",
"X = f(y)", "Y = g(y)", "X = f(y)", "Y = g(y)",
"X = g(x)", "Y = f(x)", "X = g(x)", "Y = f(x)",
"X = g(x)", "Y = f(y)", "X = g(x)", "Y = f(y)",
"X = g(x)", "Y = g(x)", "X = g(x)", "Y = g(x)",
"X = g(x)", "Y = g(y)", "X = g(x)", "Y = g(y)",
"X = g(y)", "Y = f(x)", "X = g(y)", "Y = f(x)",
"X = g(y)", "Y = f(y)", "X = g(y)", "Y = f(y)",
"X = g(y)", "Y = g(x)", "X = g(y)", "Y = g(x)",
"X = g(y)", "Y = g(y)"]); "X = g(y)", "Y = g(y)"]);
assert_prolog_success!(&mut wam, "?- f(r, X, X).", assert_prolog_success!(&mut wam, "?- f(r, X, X).",
["X = f(x)", ["X = f(x)",
@@ -1006,7 +1006,7 @@ fn test_queries_on_exceptions()
"X = y", "E = _2", "X = y", "E = _2",
"X = z", "E = _2", "X = z", "E = _2",
"X = _1", "E = handle_top(an_error_1)", "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)."); 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.", assert_prolog_success!(&mut wam, "?- catch(f(X), evaluation_error(E), true), E = zero_divisor.",
["E = zero_divisor", "X = _1"]); ["E = zero_divisor", "X = _1"]);
submit(&mut wam, "f(X) :- X is (5 rdiv 1) / 0."); 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.", assert_prolog_success!(&mut wam, "?- catch(f(X), evaluation_error(E), true), E = zero_divisor.",
["E = zero_divisor", "X = _1"]); ["E = zero_divisor", "X = _1"]);
submit(&mut wam, "f(X) :- X is 5.0 / 0."); 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.", assert_prolog_success!(&mut wam, "?- catch(f(X), evaluation_error(E), true), E = zero_divisor.",
["E = zero_divisor", "X = _1"]); ["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.", 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"]); ["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 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 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 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 rem -3, X = 1.", ["X = 1"]);
assert_prolog_success!(&mut wam, "?- X is 10 mod -3, X is -2.", ["X = -2"]); assert_prolog_success!(&mut wam, "?- X is 10 mod -3, X is -2.", ["X = -2"]);
} }