throw exception when predicate not found

This commit is contained in:
Mark Thom
2018-04-09 21:27:50 -06:00
parent fe481fedce
commit ed9cca0750
4 changed files with 20 additions and 199 deletions

View File

@@ -12,9 +12,9 @@ pub trait CopierTarget
fn deref(&self, Addr) -> Addr;
fn stack(&mut self) -> &mut AndStack;
// duplicate_term(L1, L2) uses Cheney's algorithm to copy the term at
// L1 to L2. forwarding_terms is kept to restore the innards of L1
// after it's been copied to L2.
// duplicate_term(L1, L2) uses Cheney's algorithm to copy the term
// at L1 to L2. trail is kept to restore the innards of L1 after
// it's been copied to L2.
fn duplicate_term(&mut self, a: Addr) where Self: IndexMut<usize, Output=HeapCellValue>
{
let mut trail: Vec<(Ref, HeapCellValue)>= Vec::new();
@@ -31,13 +31,13 @@ pub trait CopierTarget
match a.clone() {
Addr::Lis(a) => {
self[scan] = HeapCellValue::Addr(Addr::Lis(self.threshold()));
let hcv = self[a].clone();
self.push(hcv);
let hcv = self[a+1].clone();
self.push(hcv);
scan += 1;
},
Addr::HeapCell(_) | Addr::StackCell(_, _) => {

View File

@@ -210,11 +210,11 @@ pub struct MachineState {
pub(crate) type CallResult = Result<(), Vec<HeapCellValue>>;
fn predicate_existence_error(name: ClauseName, arity: usize) -> Vec<HeapCellValue>
fn predicate_existence_error(name: ClauseName, arity: usize, h: usize) -> Vec<HeapCellValue>
{
let name = HeapCellValue::Addr(Addr::Con(Constant::Atom(name)));
let mut error = functor!("existence_error", 2, [heap_atom!("procedure"), heap_str!(4)]);
let mut error = functor!("existence_error", 2, [heap_atom!("procedure"), heap_str!(3 + h)]);
error.append(&mut functor!("/", 2, [name, heap_integer!(arity)], Fixity::In));
error
@@ -238,7 +238,7 @@ pub(crate) trait CallPolicy: Any {
{
match idx.0.get() {
IndexPtr::Undefined =>
return Err(predicate_existence_error(name, arity)),
return Err(predicate_existence_error(name, arity, machine_st.heap.h)),
IndexPtr::Index(compiled_tl_index) => {
let module_name = idx.1;
@@ -258,7 +258,7 @@ pub(crate) trait CallPolicy: Any {
{
match idx.0.get() {
IndexPtr::Undefined =>
return Err(predicate_existence_error(name, arity)),
return Err(predicate_existence_error(name, arity, machine_st.heap.h)),
IndexPtr::Index(compiled_tl_index) => {
let module_name = idx.1;

View File

@@ -925,6 +925,13 @@ impl MachineState {
self.p = CodePtr::DirEntry(59, clause_name!("builtin"));
}
fn unwind_stack(&mut self) {
self.b = self.block;
self.or_stack.truncate(self.b);
self.fail = true;
}
fn throw_exception(&mut self, hcv: Vec<HeapCellValue>) {
let h = self.heap.h;
@@ -1535,12 +1542,8 @@ impl MachineState {
let addr = self.deref(self[temp_v!(1)].clone());
self.reset_block(addr);
},
&BuiltInInstruction::UnwindStack => {
self.b = self.block;
self.or_stack.truncate(self.b);
self.fail = true;
},
&BuiltInInstruction::UnwindStack =>
self.unwind_stack(),
&BuiltInInstruction::InternalCallN =>
self.handle_internal_call_n(call_policy, code_dirs),
&BuiltInInstruction::Fail => {

View File

@@ -359,8 +359,7 @@ fn test_queries_on_predicates() {
assert_prolog_failure!(&mut wam, "?- p(a, b, c).");
assert_prolog_success!(&mut wam, "?- p(a, b, C).", [["C = x"]]);
submit(&mut wam, "p(X) :- q(X). p(X) :- r(X).");
submit(&mut wam, "q(X) :- a.");
submit(&mut wam, "p(X) :- r(X).");
submit(&mut wam, "r(X) :- s(X, t). r(X) :- t(X, u).");
submit(&mut wam, "s(x, t).");
@@ -529,23 +528,6 @@ fn test_queries_on_cuts() {
submit(&mut wam, "b.");
assert_prolog_success!(&mut wam, "?- a(X).", [["X = c"]]);
wam.clear();
assert_prolog_failure!(&mut wam, "?- c(X).");
submit(&mut wam, "a(X) :- b, c(X), !. a(X) :- d(X).");
submit(&mut wam, "b.");
assert_prolog_failure!(&mut wam, "?- a(X).");
submit(&mut wam, "d(d).");
assert_prolog_success!(&mut wam, "?- a(X).", [["X = d"]]);
submit(&mut wam, "c(c).");
assert_prolog_success!(&mut wam, "?- a(X).", [["X = c"]]);
}
#[test]
@@ -605,170 +587,6 @@ fn test_queries_on_lists()
assert_prolog_failure!(&mut wam, "?- member([X, Y, Z], [a, [b, c], [b, b], [Z, x], [d, f]]).");
}
#[test]
fn test_queries_on_indexed_predicates()
{
let mut wam = Machine::new();
submit(&mut wam, "p(a) :- a.
p(b) :- b, f(X).
p(c) :- c, g(X).
p(f(a)) :- a.
p(g(b, c)) :- b.
p(g(b)) :- b.
p([a|b]) :- a.
p([]).
p(X) :- x.
p([c, d, e]).");
assert_prolog_failure!(&mut wam, "?- p(a).");
assert_prolog_failure!(&mut wam, "?- p(b).");
assert_prolog_failure!(&mut wam, "?- p(c).");
assert_prolog_failure!(&mut wam, "?- p(f(a)).");
assert_prolog_failure!(&mut wam, "?- p(g(b, X)).");
assert_prolog_failure!(&mut wam, "?- p(g(Y, X)).");
assert_prolog_failure!(&mut wam, "?- p(g(Y, c)).");
assert_prolog_failure!(&mut wam, "?- p(g(b)).");
assert_prolog_success!(&mut wam, "?- p([]).");
assert_prolog_success!(&mut wam, "?- p([c, d, e]).");
assert_prolog_success!(&mut wam, "?- p([c, d | X]).", [["X = [e]"]]);
assert_prolog_success!(&mut wam, "?- p([c|X]).", [["X = [d, e]"]]);
assert_prolog_success!(&mut wam, "?- p([Y|X]).", [["Y = c", "X = [d, e]"]]);
assert_prolog_success!(&mut wam, "?- p([Y|[d|Xs]]).", [["Xs = [e]", "Y = c"]]);
submit(&mut wam, "a.");
assert_prolog_success!(&mut wam, "?- p(a).");
assert_prolog_failure!(&mut wam, "?- p(b).");
assert_prolog_failure!(&mut wam, "?- p(c).");
assert_prolog_success!(&mut wam, "?- p(f(a)).");
assert_prolog_failure!(&mut wam, "?- p(g(b, X)).");
assert_prolog_failure!(&mut wam, "?- p(g(Y, X)).");
assert_prolog_failure!(&mut wam, "?- p(g(Y, c)).");
assert_prolog_failure!(&mut wam, "?- p(g(b)).");
assert_prolog_success!(&mut wam, "?- p([]).");
assert_prolog_success!(&mut wam, "?- p([c, d, e]).");
assert_prolog_success!(&mut wam, "?- p([c, d | X]).", [["X = [e]"]]);
assert_prolog_success!(&mut wam, "?- p([c|X]).", [["X = [d, e]"]]);
assert_prolog_success!(&mut wam, "?- p([Y|X]).", [["X = b", "Y = a"],
["Y = c", "X = [d, e]"]]);
assert_prolog_success!(&mut wam, "?- p([Y|[d|Xs]]).", [["Xs = [e]", "Y = c"]]);
submit(&mut wam, "b.");
submit(&mut wam, "f(x).");
assert_prolog_success!(&mut wam, "?- p(a).");
assert_prolog_success!(&mut wam, "?- p(b).");
assert_prolog_failure!(&mut wam, "?- p(c).");
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(b)).");
assert_prolog_success!(&mut wam, "?- p([]).");
assert_prolog_success!(&mut wam, "?- p([c, d, e]).");
assert_prolog_success!(&mut wam, "?- p([c, d | X]).", [["X = [e]"]]);
assert_prolog_success!(&mut wam, "?- p([c|X]).", [["X = [d, e]"]]);
assert_prolog_success!(&mut wam, "?- p([Y|X]).", [["X = b", "Y = a"],
["Y = c", "X = [d, e]"]]);
assert_prolog_success!(&mut wam, "?- p([Y|[d|Xs]]).", [["Xs = [e]", "Y = c"]]);
submit(&mut wam, "c.");
submit(&mut wam, "g(X).");
assert_prolog_success!(&mut wam, "?- p(a).");
assert_prolog_success!(&mut wam, "?- p(b).");
assert_prolog_success!(&mut wam, "?- p(c).");
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(b)).");
assert_prolog_success!(&mut wam, "?- p([]).");
assert_prolog_success!(&mut wam, "?- p([c, d, e]).");
assert_prolog_success!(&mut wam, "?- p([c, d | X]).", [["X = [e]"]]);
assert_prolog_success!(&mut wam, "?- p([c|X]).", [["X = [d, e]"]]);
assert_prolog_success!(&mut wam, "?- p([Y|X]).", [["X = b", "Y = a"],
["Y = c", "X = [d, e]"]]);
assert_prolog_success!(&mut wam, "?- p([Y|[d|Xs]]).", [["Xs = [e]", "Y = c"]]);
assert_prolog_failure!(&mut wam, "?- p(blah).");
submit(&mut wam, "x.");
assert_prolog_success!(&mut wam, "?- p(a).");
assert_prolog_success!(&mut wam, "?- p(b).");
assert_prolog_success!(&mut wam, "?- p(c).");
assert_prolog_success!(&mut wam, "?- p(true(a)).");
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_prolog_success!(&mut wam, "?- p(g(b)).");
assert_prolog_success!(&mut wam, "?- p([]).");
assert_prolog_success!(&mut wam, "?- p([c, d, e]).");
assert_prolog_success!(&mut wam, "?- p([c, d | X]).", [["X = _1"],
["X = [e]"]]);
assert_prolog_success!(&mut wam, "?- p([c|X]).", [["X = _1"],
["X = [d, e]"]]);
assert_prolog_success!(&mut wam, "?- p([Y|X]).", [["X = b", "Y = a"],
["X = _1", "Y = _0"],
["Y = c", "X = [d, e]"]]);
assert_prolog_success!(&mut wam, "?- p([Y|[d|Xs]]).", [["Xs = _1", "Y = _2"],
["Xs = [e]", "Y = c"]]);
assert_prolog_success!(&mut wam, "?- p(blah).");
submit(&mut wam, "ind_call(or(X, Y)) :- ind_call(X).
ind_call(trace) :- trace.
ind_call(or(X, Y)) :- ind_call(Y).
ind_call(notrace) :- notrace.
ind_call(nl) :- nl.
ind_call(X) :- builtin(X).
ind_call(X) :- extern(X).
ind_call(ind_call(X)) :- ind_call(X).
ind_call(repeat).
ind_call(repeat) :- ind_call(repeat).
ind_call(false).");
assert_prolog_success!(&mut wam, "?- ind_call(repeat).");
assert_prolog_success!(&mut wam, "?- ind_call(false).");
assert_prolog_success!(&mut wam, "?- ind_call(ind_call(repeat)).");
assert_prolog_success!(&mut wam, "?- ind_call(ind_call(false)).");
assert_prolog_failure!(&mut wam, "?- ind_call(notrace).");
assert_prolog_failure!(&mut wam, "?- ind_call(nl).");
assert_prolog_failure!(&mut wam, "?- ind_call(builtin(X)).");
assert_prolog_failure!(&mut wam, "?- ind_call(extern(X)).");
submit(&mut wam, "notrace.");
submit(&mut wam, "nl.");
assert_prolog_success!(&mut wam, "?- ind_call(repeat).");
assert_prolog_success!(&mut wam, "?- ind_call(false).");
assert_prolog_success!(&mut wam, "?- ind_call(ind_call(repeat)).");
assert_prolog_success!(&mut wam, "?- ind_call(ind_call(false)).");
assert_prolog_success!(&mut wam, "?- ind_call(notrace).");
assert_prolog_success!(&mut wam, "?- ind_call(nl).");
assert_prolog_failure!(&mut wam, "?- ind_call(builtin(X)).");
assert_prolog_failure!(&mut wam, "?- ind_call(extern(X)).");
submit(&mut wam, "builtin(X).");
submit(&mut wam, "extern(x).");
assert_prolog_success!(&mut wam, "?- ind_call(repeat).");
assert_prolog_success!(&mut wam, "?- ind_call(false).");
assert_prolog_success!(&mut wam, "?- ind_call(ind_call(repeat)).");
assert_prolog_success!(&mut wam, "?- ind_call(ind_call(false)).");
assert_prolog_success!(&mut wam, "?- ind_call(notrace).");
assert_prolog_success!(&mut wam, "?- ind_call(nl).");
assert_prolog_success!(&mut wam, "?- ind_call(builtin(X)).", [["X = _1"]]);
assert_prolog_success!(&mut wam, "?- ind_call(extern(X)).", [["X = _1"]]);
}
#[test]
fn test_queries_on_conjuctive_queries() {
let mut wam = Machine::new();