From: Mark Thom Date: Sun, 20 May 2018 22:26:52 +0000 (-0600) Subject: fix offsetting of heap in existence errors X-Git-Tag: v0.8.110~459 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=4608c4fe5829dbf37151f31c3200f33c6b76fbbb;p=scryer-prolog.git fix offsetting of heap in existence errors --- diff --git a/src/prolog/copier.rs b/src/prolog/copier.rs index 3099cb8c..b16ba5ad 100644 --- a/src/prolog/copier.rs +++ b/src/prolog/copier.rs @@ -61,6 +61,7 @@ pub(crate) trait CopierTarget } list_redirect.insert(a, self.threshold()); + self[scan] = HeapCellValue::Addr(Addr::Lis(self.threshold())); let hcv = self[a].clone(); diff --git a/src/prolog/machine/machine_errors.rs b/src/prolog/machine/machine_errors.rs index c232bb4d..a3cb86da 100644 --- a/src/prolog/machine/machine_errors.rs +++ b/src/prolog/machine/machine_errors.rs @@ -4,9 +4,79 @@ use prolog::num::bigint::BigInt; use std::rc::Rc; -pub(super) type MachineError = Vec; pub(super) type MachineStub = Vec; +#[derive(Clone, Copy)] +enum ErrorProvenance { + Constructed, // if constructed, offset the addresses. + Received // otherwise, preserve the addresses. +} + +pub(super) struct MachineError { + stub: MachineStub, + from: ErrorProvenance +} + +impl MachineError { + pub(super) fn functor_stub(name: ClauseName, arity: usize) -> MachineStub { + let name = HeapCellValue::Addr(Addr::Con(Constant::Atom(name))); + functor!("/", 2, [name, heap_integer!(arity)], Fixity::In) + } + + pub(super) fn evaluation_error(eval_error: EvalError) -> Self { + let stub = functor!("evaluation_error", 1, [heap_atom!(eval_error.as_str())]); + MachineError { stub, from: ErrorProvenance::Received } + } + + pub(super) fn type_error(valid_type: ValidType, culprit: Addr) -> Self { + let stub = functor!("type_error", 2, [heap_atom!(valid_type.as_str()), + HeapCellValue::Addr(culprit)]); + + MachineError { stub, from: ErrorProvenance::Received } + } + + pub(super) fn existence_error(h: usize, name: ClauseName, arity: usize) -> Self { + let mut stub = functor!("existence_error", 2, [heap_atom!("procedure"), heap_str!(3 + h)]); + stub.append(&mut Self::functor_stub(name, arity)); + + MachineError { stub, from: ErrorProvenance::Constructed } + } + + pub(super) fn domain_error(error: DomainError, culprit: Addr) -> Self { + let stub = functor!("domain_error", 2, [heap_atom!(error.as_str()), + HeapCellValue::Addr(culprit)]); + MachineError { stub, from: ErrorProvenance::Received } + } + + pub(super) fn instantiation_error() -> Self { + let stub = functor!("instantiation_error"); + MachineError { stub, from: ErrorProvenance::Received } + } + + pub(super) fn representation_error(flag: RepFlag) -> Self { + let stub = functor!("representation_error", 1, [heap_atom!(flag.as_str())]); + MachineError { stub, from: ErrorProvenance::Received } + } + + fn into_iter(self, offset: usize) -> Box> { + match self.from { + ErrorProvenance::Constructed => + Box::new(self.stub.into_iter().map(move |hcv| { + match hcv { + HeapCellValue::Addr(addr) => HeapCellValue::Addr(addr + offset), + hcv => hcv + } + })), + ErrorProvenance::Received => + Box::new(self.stub.into_iter()) + } + } + + fn len(&self) -> usize { + self.stub.len() + } +} + // from 7.12.2 b) of 13211-1:1995 #[derive(Clone, Copy)] pub enum ValidType { @@ -119,32 +189,32 @@ pub(super) enum CycleSearchResult { impl MachineState { // see 8.4.3 of Draft Technical Corrigendum 2. - pub(super) fn check_sort_errors(&self) -> Result<(), MachineError> { - let stub = self.functor_stub(clause_name!("sort"), 2); + pub(super) fn check_sort_errors(&self) -> CallResult { + let stub = MachineError::functor_stub(clause_name!("sort"), 2); let list = self.store(self.deref(self[temp_v!(1)].clone())); let sorted = self.store(self.deref(self[temp_v!(2)].clone())); match self.detect_cycles(list.clone()) { CycleSearchResult::PartialList(..) => - Err(self.error_form(self.instantiation_error(), stub.clone())), + return Err(self.error_form(MachineError::instantiation_error(), stub)), CycleSearchResult::NotList => - Err(self.error_form(self.type_error(ValidType::List, list), stub.clone())), - _ => Ok(()) - }?; + return Err(self.error_form(MachineError::type_error(ValidType::List, list), stub)), + _ => {} + }; match self.detect_cycles(sorted.clone()) { CycleSearchResult::NotList if !sorted.is_ref() => - Err(self.error_form(self.type_error(ValidType::List, sorted), stub)), + Err(self.error_form(MachineError::type_error(ValidType::List, sorted), stub)), _ => Ok(()) } } - fn check_for_list_pairs(&self, list: Addr) -> Result<(), MachineError> { - let stub = self.functor_stub(clause_name!("keysort"), 2); + fn check_for_list_pairs(&self, list: Addr) -> CallResult { + let stub = MachineError::functor_stub(clause_name!("keysort"), 2); match self.detect_cycles(list.clone()) { CycleSearchResult::NotList if !list.is_ref() => - Err(self.error_form(self.type_error(ValidType::List, list), stub)), + Err(self.error_form(MachineError::type_error(ValidType::List, list), stub)), _ => { let mut addr = list; @@ -158,8 +228,8 @@ impl MachineState { if name.as_str() == "-" => break, HeapCellValue::Addr(Addr::HeapCell(_)) => break, HeapCellValue::Addr(Addr::StackCell(..)) => break, - _ => return Err(self.error_form(self.type_error(ValidType::Pair, - Addr::HeapCell(l)), + _ => return Err(self.error_form(MachineError::type_error(ValidType::Pair, + Addr::HeapCell(l)), stub)) }; } @@ -173,70 +243,35 @@ impl MachineState { } // see 8.4.4 of Draft Technical Corrigendum 2. - pub(super) fn check_keysort_errors(&self) -> Result<(), MachineError> { - let stub = self.functor_stub(clause_name!("keysort"), 2); + pub(super) fn check_keysort_errors(&self) -> CallResult { + let stub = MachineError::functor_stub(clause_name!("keysort"), 2); let pairs = self.store(self.deref(self[temp_v!(1)].clone())); let sorted = self.store(self.deref(self[temp_v!(2)].clone())); match self.detect_cycles(pairs.clone()) { CycleSearchResult::PartialList(..) => - Err(self.error_form(self.instantiation_error(), stub)), + Err(self.error_form(MachineError::instantiation_error(), stub)), CycleSearchResult::NotList => - Err(self.error_form(self.type_error(ValidType::List, pairs), stub)), + Err(self.error_form(MachineError::type_error(ValidType::List, pairs), stub)), _ => Ok(()) }?; self.check_for_list_pairs(sorted) } - pub(super) fn functor_stub(&self, name: ClauseName, arity: usize) -> MachineStub { - let name = HeapCellValue::Addr(Addr::Con(Constant::Atom(name))); - functor!("/", 2, [name, heap_integer!(arity)], Fixity::In) - } - - pub(super) fn evaluation_error(&self, eval_error: EvalError) -> MachineError { - functor!("evaluation_error", 1, [heap_atom!(eval_error.as_str())]) - } - - pub(super) fn type_error(&self, valid_type: ValidType, culprit: Addr) -> MachineError { - functor!("type_error", 2, [heap_atom!(valid_type.as_str()), HeapCellValue::Addr(culprit)]) - } - - pub(super) fn existence_error(&self, name: ClauseName, arity: usize) -> MachineError { - let h = self.heap.h; - - let mut error = functor!("existence_error", 2, [heap_atom!("procedure"), heap_str!(3 + h)]); - error.append(&mut self.functor_stub(name, arity)); - - error - } - - pub(super) fn domain_error(&self, error: DomainError, culprit: Addr) -> MachineError { - functor!("domain_error", 2, [heap_atom!(error.as_str()), HeapCellValue::Addr(culprit)]) - } - - pub(super) fn instantiation_error(&self) -> MachineError { - functor!("instantiation_error") - } - - pub(super) fn representation_error(&self, flag: RepFlag) -> MachineError { - functor!("representation_error", 1, [heap_atom!(flag.as_str())]) - } - - pub(super) fn error_form(&self, err: MachineError, src: MachineStub) -> MachineError { + pub(super) fn error_form(&self, err: MachineError, src: MachineStub) -> MachineStub { let h = self.heap.h; + let mut stub = vec![HeapCellValue::NamedStr(2, clause_name!("error"), None), + HeapCellValue::Addr(Addr::HeapCell(h + 3)), + HeapCellValue::Addr(Addr::HeapCell(h + 3 + err.len()))]; - let mut error_form = vec![HeapCellValue::NamedStr(2, clause_name!("error"), None), - HeapCellValue::Addr(Addr::HeapCell(h + 3)), - HeapCellValue::Addr(Addr::HeapCell(h + 3 + err.len()))]; - - error_form.extend(err.into_iter()); - error_form.extend(src.into_iter()); + stub.extend(err.into_iter(3)); + stub.extend(src.into_iter()); - error_form + stub } - pub(super) fn throw_exception(&mut self, err: MachineError) { + pub(super) fn throw_exception(&mut self, err: MachineStub) { let h = self.heap.h; self.ball.boundary = 0; diff --git a/src/prolog/machine/machine_state.rs b/src/prolog/machine/machine_state.rs index 2dd2ba59..5ccf181c 100644 --- a/src/prolog/machine/machine_state.rs +++ b/src/prolog/machine/machine_state.rs @@ -365,10 +365,15 @@ pub(crate) trait CallPolicy: Any { fn try_call(&mut self, machine_st: &mut MachineState, name: ClauseName, arity: usize, idx: CodeIndex) -> CallResult - { + { match idx.0.borrow().0 { - IndexPtr::Undefined => - return Err(machine_st.existence_error(name, arity)), + IndexPtr::Undefined => { + let stub = MachineError::functor_stub(name.clone(), arity); + let h = machine_st.heap.h; + + return Err(machine_st.error_form(MachineError::existence_error(h, name, arity), + stub)); + }, IndexPtr::Index(compiled_tl_index) => { let module_name = idx.0.borrow().1.clone(); @@ -387,8 +392,13 @@ pub(crate) trait CallPolicy: Any { -> CallResult { match idx.0.borrow().0 { - IndexPtr::Undefined => - return Err(machine_st.existence_error(name, arity)), + IndexPtr::Undefined => { + let stub = MachineError::functor_stub(name.clone(), arity); + let h = machine_st.heap.h; + + return Err(machine_st.error_form(MachineError::existence_error(h, name, arity), + stub)); + }, IndexPtr::Index(compiled_tl_index) => { let module_name = idx.0.borrow().1.clone(); @@ -475,7 +485,7 @@ pub(crate) trait CallPolicy: Any { &BuiltInClauseType::Sort => { machine_st.check_sort_errors()?; - let stub = machine_st.functor_stub(clause_name!("sort"), 2); + let stub = MachineError::functor_stub(clause_name!("sort"), 2); let mut list = machine_st.try_from_list(temp_v!(1), stub)?; list.sort_unstable_by(|a1, a2| machine_st.compare_term_test(a1, a2)); @@ -491,7 +501,7 @@ pub(crate) trait CallPolicy: Any { &BuiltInClauseType::KeySort => { machine_st.check_keysort_errors()?; - let stub = machine_st.functor_stub(clause_name!("keysort"), 2); + let stub = MachineError::functor_stub(clause_name!("keysort"), 2); let mut list = machine_st.try_from_list(temp_v!(1), stub)?; let mut key_pairs = Vec::new(); @@ -544,11 +554,19 @@ pub(crate) trait CallPolicy: Any { if let Some(idx) = code_dirs.get(name.clone(), arity, user) { self.context_call(machine_st, name, arity, idx)?; } else { - return Err(machine_st.existence_error(name, arity)); + let h = machine_st.heap.h; + let stub = MachineError::functor_stub(clause_name!("call"), arity + 1); + return Err(machine_st.error_form(MachineError::existence_error(h, name, arity), + stub)); }, - ClauseType::System(_) => - return Err(machine_st.type_error(ValidType::Callable, - Addr::Con(Constant::Atom(name)))) + ClauseType::System(_) => { + let name = Addr::Con(Constant::Atom(name)); + let stub = MachineError::functor_stub(clause_name!("call"), arity + 1); + + return Err(machine_st.error_form(MachineError::type_error(ValidType::Callable, + name), + stub)); + } }; } diff --git a/src/prolog/machine/machine_state_impl.rs b/src/prolog/machine/machine_state_impl.rs index 5748a437..cb1799ad 100644 --- a/src/prolog/machine/machine_state_impl.rs +++ b/src/prolog/machine/machine_state_impl.rs @@ -323,7 +323,7 @@ impl MachineState { }; } - pub(super) fn get_number(&self, at: &ArithmeticTerm) -> Result { + pub(super) fn get_number(&self, at: &ArithmeticTerm) -> Result { match at { &ArithmeticTerm::Reg(r) => self.arith_eval_by_metacall(r), &ArithmeticTerm::Interm(i) => Ok(self.interms[i-1].clone()), @@ -332,7 +332,7 @@ impl MachineState { } fn get_rational(&self, at: &ArithmeticTerm, caller: &MachineStub) - -> Result>, MachineError> + -> Result>, MachineStub> { let n = self.get_number(at)?; @@ -342,7 +342,7 @@ impl MachineState { if let Some(r) = Ratio::from_float(fl.into_inner()) { Ok(Rc::new(r)) } else { - Err(self.error_form(self.instantiation_error(), caller.clone())) + Err(self.error_form(MachineError::instantiation_error(), caller.clone())) }, Number::Integer(bi) => Ok(Rc::new(Ratio::from_integer((*bi).clone()))) @@ -361,11 +361,11 @@ impl MachineState { Rc::new(BigInt::from_signed_bytes_le(&f(&u_n1, &u_n2).to_bytes_le())) } - pub(super) fn arith_eval_by_metacall(&self, r: RegType) -> Result + pub(super) fn arith_eval_by_metacall(&self, r: RegType) -> Result { let a = self[r].clone(); - let caller = self.functor_stub(clause_name!("(is)"), 2); + let caller = MachineError::functor_stub(clause_name!("(is)"), 2); let mut interms: Vec = Vec::with_capacity(64); for heap_val in self.post_order_iter(a) { @@ -395,7 +395,8 @@ impl MachineState { "xor" => interms.push(Number::Integer(self.xor(a1, a2)?)), "mod" => interms.push(Number::Integer(self.modulus(a1, a2)?)), "rem" => interms.push(Number::Integer(self.remainder(a1, a2)?)), - _ => return Err(self.error_form(self.instantiation_error(), caller)) + _ => return Err(self.error_form(MachineError::instantiation_error(), + caller)) } }, HeapCellValue::NamedStr(1, name, Some(Fixity::Pre)) => { @@ -403,13 +404,14 @@ impl MachineState { match name.as_str() { "-" => interms.push(- a1), - _ => return Err(self.error_form(self.instantiation_error(), caller)) + _ => return Err(self.error_form(MachineError::instantiation_error(), + caller)) } }, HeapCellValue::Addr(Addr::Con(Constant::Number(n))) => interms.push(n), _ => - return Err(self.error_form(self.instantiation_error(), caller)) + return Err(self.error_form(MachineError::instantiation_error(), caller)) } }; @@ -417,75 +419,75 @@ impl MachineState { } fn rdiv(&self, r1: Rc>, r2: Rc>) - -> Result>, MachineError> + -> Result>, MachineStub> { - let stub = self.functor_stub(clause_name!("(rdiv)"), 2); + let stub = MachineError::functor_stub(clause_name!("(rdiv)"), 2); if *r2 == Ratio::zero() { - Err(self.error_form(self.evaluation_error(EvalError::ZeroDivisor), stub)) + Err(self.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub)) } else { Ok(Rc::new(&*r1 / &*r2)) } } - fn fidiv(&self, n1: Number, n2: Number) -> Result, MachineError> + fn fidiv(&self, n1: Number, n2: Number) -> Result, MachineStub> { - let stub = self.functor_stub(clause_name!("(div)"), 2); + let stub = MachineError::functor_stub(clause_name!("(div)"), 2); match (n1, n2) { (Number::Integer(n1), Number::Integer(n2)) => if *n2 == BigInt::zero() { - Err(self.error_form(self.evaluation_error(EvalError::ZeroDivisor), stub)) + Err(self.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub)) } else { Ok(Rc::new(n1.div_floor(&n2))) }, (Number::Integer(_), n2) => - Err(self.error_form(self.type_error(ValidType::Integer, + Err(self.error_form(MachineError::type_error(ValidType::Integer, Addr::Con(Constant::Number(n2))), stub)), (n1, _) => - Err(self.error_form(self.type_error(ValidType::Integer, + Err(self.error_form(MachineError::type_error(ValidType::Integer, Addr::Con(Constant::Number(n1))), stub)) } } - fn idiv(&self, n1: Number, n2: Number) -> Result, MachineError> + fn idiv(&self, n1: Number, n2: Number) -> Result, MachineStub> { - let stub = self.functor_stub(clause_name!("(//)"), 2); + let stub = MachineError::functor_stub(clause_name!("(//)"), 2); match (n1, n2) { (Number::Integer(n1), Number::Integer(n2)) => if *n2 == BigInt::zero() { - Err(self.error_form(self.evaluation_error(EvalError::ZeroDivisor), stub)) + Err(self.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub)) } else { Ok(Rc::new(&*n1 / &*n2)) }, (Number::Integer(_), n2) => - Err(self.error_form(self.type_error(ValidType::Integer, + Err(self.error_form(MachineError::type_error(ValidType::Integer, Addr::Con(Constant::Number(n2))), stub)), (n1, _) => - Err(self.error_form(self.type_error(ValidType::Integer, + Err(self.error_form(MachineError::type_error(ValidType::Integer, Addr::Con(Constant::Number(n1))), stub)) } } - fn div(&self, n1: Number, n2: Number) -> Result + fn div(&self, n1: Number, n2: Number) -> Result { - let stub = self.functor_stub(clause_name!("(/)"), 2); + let stub = MachineError::functor_stub(clause_name!("(/)"), 2); if n2.is_zero() { - Err(self.error_form(self.evaluation_error(EvalError::ZeroDivisor), stub)) + Err(self.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub)) } else { Ok(n1 / n2) } } - fn shr(&self, n1: Number, n2: Number) -> Result, MachineError> + fn shr(&self, n1: Number, n2: Number) -> Result, MachineStub> { - let stub = self.functor_stub(clause_name!("(>>)"), 2); + let stub = MachineError::functor_stub(clause_name!("(>>)"), 2); match (n1, n2) { (Number::Integer(n1), Number::Integer(n2)) => @@ -494,19 +496,19 @@ impl MachineState { _ => Ok(Rc::new(&*n1 >> usize::max_value())) }, (Number::Integer(_), n2) => - Err(self.error_form(self.type_error(ValidType::Integer, + Err(self.error_form(MachineError::type_error(ValidType::Integer, Addr::Con(Constant::Number(n2))), stub)), (n1, _) => - Err(self.error_form(self.type_error(ValidType::Integer, + Err(self.error_form(MachineError::type_error(ValidType::Integer, Addr::Con(Constant::Number(n1))), stub)) } } - fn shl(&self, n1: Number, n2: Number) -> Result, MachineError> + fn shl(&self, n1: Number, n2: Number) -> Result, MachineStub> { - let stub = self.functor_stub(clause_name!("(<<)"), 2); + let stub = MachineError::functor_stub(clause_name!("(<<)"), 2); match (n1, n2) { (Number::Integer(n1), Number::Integer(n2)) => @@ -515,110 +517,112 @@ impl MachineState { _ => Ok(Rc::new(&*n1 << usize::max_value())) }, (Number::Integer(_), n2) => - Err(self.error_form(self.type_error(ValidType::Integer, + Err(self.error_form(MachineError::type_error(ValidType::Integer, Addr::Con(Constant::Number(n2))), stub)), (n1, _) => - Err(self.error_form(self.type_error(ValidType::Integer, + Err(self.error_form(MachineError::type_error(ValidType::Integer, Addr::Con(Constant::Number(n1))), stub)) } } - fn xor(&self, n1: Number, n2: Number) -> Result, MachineError> + fn xor(&self, n1: Number, n2: Number) -> Result, MachineStub> { - let stub = self.functor_stub(clause_name!("(xor)"), 2); + let stub = MachineError::functor_stub(clause_name!("(xor)"), 2); match (n1, n2) { (Number::Integer(n1), Number::Integer(n2)) => Ok(self.signed_bitwise_op(&*n1, &*n2, |u_n1, u_n2| u_n1 ^ u_n2)), (Number::Integer(_), n2) => - Err(self.error_form(self.type_error(ValidType::Integer, + Err(self.error_form(MachineError::type_error(ValidType::Integer, Addr::Con(Constant::Number(n2))), stub)), (n1, _) => - Err(self.error_form(self.type_error(ValidType::Integer, + Err(self.error_form(MachineError::type_error(ValidType::Integer, Addr::Con(Constant::Number(n1))), stub)) } } - fn and(&self, n1: Number, n2: Number) -> Result, MachineError> + fn and(&self, n1: Number, n2: Number) -> Result, MachineStub> { - let stub = self.functor_stub(clause_name!("(/\\)"), 2); + let stub = MachineError::functor_stub(clause_name!("(/\\)"), 2); match (n1, n2) { (Number::Integer(n1), Number::Integer(n2)) => Ok(self.signed_bitwise_op(&*n1, &*n2, |u_n1, u_n2| u_n1 & u_n2)), (Number::Integer(_), n2) => - Err(self.error_form(self.type_error(ValidType::Integer, + Err(self.error_form(MachineError::type_error(ValidType::Integer, Addr::Con(Constant::Number(n2))), stub)), (n1, _) => - Err(self.error_form(self.type_error(ValidType::Integer, + Err(self.error_form(MachineError::type_error(ValidType::Integer, Addr::Con(Constant::Number(n1))), stub)) } } - fn modulus(&self, n1: Number, n2: Number) -> Result, MachineError> + fn modulus(&self, n1: Number, n2: Number) -> Result, MachineStub> { - let stub = self.functor_stub(clause_name!("(mod)"), 2); + let stub = MachineError::functor_stub(clause_name!("(mod)"), 2); match (n1, n2) { (Number::Integer(n1), Number::Integer(n2)) => if *n2 == BigInt::zero() { - Err(self.error_form(self.evaluation_error(EvalError::ZeroDivisor), stub)) + Err(self.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), + stub)) } else { Ok(Rc::new(n1.mod_floor(&n2))) }, (Number::Integer(_), n2) => - Err(self.error_form(self.type_error(ValidType::Integer, - Addr::Con(Constant::Number(n2))), + Err(self.error_form(MachineError::type_error(ValidType::Integer, + Addr::Con(Constant::Number(n2))), stub)), (n1, _) => - Err(self.error_form(self.type_error(ValidType::Integer, - Addr::Con(Constant::Number(n1))), + Err(self.error_form(MachineError::type_error(ValidType::Integer, + Addr::Con(Constant::Number(n1))), stub)) } } - fn remainder(&self, n1: Number, n2: Number) -> Result, MachineError> + fn remainder(&self, n1: Number, n2: Number) -> Result, MachineStub> { - let stub = self.functor_stub(clause_name!("(rem)"), 2); + let stub = MachineError::functor_stub(clause_name!("(rem)"), 2); match (n1, n2) { (Number::Integer(n1), Number::Integer(n2)) => if *n2 == BigInt::zero() { - Err(self.error_form(self.evaluation_error(EvalError::ZeroDivisor), stub)) + Err(self.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), + stub)) } else { Ok(Rc::new(&*n1 % &*n2)) }, (Number::Integer(_), n2) => - Err(self.error_form(self.type_error(ValidType::Integer, - Addr::Con(Constant::Number(n2))), + Err(self.error_form(MachineError::type_error(ValidType::Integer, + Addr::Con(Constant::Number(n2))), stub)), (n1, _) => - Err(self.error_form(self.type_error(ValidType::Integer, - Addr::Con(Constant::Number(n1))), + Err(self.error_form(MachineError::type_error(ValidType::Integer, + Addr::Con(Constant::Number(n1))), stub)) } } - fn or(&self, n1: Number, n2: Number) -> Result, MachineError> + fn or(&self, n1: Number, n2: Number) -> Result, MachineStub> { - let stub = self.functor_stub(clause_name!("(\\/)"), 2); + let stub = MachineError::functor_stub(clause_name!("(\\/)"), 2); match (n1, n2) { (Number::Integer(n1), Number::Integer(n2)) => Ok(self.signed_bitwise_op(&*n1, &*n2, |u_n1, u_n2| u_n1 & u_n2)), (Number::Integer(_), n2) => - Err(self.error_form(self.type_error(ValidType::Integer, - Addr::Con(Constant::Number(n2))), + Err(self.error_form(MachineError::type_error(ValidType::Integer, + Addr::Con(Constant::Number(n2))), stub)), (n1, _) => - Err(self.error_form(self.type_error(ValidType::Integer, - Addr::Con(Constant::Number(n1))), + Err(self.error_form(MachineError::type_error(ValidType::Integer, + Addr::Con(Constant::Number(n1))), stub)) } } @@ -647,7 +651,7 @@ impl MachineState { self.p += 1; }, &ArithmeticInstruction::RDiv(ref a1, ref a2, t) => { - let stub = self.functor_stub(clause_name!("(rdiv)"), 2); + let stub = MachineError::functor_stub(clause_name!("(rdiv)"), 2); let r1 = try_or_fail!(self, self.get_rational(a1, &stub)); let r2 = try_or_fail!(self, self.get_rational(a2, &stub)); @@ -1067,7 +1071,7 @@ impl MachineState { pub(super) fn setup_call_n(&mut self, arity: usize) -> Option { - let stub = self.functor_stub(clause_name!("call"), arity + 1); + let stub = MachineError::functor_stub(clause_name!("call"), arity + 1); let addr = self.store(self.deref(self.registers[arity].clone())); let (name, narity) = match addr { @@ -1077,7 +1081,7 @@ impl MachineState { if let HeapCellValue::NamedStr(narity, name, _) = result { if narity + arity > 63 { let representation_error = - self.error_form(self.representation_error(RepFlag::MaxArity), stub); + self.error_form(MachineError::representation_error(RepFlag::MaxArity), stub); self.throw_exception(representation_error); return None; @@ -1099,13 +1103,13 @@ impl MachineState { }, Addr::Con(Constant::Atom(name)) => (name, 0), Addr::HeapCell(_) | Addr::StackCell(_, _) => { - let instantiation_error = self.error_form(self.instantiation_error(), stub); + let instantiation_error = self.error_form(MachineError::instantiation_error(), stub); self.throw_exception(instantiation_error); return None; }, _ => { - let type_error = self.error_form(self.type_error(ValidType::Callable, addr), stub); + let type_error = self.error_form(MachineError::type_error(ValidType::Callable, addr), stub); self.throw_exception(type_error); return None; @@ -1169,19 +1173,19 @@ impl MachineState { // arg(+N, +Term, ?Arg) pub(super) fn try_arg(&mut self) -> CallResult { - let stub = self.functor_stub(clause_name!("arg"), 3); + let stub = MachineError::functor_stub(clause_name!("arg"), 3); let n = self.store(self.deref(self[temp_v!(1)].clone())); match n { Addr::HeapCell(_) | Addr::StackCell(..) => // 8.5.2.3 a) - return Err(self.error_form(self.instantiation_error(), stub)), + return Err(self.error_form(MachineError::instantiation_error(), stub)), Addr::Con(Constant::Number(Number::Integer(n))) => { if n.is_negative() { // 8.5.2.3 e) let n = Addr::Con(Constant::Number(Number::Integer(n))); - return Err(self.error_form(self.domain_error(DomainError::NotLessThanZero, - n), - stub)); + let dom_err = MachineError::domain_error(DomainError::NotLessThanZero, n); + + return Err(self.error_form(dom_err, stub)); } let n = match n.to_usize() { @@ -1196,7 +1200,7 @@ impl MachineState { match term { Addr::HeapCell(_) | Addr::StackCell(..) => // 8.5.2.3 b) - return Err(self.error_form(self.instantiation_error(), stub)), + return Err(self.error_form(MachineError::instantiation_error(), stub)), Addr::Str(o) => match self.heap[o].clone() { HeapCellValue::NamedStr(arity, _, _) if 1 <= n && n <= arity => { @@ -1217,14 +1221,14 @@ impl MachineState { self.fail = true; }, _ => // 8.5.2.3 d) - return Err(self.error_form(self.type_error(ValidType::Compound, term), + return Err(self.error_form(MachineError::type_error(ValidType::Compound, term), stub)) } }, _ => // 8.5.2.3 c) - return Err(self.error_form(self.type_error(ValidType::Integer, n), stub)) + return Err(self.error_form(MachineError::type_error(ValidType::Integer, n), stub)) } Ok(()) @@ -1482,7 +1486,7 @@ impl MachineState { } pub(super) fn try_functor(&mut self) -> CallResult { - let stub = self.functor_stub(clause_name!("functor"), 3); + let stub = MachineError::functor_stub(clause_name!("functor"), 3); let a1 = self.store(self.deref(self[temp_v!(1)].clone())); match a1.clone() { @@ -1501,7 +1505,7 @@ impl MachineState { let arity = self.store(self.deref(self[temp_v!(3)].clone())); if name.is_ref() || arity.is_ref() { // 8.5.1.3 a) & 8.5.1.3 b) - return Err(self.error_form(self.instantiation_error(), stub)); + return Err(self.error_form(MachineError::instantiation_error(), stub)); } if let Addr::Con(Constant::Number(Number::Integer(arity))) = arity { @@ -1514,14 +1518,14 @@ impl MachineState { }; if arity > MAX_ARITY as isize { + let rep_err = MachineError::representation_error(RepFlag::MaxArity); // 8.5.1.3 f) - return Err(self.error_form(self.representation_error(RepFlag::MaxArity), - stub)); + return Err(self.error_form(rep_err, stub)); } else if arity < 0 { // 8.5.1.3 g) - return Err(self.error_form(self.domain_error(DomainError::NotLessThanZero, - Addr::Con(integer!(arity))), - stub)); + let dom_err = MachineError::domain_error(DomainError::NotLessThanZero, + Addr::Con(integer!(arity))); + return Err(self.error_form(dom_err, stub)); } match name { @@ -1544,15 +1548,15 @@ impl MachineState { self.unify(a1, f_a); }, Addr::Con(_) => - return Err(self.error_form(self.type_error(ValidType::Atom, name), + return Err(self.error_form(MachineError::type_error(ValidType::Atom, name), stub)), // 8.5.1.3 e) _ => - return Err(self.error_form(self.type_error(ValidType::Atomic, name), + return Err(self.error_form(MachineError::type_error(ValidType::Atomic, name), stub)) // 8.5.1.3 c) }; } else if !arity.is_ref() { // 8.5.1.3 d) - return Err(self.error_form(self.type_error(ValidType::Integer, arity), stub)); + return Err(self.error_form(MachineError::type_error(ValidType::Integer, arity), stub)); } } }; @@ -1591,7 +1595,7 @@ impl MachineState { } pub(super) fn try_from_list(&self, r: RegType, caller: MachineStub) - -> Result, MachineError> + -> Result, MachineStub> { let a1 = self.store(self.deref(self[r].clone())); @@ -1613,13 +1617,13 @@ impl MachineState { Addr::Con(Constant::EmptyList) => break, Addr::HeapCell(_) | Addr::StackCell(..) => - return Err(self.error_form(self.instantiation_error(), caller)), + return Err(self.error_form(MachineError::instantiation_error(), caller)), _ => - return Err(self.error_form(self.type_error(ValidType::List, a1), + return Err(self.error_form(MachineError::type_error(ValidType::List, a1), caller)) }, _ => - return Err(self.error_form(self.type_error(ValidType::List, a1), + return Err(self.error_form(MachineError::type_error(ValidType::List, a1), caller)) }; } @@ -1627,31 +1631,31 @@ impl MachineState { Ok(result) }, Addr::HeapCell(_) | Addr::StackCell(..) => - Err(self.error_form(self.instantiation_error(), caller)), + Err(self.error_form(MachineError::instantiation_error(), caller)), Addr::Con(Constant::EmptyList) => Ok(vec![]), _ => - Err(self.error_form(self.type_error(ValidType::List, a1), caller)) + Err(self.error_form(MachineError::type_error(ValidType::List, a1), caller)) } } // see 8.4.4.3 of Draft Technical Corrigendum 2 for an error guide. - pub(super) fn project_onto_key(&self, a: Addr) -> Result { - let stub = self.functor_stub(clause_name!("keysort"), 2); + pub(super) fn project_onto_key(&self, a: Addr) -> Result { + let stub = MachineError::functor_stub(clause_name!("keysort"), 2); match self.store(self.deref(a)) { Addr::HeapCell(_) | Addr::StackCell(..) => - Err(self.error_form(self.instantiation_error(), stub)), + Err(self.error_form(MachineError::instantiation_error(), stub)), Addr::Str(s) => match self.heap[s].clone() { HeapCellValue::NamedStr(2, ref name, Some(Fixity::In)) if *name == clause_name!("-") => Ok(Addr::HeapCell(s+1)), - _ => Err(self.error_form(self.type_error(ValidType::Pair, + _ => Err(self.error_form(MachineError::type_error(ValidType::Pair, self.heap[s].as_addr(s)), stub)) }, - a => Err(self.error_form(self.type_error(ValidType::Pair, a), stub)) + a => Err(self.error_form(MachineError::type_error(ValidType::Pair, a), stub)) } } diff --git a/src/prolog/machine/system_calls.rs b/src/prolog/machine/system_calls.rs index 2a18ce83..a48f766c 100644 --- a/src/prolog/machine/system_calls.rs +++ b/src/prolog/machine/system_calls.rs @@ -102,7 +102,7 @@ impl MachineState { } } - pub(super) fn skip_max_list(&mut self) -> Result<(), MachineError> { + pub(super) fn skip_max_list(&mut self) -> CallResult { let max_steps = self.store(self.deref(self[temp_v!(2)].clone())); match max_steps { @@ -149,8 +149,8 @@ impl MachineState { self.fail = true; }, _ => { - let stub = self.functor_stub(clause_name!("$skip_max_list"), 4); - return Err(self.error_form(self.instantiation_error(), stub)); + let stub = MachineError::functor_stub(clause_name!("$skip_max_list"), 4); + return Err(self.error_form(MachineError::instantiation_error(), stub)); } }; @@ -242,8 +242,8 @@ impl MachineState { CallWithInferenceLimitCallPolicy.") }, _ => { - let stub = self.functor_stub(clause_name!("call_with_inference_limit"), 3); - let type_error = self.error_form(self.type_error(ValidType::Integer, a2), + let stub = MachineError::functor_stub(clause_name!("call_with_inference_limit"), 3); + let type_error = self.error_form(MachineError::type_error(ValidType::Integer, a2), stub); self.throw_exception(type_error) }