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

@@ -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 => {