]> Repositorios git - scryer-prolog.git/commitdiff
fix offsetting of heap in existence errors
authorMark Thom <[email protected]>
Sun, 20 May 2018 22:26:52 +0000 (16:26 -0600)
committerMark Thom <[email protected]>
Sun, 20 May 2018 22:26:52 +0000 (16:26 -0600)
src/prolog/copier.rs
src/prolog/machine/machine_errors.rs
src/prolog/machine/machine_state.rs
src/prolog/machine/machine_state_impl.rs
src/prolog/machine/system_calls.rs

index 3099cb8c6f28a2b6f1d2a145832d8321b2ee6845..b16ba5ad44d6dd14ea1d7f074264889fd19c9b9d 100644 (file)
@@ -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();
index c232bb4da9654ed0d1cdd5f9e7a0f0556802765a..a3cb86da14639a33b1cccd46e79b01de10aba00f 100644 (file)
@@ -4,9 +4,79 @@ use prolog::num::bigint::BigInt;
 
 use std::rc::Rc;
 
-pub(super) type MachineError = Vec<HeapCellValue>;
 pub(super) type MachineStub = Vec<HeapCellValue>;
 
+#[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<Iterator<Item=HeapCellValue>> {
+        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;
index 2dd2ba595c50b41c0a0a9861a4c8b09d52bdad8e..5ccf181c752d6bada2737a199179c4d579a6dc65 100644 (file)
@@ -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));
+                }
             };
         }
 
index 5748a43790587a633622f8b97e0dc2e983a5c4f1..cb1799adf9bc4465f0348ca5b0c5f90dc80cdf4a 100644 (file)
@@ -323,7 +323,7 @@ impl MachineState {
         };
     }
 
-    pub(super) fn get_number(&self, at: &ArithmeticTerm) -> Result<Number, MachineError> {
+    pub(super) fn get_number(&self, at: &ArithmeticTerm) -> Result<Number, MachineStub> {
         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<Rc<Ratio<BigInt>>, MachineError>
+                    -> Result<Rc<Ratio<BigInt>>, 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<Number, MachineError>
+    pub(super) fn arith_eval_by_metacall(&self, r: RegType) -> Result<Number, MachineStub>
     {
         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<Number> = 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<Ratio<BigInt>>, r2: Rc<Ratio<BigInt>>)
-            -> Result<Rc<Ratio<BigInt>>, MachineError>
+            -> Result<Rc<Ratio<BigInt>>, 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<Rc<BigInt>, MachineError>
+    fn fidiv(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, 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<Rc<BigInt>, MachineError>
+    fn idiv(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, 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<Number, MachineError>
+    fn div(&self, n1: Number, n2: Number) -> Result<Number, MachineStub>
     {
-        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<Rc<BigInt>, MachineError>
+    fn shr(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, 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<Rc<BigInt>, MachineError>
+    fn shl(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, 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<Rc<BigInt>, MachineError>
+    fn xor(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, 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<Rc<BigInt>, MachineError>
+    fn and(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, 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<Rc<BigInt>, MachineError>
+    fn modulus(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, 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<Rc<BigInt>, MachineError>
+    fn remainder(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, 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<Rc<BigInt>, MachineError>
+    fn or(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, 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<PredicateKey>
     {
-        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<Vec<Addr>, MachineError>
+                                -> Result<Vec<Addr>, 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<Addr, MachineError> {
-        let stub = self.functor_stub(clause_name!("keysort"), 2);
+    pub(super) fn project_onto_key(&self, a: Addr) -> Result<Addr, MachineStub> {
+        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))
         }
     }
 
index 2a18ce83b687ebd08d89cc0129210ab469b6ab65..a48f766c5111fff0df5598784fc8f8e1f9bd0010 100644 (file)
@@ -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)
                     }