]> Repositorios git - scryer-prolog.git/commitdiff
Implemented num_order methods on Integer & Rational numbers
authorFayeed Pawaskar <[email protected]>
Mon, 4 Sep 2023 08:42:47 +0000 (14:12 +0530)
committerFayeed Pawaskar <[email protected]>
Mon, 4 Sep 2023 08:42:47 +0000 (14:12 +0530)
src/arithmetic.rs
src/heap_print.rs
src/indexing.rs
src/machine/arithmetic_ops.rs
src/machine/heap.rs
src/machine/loader.rs
src/machine/machine_state.rs
src/machine/machine_state_impl.rs
src/machine/preprocessor.rs
src/machine/system_calls.rs

index ded849062032026f7c568c3c77d099c507b26934..d3d97c4d00034120d0808d631986990c505d188f 100644 (file)
@@ -14,6 +14,8 @@ use crate::parser::dashu::{Integer, Rational};
 use crate::machine::machine_errors::*;
 
 use dashu::base::Abs;
+use dashu::base::BitTest;
+use num_order::NumOrd;
 use ordered_float::*;
 
 use std::cell::Cell;
@@ -370,8 +372,9 @@ impl<'a> ArithmeticEvaluator<'a> {
 pub(crate) fn rnd_i<'a>(n: &'a Number, arena: &mut Arena) -> Number {
     match n {
         &Number::Integer(i) => {
-            if let Some(n) = i.to_i64() {
-                fixnum!(Number, n, arena)
+            let result = i.value().try_into();
+            if let Ok(value) = result{
+                fixnum!(Number, value, arena)
             } else {
                 *n
             }
@@ -392,8 +395,9 @@ pub(crate) fn rnd_i<'a>(n: &'a Number, arena: &mut Arena) -> Number {
         &Number::Rational(ref r) => {
             let (_, floor) = (r.fract(), r.floor());
 
-            if let Some(floor) = floor.to_i64() {
-                fixnum!(Number, floor, arena)
+            let result = floor.clone().try_into();
+            if let Ok(value) = result{
+                fixnum!(Number, value, arena)
             } else {
                 Number::Integer(arena_alloc!(floor, arena))
             }
@@ -542,10 +546,10 @@ impl PartialEq for Number {
     fn eq(&self, rhs: &Self) -> bool {
         match (self, rhs) {
             (&Number::Fixnum(n1), &Number::Fixnum(n2)) => n1.eq(&n2),
-            (&Number::Fixnum(n1), &Number::Integer(ref n2)) => n1.get_num().eq(&**n2),
-            (&Number::Integer(ref n1), &Number::Fixnum(n2)) => (&**n1).eq(&n2.get_num()),
-            (&Number::Fixnum(n1), &Number::Rational(ref n2)) => n1.get_num().eq(&**n2),
-            (&Number::Rational(ref n1), &Number::Fixnum(n2)) => (&**n1).eq(&n2.get_num()),
+            (&Number::Fixnum(n1), &Number::Integer(ref n2)) => n1.get_num().num_eq(&**n2),
+            (&Number::Integer(ref n1), &Number::Fixnum(n2)) => (&**n1).num_eq(&n2.get_num()),
+            (&Number::Fixnum(n1), &Number::Rational(ref n2)) => Integer::from(n1.get_num()).num_eq(&**n2),
+            (&Number::Rational(ref n1), &Number::Fixnum(n2)) => (&**n1).num_eq(&Integer::from(n2.get_num())),
             (&Number::Fixnum(n1), &Number::Float(n2)) => OrderedFloat(n1.get_num() as f64).eq(&n2),
             (&Number::Float(n1), &Number::Fixnum(n2)) => n1.eq(&OrderedFloat(n2.get_num() as f64)),
             (&Number::Integer(ref n1), &Number::Integer(ref n2)) => n1.eq(n2),
@@ -558,7 +562,7 @@ impl PartialEq for Number {
                 }
                 #[cfg(not(feature = "num"))]
                 {
-                    &**n1 == &**n2
+                    (&**n1).num_eq(&**n2)
                 }
             }
             (&Number::Rational(ref n1), &Number::Integer(ref n2)) => {
@@ -568,7 +572,7 @@ impl PartialEq for Number {
                 }
                 #[cfg(not(feature = "num"))]
                 {
-                    &**n1 == &**n2
+                    (&**n1).num_eq(&**n2)
                 }
             }
             (&Number::Rational(ref n1), &Number::Float(n2)) => OrderedFloat(n1.to_f64().value()).eq(&n2),
@@ -594,8 +598,8 @@ impl PartialOrd<usize> for Number {
                     (n as usize).partial_cmp(rhs)
                 }
             }
-            Number::Integer(n) => (&**n).partial_cmp(rhs),
-            Number::Rational(r) => (&**r).partial_cmp(rhs),
+            Number::Integer(n) => Some((&**n).num_cmp(rhs)),
+            Number::Rational(r) => Some((&**r).num_cmp(&Integer::from(*rhs))),
             Number::Float(f) => f.partial_cmp(&OrderedFloat(*rhs as f64)),
         }
     }
@@ -614,8 +618,8 @@ impl PartialEq<usize> for Number {
                     (n as usize).eq(rhs)
                 }
             }
-            Number::Integer(n) => (&**n).eq(rhs),
-            Number::Rational(r) => (&**r).eq(rhs),
+            Number::Integer(n) => (&**n).num_eq(rhs),
+            Number::Rational(r) => (&**r).num_eq(&Integer::from(*rhs)),
             Number::Float(f) => f.eq(&OrderedFloat(*rhs as f64)),
         }
     }
@@ -649,7 +653,7 @@ impl Ord for Number {
                 }
                 #[cfg(not(feature = "num"))]
                 {
-                    (&*n1).partial_cmp(&*n2).unwrap_or(Ordering::Less)
+                    (&*n1).num_partial_cmp(&*n2).unwrap_or(Ordering::Less)
                 }
             }
             (&Number::Rational(n1), &Number::Integer(n2)) => {
@@ -659,7 +663,7 @@ impl Ord for Number {
                 }
                 #[cfg(not(feature = "num"))]
                 {
-                    (&*n1).partial_cmp(&*n2).unwrap_or(Ordering::Less)
+                    (&*n1).num_partial_cmp(&*n2).unwrap_or(Ordering::Less)
                 }
             }
             (&Number::Rational(n1), &Number::Float(n2)) => OrderedFloat(n1.to_f64().value()).cmp(&n2),
@@ -706,14 +710,14 @@ impl TryFrom<HeapCellValue> for Number {
 pub(crate) fn binary_pow(mut n: Integer, power: &Integer) -> Integer {
     let mut power = Integer::from(power.abs());
 
-    if power == 0 {
+    if power.num_eq(&0) {
         return Integer::from(1);
     }
 
     let mut oddand = Integer::from(1);
 
-    while power > 1 {
-        if power.is_odd() {
+    while power.num_gt(&1) {
+        if power.bit(0) {
             oddand *= &n;
         }
 
index 8be390768d533a227ab9040c8927338e70060416..d22ca6c9d3f5f9978f199fa7d47be99656c052b5 100644 (file)
@@ -1020,7 +1020,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
 
         match self.op_dir.get(&(atom!("rdiv"), Fixity::In)) {
             Some(op_desc) => {
-                if r.is_integer() {
+                if r.denominator().is_one() {
                     let output_str = format!("{}", r);
 
                     push_space_if_amb!(self, &output_str, {
@@ -1361,7 +1361,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
                                 Ok(Number::Integer(n)) => &*n >= &Integer::from(0),
                                 Ok(Number::Fixnum(n)) => n.get_num() >= 0,
                                 Ok(Number::Float(f)) => f >= OrderedFloat(0f64),
-                                Ok(Number::Rational(r)) => &*r >= &Integer::from(0),
+                                Ok(Number::Rational(r)) => &*r >= &Rational::from(0),
                                 _ => false,
                             }
                         }) && needs_bracketing(op_desc, op)
index bad75be4616c0252f4feaa0e9831997add90686c..67a2b5e7688d13ce1669d96742a2c588d1dbed88 100644 (file)
@@ -1116,8 +1116,9 @@ pub(crate) fn constant_key_alternatives(
         }
         */
         Literal::Integer(ref n) => {
-            if let Some(n) = n.to_isize() {
-                Fixnum::build_with_checked(n as i64).map(|n| {
+            let result = n.value().try_into();
+            if let Ok(value) = result {
+                Fixnum::build_with_checked(value).map(|n| {
                     constants.push(Literal::Fixnum(n));
                 }).unwrap();
             }
index 020878653644875293fe14e7c7de2374ea35502e..80b4153fd9c068b4b459248f77009d45d0f95b19 100644 (file)
@@ -1,7 +1,9 @@
 use dashu::base::Abs;
+use dashu::base::DivRem;
 use dashu::base::Gcd;
 use dashu::integer::IBig;
 use divrem::*;
+use num_order::NumOrd;
 
 use crate::arena::*;
 use crate::arithmetic::*;
@@ -454,14 +456,14 @@ pub(crate) fn max(n1: Number, n2: Number) -> Result<Number, MachineStubGen> {
             }
         }
         (Number::Fixnum(n1), Number::Integer(n2)) => {
-            if &*n2 > &n1.get_num() {
+            if (&*n2).num_gt(&n1.get_num()) {
                 Ok(Number::Integer(n2))
             } else {
                 Ok(Number::Fixnum(n1))
             }
         }
         (Number::Integer(n1), Number::Fixnum(n2)) => {
-            if &*n1 > &n2.get_num() {
+            if (&*n1).num_gt(&n2.get_num()) {
                 Ok(Number::Integer(n1))
             } else {
                 Ok(Number::Fixnum(n2))
@@ -498,14 +500,14 @@ pub(crate) fn min(n1: Number, n2: Number) -> Result<Number, MachineStubGen> {
             }
         }
         (Number::Fixnum(n1), Number::Integer(n2)) => {
-            if &*n2 < &n1.get_num() {
+            if (&*n2).num_lt(&n1.get_num()) {
                 Ok(Number::Integer(n2))
             } else {
                 Ok(Number::Fixnum(n1))
             }
         }
         (Number::Integer(n1), Number::Fixnum(n2)) => {
-            if &*n1 < &n2.get_num() {
+            if (&*n1).num_lt(&n2.get_num()) {
                 Ok(Number::Integer(n1))
             } else {
                 Ok(Number::Fixnum(n2))
@@ -560,7 +562,7 @@ pub(crate) fn rdiv(
     r1: TypedArenaPtr<Rational>,
     r2: TypedArenaPtr<Rational>,
 ) -> Result<Rational, MachineStubGen> {
-    if &*r2 == &0 {
+    if &*r2 == &Rational::from(0) {
         let stub_gen = || {
             let rdiv_atom = atom!("rdiv");
             functor_stub(rdiv_atom, 2)
@@ -594,7 +596,7 @@ pub(crate) fn idiv(n1: Number, n2: Number, arena: &mut Arena) -> Result<Number,
             }
         }
         (Number::Fixnum(n1), Number::Integer(n2)) => {
-            if &*n2 == &0 {
+            if (&*n2).num_eq(&0) {
                 Err(zero_divisor_eval_error(stub_gen))
             } else {
                 Ok(Number::arena_from(Integer::from(n1) / &*n2, arena))
@@ -608,11 +610,11 @@ pub(crate) fn idiv(n1: Number, n2: Number, arena: &mut Arena) -> Result<Number,
             }
         }
         (Number::Integer(n1), Number::Integer(n2)) => {
-            if &*n2 == &0 {
+            if (&*n2).num_eq(&0) {
                 Err(zero_divisor_eval_error(stub_gen))
             } else {
                 Ok(Number::arena_from(
-                    <(Integer, Integer)>::from(n1.div_rem_floor_ref(&*n2)).0,
+                    <(Integer, Integer)>::from(n1.value().div_rem(&*n2)).0,
                     arena,
                 ))
             }
@@ -666,11 +668,15 @@ pub(crate) fn shr(n1: Number, n2: Number, arena: &mut Arena) -> Result<Number, M
         (Number::Fixnum(n1), Number::Integer(n2)) => {
             let n1 = Integer::from(n1.get_num());
 
-            match n2.to_usize() {
-                Some(n2) => Ok(Number::arena_from(n1 >> n2, arena)),
-                _ => {
-                               Ok(Number::arena_from(n1 >> usize::max_value(), arena))
-                       },
+            let result: Result<usize, _> = n2.value().try_into();
+
+            match result {
+                Ok(n2) => {
+                    Ok(Number::arena_from(n1 >> n2, arena))
+                }
+                Err(_) => {
+                    Ok(Number::arena_from(n1 >> usize::max_value(), arena))
+                }
             }
         }
         (Number::Integer(n1), Number::Fixnum(n2)) => match usize::try_from(n2.get_num()) {
@@ -679,11 +685,17 @@ pub(crate) fn shr(n1: Number, n2: Number, arena: &mut Arena) -> Result<Number, M
                        Ok(Number::arena_from(Integer::from(&*n1 >> usize::max_value()),arena))
                },
         },
-        (Number::Integer(n1), Number::Integer(n2)) => match n2.to_usize() {
-            Some(n2) => Ok(Number::arena_from(Integer::from(&*n1 >> n2), arena)),
-            _ => {
-                       Ok(Number::arena_from(Integer::from(&*n1 >> usize::max_value()), arena))
-            },
+        (Number::Integer(n1), Number::Integer(n2)) => {
+            let result: Result<usize, _> = n2.value().try_into();
+
+            match result {
+                Ok(n2) => {
+                    Ok(Number::arena_from(Integer::from(&*n1 >> n2), arena))
+                }
+                Err(_) => {
+                    Ok(Number::arena_from(Integer::from(&*n1 >> usize::max_value()), arena))
+                }
+            }
         },
         (Number::Integer(_), n2) => Err(numerical_type_error(ValidType::Integer, n2, stub_gen)),
         (Number::Fixnum(_), n2) => Err(numerical_type_error(ValidType::Integer, n2, stub_gen)),
@@ -717,8 +729,11 @@ pub(crate) fn shl(n1: Number, n2: Number, arena: &mut Arena) -> Result<Number, M
         (Number::Fixnum(n1), Number::Integer(n2)) => {
             let n1 = Integer::from(n1.get_num());
 
-            match n2.to_u32() {
-                Some(n2) => Ok(Number::arena_from(n1.to_u64().unwrap() << n2, arena)),
+            match n2.value().try_into() as Result<u32, _> {
+                Ok(n2) => {
+                    let n1: u64 = n1.try_into().unwrap();
+                    Ok(Number::arena_from(n1 << n2, arena))
+                },
                 _ => {
                                Ok(Number::arena_from(n1 << usize::max_value(), arena))
                        }
@@ -730,8 +745,11 @@ pub(crate) fn shl(n1: Number, n2: Number, arena: &mut Arena) -> Result<Number, M
                        Ok(Number::arena_from(Integer::from(&*n1 << usize::max_value()),arena))
                    }
         },
-        (Number::Integer(n1), Number::Integer(n2)) => match n2.to_u32() {
-            Some(n2) => Ok(Number::arena_from(Integer::from(n1.to_u64().unwrap() << n2), arena)),
+        (Number::Integer(n1), Number::Integer(n2)) => match n2.value().try_into() as Result<u32, _> {
+            Ok(n2) => {
+                let n1: u64 = n1.value().try_into().unwrap();
+                Ok(Number::arena_from(Integer::from(n1 << n2), arena))
+            },
             _ => {
                        Ok(Number::arena_from(Integer::from(&*n1 << usize::max_value()),arena))
                }
@@ -845,12 +863,12 @@ pub(crate) fn modulus(x: Number, y: Number, arena: &mut Arena) -> Result<Number,
             }
         }
         (Number::Fixnum(n1), Number::Integer(n2)) => {
-            if &*n2 == &0 {
+            if (&*n2).num_eq(&0) {
                 Err(zero_divisor_eval_error(stub_gen))
             } else {
                 let n1 = Integer::from(n1.get_num());
                 Ok(Number::arena_from(
-                    <(Integer, Integer)>::from(n1.div_rem_floor_ref(&*n2)).1,
+                    <(Integer, Integer)>::from(n1.div_rem(&*n2)).1,
                     arena,
                 ))
             }
@@ -863,17 +881,17 @@ pub(crate) fn modulus(x: Number, y: Number, arena: &mut Arena) -> Result<Number,
             } else {
                 let n2 = Integer::from(n2_i);
                 Ok(Number::arena_from(
-                    <(Integer, Integer)>::from(n1.div_rem_floor_ref(&n2)).1,
+                    <(Integer, Integer)>::from(n1.value().div_rem(&n2)).1,
                     arena,
                 ))
             }
         }
         (Number::Integer(x), Number::Integer(y)) => {
-            if &*y == &0 {
+            if (&*y).num_eq(&0) {
                 Err(zero_divisor_eval_error(stub_gen))
             } else {
                 Ok(Number::arena_from(
-                    <(Integer, Integer)>::from(x.div_rem_floor_ref(&*y)).1,
+                    <(Integer, Integer)>::from(x.value().div_rem(&*y)).1,
                     arena,
                 ))
             }
@@ -903,7 +921,7 @@ pub(crate) fn remainder(x: Number, y: Number, arena: &mut Arena) -> Result<Numbe
             }
         }
         (Number::Fixnum(n1), Number::Integer(n2)) => {
-            if &*n2 == &0 {
+            if (&*n2).num_eq(&0) {
                 Err(zero_divisor_eval_error(stub_gen))
             } else {
                 let n1 = Integer::from(n1.get_num());
@@ -921,7 +939,7 @@ pub(crate) fn remainder(x: Number, y: Number, arena: &mut Arena) -> Result<Numbe
             }
         }
         (Number::Integer(n1), Number::Integer(n2)) => {
-            if &*n2 == &0 {
+            if (&*n2).num_eq(&0) {
                 Err(zero_divisor_eval_error(stub_gen))
             } else {
                 Ok(Number::arena_from(Integer::from(&*n1 % &*n2), arena))
@@ -962,7 +980,8 @@ pub(crate) fn gcd(n1: Number, n2: Number, arena: &mut Arena) -> Result<Number, M
         }
         (Number::Integer(n1), Number::Integer(n2)) => {
             let n1_clone: Integer = (*n1).clone();
-            Ok(Number::arena_from(Integer::from(n1_clone.gcd(&Integer::from(n2.to_isize().unwrap()))) as IBig, arena))
+            let n2: isize = n2.value().try_into().unwrap();
+            Ok(Number::arena_from(Integer::from(n1_clone.gcd(&Integer::from(n2))) as IBig, arena))
         }
         (Number::Float(f), _) | (_, Number::Float(f)) => {
             let n = Number::Float(f);
index 1cdfeb748d4c55c196dd323dd66722db4ab72cfe..1fc757d128f6cc8e0cd9df56f56ca30e688b655d 100644 (file)
@@ -258,7 +258,10 @@ pub(crate) fn to_local_code_ptr(heap: &Heap, addr: HeapCellValue) -> Option<usiz
     let extract_integer = |s: usize| -> Option<usize> {
         match Number::try_from(heap[s]) {
             Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).ok(),
-            Ok(Number::Integer(n)) => n.to_usize(),
+            Ok(Number::Integer(n)) => {
+                let value: usize = n.value().try_into().unwrap();
+                Some(value)
+            },
             _ => None,
         }
     };
index 0fe88cbbfdef1d3b50c6e762fc7a5a3006722f54..e51aa23c87bdef152c39eaaea7cd0fab676e6053 100644 (file)
@@ -1652,7 +1652,10 @@ impl Machine {
 
         let arity = self.deref_register(3);
         let arity = match Number::try_from(arity) {
-            Ok(Number::Integer(n)) if &*n >= &Integer::from(0) && &*n <= &Integer::from(MAX_ARITY) => Ok(n.to_usize().unwrap()),
+            Ok(Number::Integer(n)) if &*n >= &Integer::from(0) && &*n <= &Integer::from(MAX_ARITY) => {
+                let value: usize = n.value().try_into().unwrap();
+                Ok(value)
+            },
             Ok(Number::Fixnum(n)) if n.get_num() >= 0 && n.get_num() <= MAX_ARITY as i64 => {
                 Ok(usize::try_from(n.get_num()).unwrap())
             }
@@ -2226,7 +2229,10 @@ impl Machine {
             .store(self.machine_st.deref(self.machine_st[temp_v!(3)]));
 
         let target_pos = match Number::try_from(target_pos) {
-            Ok(Number::Integer(n)) => n.to_usize().unwrap(),
+            Ok(Number::Integer(n)) => {
+                let value: usize = n.value().try_into().unwrap();
+                value
+            },
             Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).unwrap(),
             _ => unreachable!(),
         };
index ccd657648e29e04b8445088ca2e4eb54985bc217..47911e9af6e515378b65879dfc7085bd92d02746 100644 (file)
@@ -872,8 +872,10 @@ impl MachineState {
                         }
                     }
                     Ok(Number::Integer(n)) => {
-                        if let Some(n) = n.to_usize() {
-                            printer.max_depth = n;
+                        let result = n.value().try_into();
+
+                        if let Ok(value) = result {
+                            printer.max_depth = value;
                         } else {
                             self.fail = true;
                             return Ok(None);
index 90036db65b64624b65dcff7e8bdfde3c9b78e5a0..854c7152bb5e0249a92aeedf3c6f2dedd19cc5e5 100644 (file)
@@ -16,6 +16,7 @@ use crate::parser::ast::*;
 use crate::parser::dashu::{Integer, Rational};
 
 use indexmap::IndexSet;
+use num_order::NumOrd;
 
 use std::cmp::Ordering;
 use std::convert::TryFrom;
@@ -297,12 +298,12 @@ impl MachineState {
 
     pub fn unify_big_int(&mut self, n1: TypedArenaPtr<Integer>, value: HeapCellValue) {
         let mut unifier = DefaultUnifier::from(self);
-        unifier.unify_big_num(n1, value);
+        unifier.unify_big_integer(n1, value);
     }
 
     pub fn unify_rational(&mut self, n1: TypedArenaPtr<Rational>, value: HeapCellValue) {
         let mut unifier = DefaultUnifier::from(self);
-        unifier.unify_big_num(n1, value);
+        unifier.unify_big_rational(n1, value);
     }
 
     pub fn unify_f64(&mut self, f1: F64Ptr, value: HeapCellValue) {
@@ -1181,7 +1182,10 @@ impl MachineState {
 
                 let n = match n {
                     Number::Fixnum(n) => n.get_num() as usize,
-                    Number::Integer(n) if *n >= 0 && *n <= std::usize::MAX => n.to_usize().unwrap(),
+                    Number::Integer(n) if (*n).num_ge(&0) && (*n).num_le(&std::usize::MAX) => {
+                        let value: usize = n.value().try_into().unwrap();
+                        value
+                    },
                     _ => {
                         self.fail = true;
                         return Ok(());
@@ -1398,9 +1402,15 @@ impl MachineState {
                         let err = self.domain_error(DomainErrorType::NotLessThanZero, n);
                         return Err(self.error_form(err, stub_gen()));
                     }
-                    Ok(Number::Rational(n)) => n.numerator().to_i64().unwrap(),
+                    Ok(Number::Rational(n)) => {
+                        let value: i64 = n.numerator().try_into().unwrap();
+                        value
+                    },
                     Ok(Number::Fixnum(n)) => n.get_num(),
-                    Ok(Number::Integer(n)) => n.to_i64().unwrap(),
+                    Ok(Number::Integer(n)) => {
+                        let value: i64 = n.value().try_into().unwrap();
+                        value
+                    },
                     Err(_) => {
                         return type_error(arity);
                     }
@@ -1681,9 +1691,9 @@ impl MachineState {
                             Err(_) => {}
                         },
                         Ok(Number::Integer(n)) => {
-                            if let Some(b) = n.to_u8() {
-                                bytes.push(b);
-                            }
+                            let b: u8 = n.value().try_into().unwrap();
+                            
+                            bytes.push(b);
                         }
                         _ => {}
                     }
index a0cab8695830b77d01eb78e974dfd3b60f18303f..cc831d9496fb3b9d958d3f408541de85aec01ef8 100644 (file)
@@ -65,7 +65,10 @@ fn setup_predicate_indicator(term: &mut Term) -> Result<PredicateKey, Compilatio
             let name = terms.pop().unwrap();
 
             let arity = match arity {
-                Term::Literal(_, Literal::Integer(n)) => n.to_usize(),
+                Term::Literal(_, Literal::Integer(n)) => {
+                    let value: usize = n.value().try_into().unwrap();
+                    Some(value)
+                },
                 Term::Literal(_, Literal::Fixnum(n)) => usize::try_from(n.get_num()).ok(),
                 _ => None,
             }.ok_or(CompilationError::InvalidModuleExport)?;
index b158d428e22d8a96b5642b1dca182b9ef4e81841..96ccd59b799aba5615a61fa15a144d723610f525 100644 (file)
@@ -1,8 +1,10 @@
 use crate::parser::ast::*;
 use crate::parser::parser::*;
 
+use dashu::integer::Sign;
 use dashu::integer::UBig;
 use lazy_static::lazy_static;
+use num_order::NumOrd;
 
 use crate::arena::*;
 use crate::atom_table::*;
@@ -748,7 +750,11 @@ impl MachineState {
 
             let max_steps_n = match max_steps {
                 Ok(Number::Fixnum(n)) => Some(n.get_num()),
-                Ok(Number::Integer(n)) => n.to_i64(),
+                Ok(Number::Integer(n)) => {
+                    let value: i64 = n.value().try_into().unwrap();
+
+                    Some(value)
+                },
                 _ => None,
             };
 
@@ -1110,7 +1116,8 @@ impl MachineState {
                     }
                 }
                 Ok(Number::Integer(n)) => {
-                    if let Some(c) = n.to_u32().and_then(std::char::from_u32) {
+                    let n: u32 = n.value().try_into().unwrap();
+                    if let Some(c) = std::char::from_u32(n) {
                         string.push(c);
                         continue;
                     }
@@ -1755,7 +1762,10 @@ impl Machine {
         let reg = self.deref_register(2);
         let n = match Number::try_from(reg) {
             Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).ok(),
-            Ok(Number::Integer(n)) => n.to_usize(),
+            Ok(Number::Integer(n)) => {
+                let value: usize = n.value().try_into().unwrap();
+                Some(value)
+            },
             _ => {
                 unreachable!()
             }
@@ -2468,8 +2478,9 @@ impl Machine {
             addr if addr.is_var() => addr,
             addr => match Number::try_from(addr) {
                 Ok(Number::Integer(n)) => {
-                    if let Some(nb) = n.to_u8() {
-                        fixnum_as_cell!(Fixnum::build_with(nb as i64))
+                    let result: Result<u8, _> = n.value().try_into();
+                    if let Ok(value) = result {
+                        fixnum_as_cell!(Fixnum::build_with(value as i64))
                     } else {
                         let err = self.machine_st.type_error(ValidType::InByte, addr);
                         return Err(self.machine_st.error_form(err, stub_gen()));
@@ -2665,9 +2676,9 @@ impl Machine {
             _ => {
                 match Number::try_from(a2) {
                     Ok(Number::Integer(n)) => {
-                        let n = n
-                            .to_u32()
-                            .and_then(|n| std::char::from_u32(n).and_then(|_| Some(n)));
+                        let n: u32 = n.value().try_into().unwrap();
+
+                        let n = std::char::from_u32(n).and_then(|_| Some(n));
 
                         if let Some(n) = n {
                             fixnum_as_cell!(Fixnum::build_with(n as i64))
@@ -2835,7 +2846,9 @@ impl Machine {
             _ => {
                 match Number::try_from(a2) {
                     Ok(Number::Integer(n)) => {
-                        let c = match n.to_u32().and_then(std::char::from_u32) {
+                        let n: u32 = n.value().try_into().unwrap();
+                        let n = std::char::from_u32(n);
+                        let c = match n {
                             Some(c) => c,
                             _ => {
                                 let err = self.machine_st.representation_error(RepFlag::CharacterCode);
@@ -3070,7 +3083,9 @@ impl Machine {
         } else {
             match Number::try_from(addr) {
                 Ok(Number::Integer(n)) => {
-                    if let Some(c) = n.to_u32().and_then(|c| char::try_from(c).ok()) {
+                    let n: u32 = n.value().try_into().unwrap();
+                    let n = char::try_from(n);
+                    if let Some(c) = n.ok() {
                         write!(&mut stream, "{}", c).unwrap();
                         return Ok(());
                     }
@@ -3207,17 +3222,21 @@ impl Machine {
         } else {
             match Number::try_from(addr) {
                 Ok(Number::Integer(n)) => {
-                    if let Some(nb) = n.to_u8() {
-                        match stream.write(&mut [nb]) {
-                            Ok(1) => {
-                                return Ok(());
-                            }
-                            _ => {
-                                let err = self.machine_st.existence_error(
-                                    ExistenceError::Stream(stream_as_cell!(stream))
-                                );
+                    let n: u8 = n.value().try_into().unwrap();
+                    
+                    match n {
+                        nb => {
+                            match stream.write(&mut [nb]) {
+                                Ok(1) => {
+                                    return Ok(());
+                                }
+                                _ => {
+                                    let err = self.machine_st.existence_error(
+                                        ExistenceError::Stream(stream_as_cell!(stream))
+                                    );
 
-                                return Err(self.machine_st.error_form(err, stub_gen()));
+                                    return Err(self.machine_st.error_form(err, stub_gen()));
+                                }
                             }
                         }
                     }
@@ -3281,15 +3300,17 @@ impl Machine {
             addr
         } else {
             match Number::try_from(addr) {
-                Ok(Number::Integer(ref n)) if **n == -1_i64 => {
+                Ok(Number::Integer(ref n)) if (**n).num_eq(&1_i64) => {
                     fixnum_as_cell!(Fixnum::build_with(-1))
                 }
                 Ok(Number::Fixnum(n)) if n.get_num() == -1_i64 => {
                     fixnum_as_cell!(Fixnum::build_with(-1))
                 }
                 Ok(Number::Integer(n)) => {
-                    if let Some(nb) = n.to_u8() {
-                        fixnum_as_cell!(Fixnum::build_with(nb as i64))
+                    let n: Result<u8, _> = n.value().try_into();
+
+                    if let Ok(value) = n {
+                        fixnum_as_cell!(Fixnum::build_with(value as i64))
                     } else {
                         let err = self.machine_st.type_error(ValidType::InByte, addr);
                         return Err(self.machine_st.error_form(err, stub_gen()));
@@ -3442,8 +3463,10 @@ impl Machine {
 
         let num = match Number::try_from(self.deref_register(2)) {
             Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).unwrap(),
-            Ok(Number::Integer(n)) => match n.to_usize() {
-                Some(u) => u,
+            Ok(Number::Integer(n)) => match n.value().try_into() as Result<usize, _> {
+                Ok(u) => {
+                    u
+                }
                 _ => {
                     self.machine_st.fail = true;
                     return Ok(());
@@ -3540,9 +3563,8 @@ impl Machine {
         } else {
             match Number::try_from(addr) {
                 Ok(Number::Integer(n)) => {
-                    let n = n
-                        .to_u32()
-                        .and_then(|n| std::char::from_u32(n));
+                    let n: u32 = n.value().try_into().unwrap();
+                    let n = std::char::from_u32(n);
 
                     if let Some(n) = n {
                         fixnum_as_cell!(Fixnum::build_with(n as i64))
@@ -3891,7 +3913,10 @@ impl Machine {
 
             let arity = match Number::try_from(arity) {
                 Ok(Number::Fixnum(n)) => Some(n.get_num() as usize),
-                Ok(Number::Integer(n)) => n.to_usize(),
+                Ok(Number::Integer(n)) => {
+                    let value: usize = n.value().try_into().unwrap();
+                    Some(value)
+                },
                 _ => None,
             };
 
@@ -4215,9 +4240,9 @@ impl Machine {
 
         let n = match Number::try_from(len) {
             Ok(Number::Fixnum(n)) => n.get_num() as usize,
-            Ok(Number::Integer(n)) => match n.to_usize() {
-                Some(n) => n,
-                None => {
+            Ok(Number::Integer(n)) => match n.value().try_into() as Result<usize, _> {
+                Ok(n) => n,
+                Err(_) => {
                     let err = self.machine_st.resource_error(len);
                     return Err(self.machine_st.error_form(err, stub_gen()));
                 }
@@ -4499,13 +4524,16 @@ impl Machine {
        let status_code = self.deref_register(2);
        let status_code: u16 = match Number::try_from(status_code) {
            Ok(Number::Fixnum(n)) => n.get_num() as u16,
-           Ok(Number::Integer(n)) => match n.to_u16() {
-               Some(u) => u,
-               _ => {
-                   self.machine_st.fail = true;
-                   return Ok(());
-               }
-           }
+           Ok(Number::Integer(n)) => {
+            let n: Result<u16, _> = n.value().try_into();
+            
+            if let Ok(value) = n {
+                value
+            } else {
+                self.machine_st.fail = true;
+                return Ok(());
+            }
+        }
            _ => unreachable!()
        };
        let stub_gen = || functor_stub(atom!("http_listen"), 2);
@@ -4777,7 +4805,10 @@ impl Machine {
         let specifier = cell_as_atom_cell!(self.deref_register(2)).get_name();
 
         let priority = match Number::try_from(priority) {
-            Ok(Number::Integer(n)) => n.to_u16().unwrap(),
+            Ok(Number::Integer(n)) => {
+                let n: u16 = n.value().try_into().unwrap();
+                n
+            },
             Ok(Number::Fixnum(n)) => u16::try_from(n.get_num()).unwrap(),
             _ => {
                 unreachable!();
@@ -4927,7 +4958,10 @@ impl Machine {
         let addr = self.deref_register(1);
 
         let b = match Number::try_from(addr) {
-            Ok(Number::Integer(n)) => n.to_usize(),
+            Ok(Number::Integer(n)) => {
+                let value: usize = n.value().try_into().unwrap();
+                Some(value)
+            },
             Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).ok(),
             _ => {
                 self.machine_st.fail = true;
@@ -5296,12 +5330,16 @@ impl Machine {
 
         let code = match Number::try_from(code) {
             Ok(Number::Fixnum(n)) => u8::try_from(n.get_num()).unwrap(),
-            Ok(Number::Integer(n)) => n.to_u8().unwrap(),
+            Ok(Number::Integer(n)) => {
+                let n: u8 = n.value().try_into().unwrap();
+                n
+            },
             Ok(Number::Rational(r)) => {
                 // n has already been confirmed as an integer, and
                 // internally, Rational is assumed reduced, so its
                 // denominator must be 1.
-                r.numerator().to_u8().unwrap()
+                let r = r.numerator().try_into().unwrap();
+                r
             }
             _ => {
                 unreachable!()
@@ -5331,7 +5369,10 @@ impl Machine {
 
         let n = match Number::try_from(a2) {
             Ok(Number::Fixnum(bp)) => bp.get_num() as usize,
-            Ok(Number::Integer(n)) => n.to_usize().unwrap(),
+            Ok(Number::Integer(n)) => {
+                let value: usize = n.value().try_into().unwrap();
+                value
+            },
             _ => {
                 let stub = functor_stub(
                     atom!("call_with_inference_limit"),
@@ -5347,8 +5388,9 @@ impl Machine {
         let a3 = self.deref_register(3);
         let count = self.machine_st.cwil.add_limit(n, bp);
 
-        if let Some(count) = count.to_i64() {
-            self.machine_st.unify_fixnum(Fixnum::build_with(count), a3);
+        let result = count.try_into();
+        if let Ok(value) = result{
+            self.machine_st.unify_fixnum(Fixnum::build_with(value), a3);
         } else {
             let count = arena_alloc!(count.clone(), &mut self.machine_st.arena);
             self.machine_st.unify_big_int(count, a3);
@@ -5375,8 +5417,10 @@ impl Machine {
         let arity = match Number::try_from(a3) {
             Ok(Number::Fixnum(n))  => n.get_num() as usize,
             Ok(Number::Integer(n)) => {
-                if let Some(n) = n.to_usize() {
-                    n
+                let result = n.value().try_into();
+
+                if let Ok(value) = result {
+                    value
                 } else {
                     return false;
                 }
@@ -5501,8 +5545,9 @@ impl Machine {
 
         let count = self.machine_st.cwil.remove_limit(bp).clone();
 
-        if let Some(count) = count.to_i64() {
-            self.machine_st.unify_fixnum(Fixnum::build_with(count), a2);
+        let result = count.clone().try_into();
+        if let Ok(value) = result{
+            self.machine_st.unify_fixnum(Fixnum::build_with(value), a2);
         } else {
             let count = arena_alloc!(count.clone(), &mut self.machine_st.arena);
             self.machine_st.unify_big_int(count, a2);
@@ -6016,14 +6061,17 @@ impl Machine {
 
         match Number::try_from(seed) {
             Ok(Number::Fixnum(n)) => {
-                let _: StdRng = SeedableRng::seed_from_u64(Integer::from(n).to_u64().unwrap());
+                let n: u64 = Integer::from(n).try_into().unwrap();
+                let _: StdRng = SeedableRng::seed_from_u64(n);
             },
             Ok(Number::Integer(n)) => {
-                let _: StdRng = SeedableRng::seed_from_u64(n.to_u64().unwrap());
+                let n: u64 = n.value().try_into().unwrap();
+                let _: StdRng = SeedableRng::seed_from_u64(n);
             },
             Ok(Number::Rational(n)) => {
                 if n.denominator() == &UBig::from(1 as u32) {
-                    let _: StdRng = SeedableRng::seed_from_u64(n.numerator().to_u64().unwrap());
+                    let n: u64 = n.numerator().try_into().unwrap();
+                    let _: StdRng = SeedableRng::seed_from_u64(n);
                 }
             },
             _ => {
@@ -6428,7 +6476,8 @@ impl Machine {
         let position = match Number::try_from(position) {
             Ok(Number::Fixnum(n)) => n.get_num() as u64,
             Ok(Number::Integer(n)) => {
-                if let Some(n) = n.to_u64() {
+                let n: Result<u64, _> = n.value().try_into();
+                if let Ok(n) = n {
                     n
                 } else {
                     self.machine_st.fail = true;
@@ -6704,7 +6753,10 @@ impl Machine {
 
         let arity = match Number::try_from(arity) {
             Ok(Number::Fixnum(n)) => n.get_num() as usize,
-            Ok(Number::Integer(n)) => n.to_usize().unwrap(),
+            Ok(Number::Integer(n)) => {
+                let value: usize = n.value().try_into().unwrap();
+                value
+            },
             _ => {
                 unreachable!()
             }
@@ -6759,7 +6811,10 @@ impl Machine {
         let index_ptr = self.deref_register(1);
         let index_ptr = match Number::try_from(index_ptr) {
             Ok(Number::Fixnum(n)) => n.get_num() as usize,
-            Ok(Number::Integer(n)) => n.to_usize().unwrap(),
+            Ok(Number::Integer(n)) => {
+                let value: usize = n.value().try_into().unwrap();
+                value
+            },
             _ => {
                 unreachable!()
             }
@@ -7061,8 +7116,8 @@ impl Machine {
 
         let length = match Number::try_from(length) {
             Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).unwrap(),
-            Ok(Number::Integer(n)) => match n.to_usize() {
-                Some(u) => u,
+            Ok(Number::Integer(n)) => match n.value().try_into() as Result<usize, _> {
+                Ok(u) => u,
                 _ => {
                     self.machine_st.fail = true;
                     return;
@@ -7123,11 +7178,14 @@ impl Machine {
 
         let iterations = match Number::try_from(iterations) {
             Ok(Number::Fixnum(n)) => u64::try_from(n.get_num()).unwrap(),
-            Ok(Number::Integer(n)) => match n.to_u64() {
-                Some(i) => i,
-                None => {
-                    self.machine_st.fail = true;
-                    return;
+            Ok(Number::Integer(n)) => {
+                let n: Result<u64, _> = n.value().try_into(); 
+                match n {
+                    Ok(i) => i,
+                    _ => {
+                        self.machine_st.fail = true;
+                        return;
+                    }
                 }
             },
             _ => {
@@ -7695,7 +7753,10 @@ impl Machine {
                 Number::Fixnum(Fixnum::build_with(n.get_num().count_ones() as i64))
             }
             Ok(Number::Integer(n)) => {
-                Number::arena_from(n.count_ones(), &mut self.machine_st.arena)
+                let value: usize = if n.sign() == Sign::Positive {
+                    UBig::from(n.value().into_parts().1).count_ones()
+                } else { 0 };
+                Number::arena_from(value, &mut self.machine_st.arena)
             }
             _ => {
                 unreachable!()