Merge pull request #1993 from coasys/dashu-fixes

Dashu fixes
This commit is contained in:
Mark Thom
2023-09-11 11:33:16 -06:00
committed by GitHub
13 changed files with 322 additions and 200 deletions

50
Cargo.lock generated
View File

@@ -369,7 +369,7 @@ dependencies = [
[[package]] [[package]]
name = "dashu" name = "dashu"
version = "0.3.1" version = "0.3.1"
source = "git+https://github.com/coasys/dashu.git#f9342190be9062630124e666b001077bb5f02f23" source = "git+https://github.com/cmpute/dashu.git#9d1ba4ac98a4675f294e2f2c072bf47f96d33e9b"
dependencies = [ dependencies = [
"dashu-base", "dashu-base",
"dashu-float", "dashu-float",
@@ -381,37 +381,36 @@ dependencies = [
[[package]] [[package]]
name = "dashu-base" name = "dashu-base"
version = "0.3.1" version = "0.3.1"
source = "git+https://github.com/coasys/dashu.git#f9342190be9062630124e666b001077bb5f02f23" source = "git+https://github.com/cmpute/dashu.git#9d1ba4ac98a4675f294e2f2c072bf47f96d33e9b"
[[package]] [[package]]
name = "dashu-float" name = "dashu-float"
version = "0.3.2" version = "0.3.2"
source = "git+https://github.com/coasys/dashu.git#f9342190be9062630124e666b001077bb5f02f23" source = "git+https://github.com/cmpute/dashu.git#9d1ba4ac98a4675f294e2f2c072bf47f96d33e9b"
dependencies = [ dependencies = [
"dashu-base", "dashu-base",
"dashu-int", "dashu-int",
"num-modular",
"num-order", "num-order",
"num-traits",
"static_assertions", "static_assertions",
] ]
[[package]] [[package]]
name = "dashu-int" name = "dashu-int"
version = "0.3.1" version = "0.3.1"
source = "git+https://github.com/coasys/dashu.git#f9342190be9062630124e666b001077bb5f02f23" source = "git+https://github.com/cmpute/dashu.git#9d1ba4ac98a4675f294e2f2c072bf47f96d33e9b"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"dashu-base", "dashu-base",
"num-modular 0.5.2", "num-modular",
"num-order", "num-order",
"num-traits",
"static_assertions", "static_assertions",
] ]
[[package]] [[package]]
name = "dashu-macros" name = "dashu-macros"
version = "0.3.1" version = "0.3.1"
source = "git+https://github.com/coasys/dashu.git#f9342190be9062630124e666b001077bb5f02f23" source = "git+https://github.com/cmpute/dashu.git#9d1ba4ac98a4675f294e2f2c072bf47f96d33e9b"
dependencies = [ dependencies = [
"dashu-base", "dashu-base",
"dashu-float", "dashu-float",
@@ -424,13 +423,13 @@ dependencies = [
[[package]] [[package]]
name = "dashu-ratio" name = "dashu-ratio"
version = "0.3.2" version = "0.3.2"
source = "git+https://github.com/coasys/dashu.git#f9342190be9062630124e666b001077bb5f02f23" source = "git+https://github.com/cmpute/dashu.git#9d1ba4ac98a4675f294e2f2c072bf47f96d33e9b"
dependencies = [ dependencies = [
"dashu-base", "dashu-base",
"dashu-float", "dashu-float",
"dashu-int", "dashu-int",
"num-modular",
"num-order", "num-order",
"num-traits",
] ]
[[package]] [[package]]
@@ -1311,39 +1310,19 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "num-integer"
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
dependencies = [
"autocfg",
"num-traits",
]
[[package]] [[package]]
name = "num-modular" name = "num-modular"
version = "0.5.1" version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64a5fe11d4135c3bcdf3a95b18b194afa9608a5f6ff034f5d857bc9a27fb0119" checksum = "17bb261bf36fa7d83f4c294f834e91256769097b3cb505d44831e0a179ac647f"
dependencies = [
"num-integer",
"num-traits",
]
[[package]]
name = "num-modular"
version = "0.5.2"
source = "git+https://github.com/coasys/num-modular.git#1ae06248ec69390370def3a229b3bf4c209aa6c7"
[[package]] [[package]]
name = "num-order" name = "num-order"
version = "1.0.4" version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e81e321057a0370997b13e6638bba6bd7f6f426e1f8e9a2562490a28eb23e1bc" checksum = "537b596b97c40fcf8056d153049eb22f481c17ebce72a513ec9286e4986d1bb6"
dependencies = [ dependencies = [
"num-modular 0.5.1", "num-modular",
"num-traits",
] ]
[[package]] [[package]]
@@ -1943,6 +1922,7 @@ dependencies = [
"libloading", "libloading",
"modular-bitfield", "modular-bitfield",
"native-tls", "native-tls",
"num-order",
"ordered-float", "ordered-float",
"phf 0.9.0", "phf 0.9.0",
"predicates-core", "predicates-core",

View File

@@ -68,7 +68,8 @@ libloading = "0.7"
derive_deref = "1.1.1" derive_deref = "1.1.1"
http-body-util = "0.1.0-rc.2" http-body-util = "0.1.0-rc.2"
bytes = "1" bytes = "1"
dashu = { git = "https://github.com/coasys/dashu.git", version = "0.3.1" } dashu = { version = "0.3.1", git = "https://github.com/cmpute/dashu.git" }
num-order = { version = "1.2.0" }
rand = "0.8.5" rand = "0.8.5"
[target.'cfg(not(target_arch = "wasm32"))'.dependencies] [target.'cfg(not(target_arch = "wasm32"))'.dependencies]

View File

@@ -14,6 +14,8 @@ use crate::parser::dashu::{Integer, Rational};
use crate::machine::machine_errors::*; use crate::machine::machine_errors::*;
use dashu::base::Abs; use dashu::base::Abs;
use dashu::base::BitTest;
use num_order::NumOrd;
use ordered_float::*; use ordered_float::*;
use std::cell::Cell; use std::cell::Cell;
@@ -361,8 +363,9 @@ impl<'a> ArithmeticEvaluator<'a> {
pub(crate) fn rnd_i<'a>(n: &'a Number, arena: &mut Arena) -> Number { pub(crate) fn rnd_i<'a>(n: &'a Number, arena: &mut Arena) -> Number {
match n { match n {
&Number::Integer(i) => { &Number::Integer(i) => {
if let Some(n) = i.to_i64() { let result = (&*i).try_into();
fixnum!(Number, n, arena) if let Ok(value) = result{
fixnum!(Number, value, arena)
} else { } else {
*n *n
} }
@@ -383,8 +386,9 @@ pub(crate) fn rnd_i<'a>(n: &'a Number, arena: &mut Arena) -> Number {
&Number::Rational(ref r) => { &Number::Rational(ref r) => {
let (_, floor) = (r.fract(), r.floor()); let (_, floor) = (r.fract(), r.floor());
if let Some(floor) = floor.to_i64() { let result = floor.clone().try_into();
fixnum!(Number, floor, arena) if let Ok(value) = result{
fixnum!(Number, value, arena)
} else { } else {
Number::Integer(arena_alloc!(floor, arena)) Number::Integer(arena_alloc!(floor, arena))
} }
@@ -533,10 +537,10 @@ impl PartialEq for Number {
fn eq(&self, rhs: &Self) -> bool { fn eq(&self, rhs: &Self) -> bool {
match (self, rhs) { match (self, rhs) {
(&Number::Fixnum(n1), &Number::Fixnum(n2)) => n1.eq(&n2), (&Number::Fixnum(n1), &Number::Fixnum(n2)) => n1.eq(&n2),
(&Number::Fixnum(n1), &Number::Integer(ref n2)) => n1.get_num().eq(&**n2), (&Number::Fixnum(n1), &Number::Integer(ref n2)) => n1.get_num().num_eq(&**n2),
(&Number::Integer(ref n1), &Number::Fixnum(n2)) => (&**n1).eq(&n2.get_num()), (&Number::Integer(ref n1), &Number::Fixnum(n2)) => (&**n1).num_eq(&n2.get_num()),
(&Number::Fixnum(n1), &Number::Rational(ref n2)) => n1.get_num().eq(&**n2), (&Number::Fixnum(n1), &Number::Rational(ref n2)) => Integer::from(n1.get_num()).num_eq(&**n2),
(&Number::Rational(ref n1), &Number::Fixnum(n2)) => (&**n1).eq(&n2.get_num()), (&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::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::Float(n1), &Number::Fixnum(n2)) => n1.eq(&OrderedFloat(n2.get_num() as f64)),
(&Number::Integer(ref n1), &Number::Integer(ref n2)) => n1.eq(n2), (&Number::Integer(ref n1), &Number::Integer(ref n2)) => n1.eq(n2),
@@ -553,7 +557,7 @@ impl PartialEq for Number {
} }
#[cfg(not(feature = "num"))] #[cfg(not(feature = "num"))]
{ {
&**n1 == &**n2 (&**n1).num_eq(&**n2)
} }
} }
(&Number::Rational(ref n1), &Number::Integer(ref n2)) => { (&Number::Rational(ref n1), &Number::Integer(ref n2)) => {
@@ -563,7 +567,7 @@ impl PartialEq for Number {
} }
#[cfg(not(feature = "num"))] #[cfg(not(feature = "num"))]
{ {
&**n1 == &**n2 (&**n1).num_eq(&**n2)
} }
} }
(&Number::Rational(ref n1), &Number::Float(n2)) => { (&Number::Rational(ref n1), &Number::Float(n2)) => {
@@ -593,8 +597,8 @@ impl PartialOrd<usize> for Number {
(n as usize).partial_cmp(rhs) (n as usize).partial_cmp(rhs)
} }
} }
Number::Integer(n) => (&**n).partial_cmp(rhs), Number::Integer(n) => Some((&**n).num_cmp(rhs)),
Number::Rational(r) => (&**r).partial_cmp(rhs), Number::Rational(r) => Some((&**r).num_cmp(&Integer::from(*rhs))),
Number::Float(f) => f.partial_cmp(&OrderedFloat(*rhs as f64)), Number::Float(f) => f.partial_cmp(&OrderedFloat(*rhs as f64)),
} }
} }
@@ -613,8 +617,8 @@ impl PartialEq<usize> for Number {
(n as usize).eq(rhs) (n as usize).eq(rhs)
} }
} }
Number::Integer(n) => (&**n).eq(rhs), Number::Integer(n) => (&**n).num_eq(rhs),
Number::Rational(r) => (&**r).eq(rhs), Number::Rational(r) => (&**r).num_eq(&Integer::from(*rhs)),
Number::Float(f) => f.eq(&OrderedFloat(*rhs as f64)), Number::Float(f) => f.eq(&OrderedFloat(*rhs as f64)),
} }
} }
@@ -650,7 +654,7 @@ impl Ord for Number {
} }
#[cfg(not(feature = "num"))] #[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)) => { (&Number::Rational(n1), &Number::Integer(n2)) => {
@@ -660,7 +664,7 @@ impl Ord for Number {
} }
#[cfg(not(feature = "num"))] #[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)) => { (&Number::Rational(n1), &Number::Float(n2)) => {
@@ -711,14 +715,14 @@ impl TryFrom<HeapCellValue> for Number {
pub(crate) fn binary_pow(mut n: Integer, power: &Integer) -> Integer { pub(crate) fn binary_pow(mut n: Integer, power: &Integer) -> Integer {
let mut power = Integer::from(power.abs()); let mut power = Integer::from(power.abs());
if power == 0 { if power.num_eq(&0) {
return Integer::from(1); return Integer::from(1);
} }
let mut oddand = Integer::from(1); let mut oddand = Integer::from(1);
while power > 1 { while power.num_gt(&1) {
if power.is_odd() { if power.bit(0) {
oddand *= &n; oddand *= &n;
} }

View File

@@ -1024,7 +1024,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
match self.op_dir.get(&(atom!("rdiv"), Fixity::In)) { match self.op_dir.get(&(atom!("rdiv"), Fixity::In)) {
Some(op_desc) => { Some(op_desc) => {
if r.is_integer() { if r.denominator().is_one() {
let output_str = format!("{}", r); let output_str = format!("{}", r);
push_space_if_amb!(self, &output_str, { push_space_if_amb!(self, &output_str, {
@@ -1370,7 +1370,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
Ok(Number::Integer(n)) => &*n >= &Integer::from(0), Ok(Number::Integer(n)) => &*n >= &Integer::from(0),
Ok(Number::Fixnum(n)) => n.get_num() >= 0, Ok(Number::Fixnum(n)) => n.get_num() >= 0,
Ok(Number::Float(f)) => f >= OrderedFloat(0f64), Ok(Number::Float(f)) => f >= OrderedFloat(0f64),
Ok(Number::Rational(r)) => &*r >= &Integer::from(0), Ok(Number::Rational(r)) => &*r >= &Rational::from(0),
_ => false, _ => false,
} }
}) && needs_bracketing(op_desc, op) }) && needs_bracketing(op_desc, op)

View File

@@ -1122,12 +1122,11 @@ pub(crate) fn constant_key_alternatives(
} }
*/ */
Literal::Integer(ref n) => { Literal::Integer(ref n) => {
if let Some(n) = n.to_isize() { let result = (&**n).try_into();
Fixnum::build_with_checked(n as i64) if let Ok(value) = result {
.map(|n| { Fixnum::build_with_checked(value).map(|n| {
constants.push(Literal::Fixnum(n)); constants.push(Literal::Fixnum(n));
}) }).unwrap();
.unwrap();
} }
} }
_ => {} _ => {}

View File

@@ -1,7 +1,9 @@
use dashu::base::Abs; use dashu::base::Abs;
use dashu::base::DivRem;
use dashu::base::Gcd; use dashu::base::Gcd;
use dashu::integer::IBig; use dashu::integer::IBig;
use divrem::*; use divrem::*;
use num_order::NumOrd;
use crate::arena::*; use crate::arena::*;
use crate::arithmetic::*; use crate::arithmetic::*;
@@ -454,14 +456,14 @@ pub(crate) fn max(n1: Number, n2: Number) -> Result<Number, MachineStubGen> {
} }
} }
(Number::Fixnum(n1), Number::Integer(n2)) => { (Number::Fixnum(n1), Number::Integer(n2)) => {
if &*n2 > &n1.get_num() { if (&*n2).num_gt(&n1.get_num()) {
Ok(Number::Integer(n2)) Ok(Number::Integer(n2))
} else { } else {
Ok(Number::Fixnum(n1)) Ok(Number::Fixnum(n1))
} }
} }
(Number::Integer(n1), Number::Fixnum(n2)) => { (Number::Integer(n1), Number::Fixnum(n2)) => {
if &*n1 > &n2.get_num() { if (&*n1).num_gt(&n2.get_num()) {
Ok(Number::Integer(n1)) Ok(Number::Integer(n1))
} else { } else {
Ok(Number::Fixnum(n2)) 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)) => { (Number::Fixnum(n1), Number::Integer(n2)) => {
if &*n2 < &n1.get_num() { if (&*n2).num_lt(&n1.get_num()) {
Ok(Number::Integer(n2)) Ok(Number::Integer(n2))
} else { } else {
Ok(Number::Fixnum(n1)) Ok(Number::Fixnum(n1))
} }
} }
(Number::Integer(n1), Number::Fixnum(n2)) => { (Number::Integer(n1), Number::Fixnum(n2)) => {
if &*n1 < &n2.get_num() { if (&*n1).num_lt(&n2.get_num()) {
Ok(Number::Integer(n1)) Ok(Number::Integer(n1))
} else { } else {
Ok(Number::Fixnum(n2)) Ok(Number::Fixnum(n2))
@@ -560,7 +562,7 @@ pub(crate) fn rdiv(
r1: TypedArenaPtr<Rational>, r1: TypedArenaPtr<Rational>,
r2: TypedArenaPtr<Rational>, r2: TypedArenaPtr<Rational>,
) -> Result<Rational, MachineStubGen> { ) -> Result<Rational, MachineStubGen> {
if &*r2 == &0 { if &*r2 == &Rational::from(0) {
let stub_gen = || { let stub_gen = || {
let rdiv_atom = atom!("rdiv"); let rdiv_atom = atom!("rdiv");
functor_stub(rdiv_atom, 2) 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)) => { (Number::Fixnum(n1), Number::Integer(n2)) => {
if &*n2 == &0 { if (&*n2).num_eq(&0) {
Err(zero_divisor_eval_error(stub_gen)) Err(zero_divisor_eval_error(stub_gen))
} else { } else {
Ok(Number::arena_from(Integer::from(n1) / &*n2, arena)) 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)) => { (Number::Integer(n1), Number::Integer(n2)) => {
if &*n2 == &0 { if (&*n2).num_eq(&0) {
Err(zero_divisor_eval_error(stub_gen)) Err(zero_divisor_eval_error(stub_gen))
} else { } else {
Ok(Number::arena_from( Ok(Number::arena_from(
<(Integer, Integer)>::from(n1.div_rem_floor_ref(&*n2)).0, <(Integer, Integer)>::from((&*n1).div_rem(&*n2)).0,
arena, arena,
)) ))
} }
@@ -666,9 +668,15 @@ pub(crate) fn shr(n1: Number, n2: Number, arena: &mut Arena) -> Result<Number, M
(Number::Fixnum(n1), Number::Integer(n2)) => { (Number::Fixnum(n1), Number::Integer(n2)) => {
let n1 = Integer::from(n1.get_num()); let n1 = Integer::from(n1.get_num());
match n2.to_usize() { let result: Result<usize, _> = (&*n2).try_into();
Some(n2) => Ok(Number::arena_from(n1 >> n2, arena)),
_ => Ok(Number::arena_from(n1 >> usize::max_value(), arena)), 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()) { (Number::Integer(n1), Number::Fixnum(n2)) => match usize::try_from(n2.get_num()) {
@@ -678,12 +686,17 @@ pub(crate) fn shr(n1: Number, n2: Number, arena: &mut Arena) -> Result<Number, M
arena, arena,
)), )),
}, },
(Number::Integer(n1), Number::Integer(n2)) => match n2.to_usize() { (Number::Integer(n1), Number::Integer(n2)) => {
Some(n2) => Ok(Number::arena_from(Integer::from(&*n1 >> n2), arena)), let result: Result<usize, _> = (&*n2).try_into();
_ => Ok(Number::arena_from(
Integer::from(&*n1 >> usize::max_value()), match result {
arena, 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::Integer(_), n2) => Err(numerical_type_error(ValidType::Integer, n2, stub_gen)),
(Number::Fixnum(_), n2) => Err(numerical_type_error(ValidType::Integer, n2, stub_gen)), (Number::Fixnum(_), n2) => Err(numerical_type_error(ValidType::Integer, n2, stub_gen)),
@@ -717,9 +730,14 @@ pub(crate) fn shl(n1: Number, n2: Number, arena: &mut Arena) -> Result<Number, M
(Number::Fixnum(n1), Number::Integer(n2)) => { (Number::Fixnum(n1), Number::Integer(n2)) => {
let n1 = Integer::from(n1.get_num()); let n1 = Integer::from(n1.get_num());
match n2.to_u32() { match (&*n2).try_into() as Result<u32, _> {
Some(n2) => Ok(Number::arena_from(n1.to_u64().unwrap() << n2, arena)), Ok(n2) => {
_ => Ok(Number::arena_from(n1 << usize::max_value(), arena)), let n1: u64 = n1.try_into().unwrap();
Ok(Number::arena_from(n1 << n2, arena))
},
_ => {
Ok(Number::arena_from(n1 << usize::max_value(), arena))
}
} }
} }
(Number::Integer(n1), Number::Fixnum(n2)) => match usize::try_from(n2.get_num()) { (Number::Integer(n1), Number::Fixnum(n2)) => match usize::try_from(n2.get_num()) {
@@ -729,15 +747,14 @@ pub(crate) fn shl(n1: Number, n2: Number, arena: &mut Arena) -> Result<Number, M
arena, arena,
)), )),
}, },
(Number::Integer(n1), Number::Integer(n2)) => match n2.to_u32() { (Number::Integer(n1), Number::Integer(n2)) => match (&*n2).try_into() as Result<u32, _> {
Some(n2) => Ok(Number::arena_from( Ok(n2) => {
Integer::from(n1.to_u64().unwrap() << n2), let n1: u64 = (&*n1).try_into().unwrap();
arena, Ok(Number::arena_from(Integer::from(n1 << n2), arena))
)), },
_ => Ok(Number::arena_from( _ => {
Integer::from(&*n1 << usize::max_value()), Ok(Number::arena_from(Integer::from(&*n1 << usize::max_value()),arena))
arena, }
)),
}, },
(Number::Integer(_), n2) => Err(numerical_type_error(ValidType::Integer, n2, stub_gen)), (Number::Integer(_), n2) => Err(numerical_type_error(ValidType::Integer, n2, stub_gen)),
(Number::Fixnum(_), n2) => Err(numerical_type_error(ValidType::Integer, n2, stub_gen)), (Number::Fixnum(_), n2) => Err(numerical_type_error(ValidType::Integer, n2, stub_gen)),
@@ -848,12 +865,12 @@ pub(crate) fn modulus(x: Number, y: Number, arena: &mut Arena) -> Result<Number,
} }
} }
(Number::Fixnum(n1), Number::Integer(n2)) => { (Number::Fixnum(n1), Number::Integer(n2)) => {
if &*n2 == &0 { if (&*n2).num_eq(&0) {
Err(zero_divisor_eval_error(stub_gen)) Err(zero_divisor_eval_error(stub_gen))
} else { } else {
let n1 = Integer::from(n1.get_num()); let n1 = Integer::from(n1.get_num());
Ok(Number::arena_from( Ok(Number::arena_from(
<(Integer, Integer)>::from(n1.div_rem_floor_ref(&*n2)).1, <(Integer, Integer)>::from(n1.div_rem(&*n2)).1,
arena, arena,
)) ))
} }
@@ -866,17 +883,17 @@ pub(crate) fn modulus(x: Number, y: Number, arena: &mut Arena) -> Result<Number,
} else { } else {
let n2 = Integer::from(n2_i); let n2 = Integer::from(n2_i);
Ok(Number::arena_from( Ok(Number::arena_from(
<(Integer, Integer)>::from(n1.div_rem_floor_ref(&n2)).1, <(Integer, Integer)>::from((&*n1).div_rem(&n2)).1,
arena, arena,
)) ))
} }
} }
(Number::Integer(x), Number::Integer(y)) => { (Number::Integer(x), Number::Integer(y)) => {
if &*y == &0 { if (&*y).num_eq(&0) {
Err(zero_divisor_eval_error(stub_gen)) Err(zero_divisor_eval_error(stub_gen))
} else { } else {
Ok(Number::arena_from( Ok(Number::arena_from(
<(Integer, Integer)>::from(x.div_rem_floor_ref(&*y)).1, <(Integer, Integer)>::from((&*x).div_rem(&*y)).1,
arena, arena,
)) ))
} }
@@ -906,7 +923,7 @@ pub(crate) fn remainder(x: Number, y: Number, arena: &mut Arena) -> Result<Numbe
} }
} }
(Number::Fixnum(n1), Number::Integer(n2)) => { (Number::Fixnum(n1), Number::Integer(n2)) => {
if &*n2 == &0 { if (&*n2).num_eq(&0) {
Err(zero_divisor_eval_error(stub_gen)) Err(zero_divisor_eval_error(stub_gen))
} else { } else {
let n1 = Integer::from(n1.get_num()); let n1 = Integer::from(n1.get_num());
@@ -924,7 +941,7 @@ pub(crate) fn remainder(x: Number, y: Number, arena: &mut Arena) -> Result<Numbe
} }
} }
(Number::Integer(n1), Number::Integer(n2)) => { (Number::Integer(n1), Number::Integer(n2)) => {
if &*n2 == &0 { if (&*n2).num_eq(&0) {
Err(zero_divisor_eval_error(stub_gen)) Err(zero_divisor_eval_error(stub_gen))
} else { } else {
Ok(Number::arena_from(Integer::from(&*n1 % &*n2), arena)) Ok(Number::arena_from(Integer::from(&*n1 % &*n2), arena))
@@ -962,10 +979,8 @@ pub(crate) fn gcd(n1: Number, n2: Number, arena: &mut Arena) -> Result<Number, M
} }
(Number::Integer(n1), Number::Integer(n2)) => { (Number::Integer(n1), Number::Integer(n2)) => {
let n1_clone: Integer = (*n1).clone(); let n1_clone: Integer = (*n1).clone();
Ok(Number::arena_from( let n2: isize = (&*n2).try_into().unwrap();
Integer::from(n1_clone.gcd(&Integer::from(n2.to_isize().unwrap()))) as IBig, Ok(Number::arena_from(Integer::from(n1_clone.gcd(&Integer::from(n2))) as IBig, arena))
arena,
))
} }
(Number::Float(f), _) | (_, Number::Float(f)) => { (Number::Float(f), _) | (_, Number::Float(f)) => {
let n = Number::Float(f); let n = Number::Float(f);

View File

@@ -246,7 +246,10 @@ pub(crate) fn to_local_code_ptr(heap: &Heap, addr: HeapCellValue) -> Option<usiz
let extract_integer = |s: usize| -> Option<usize> { let extract_integer = |s: usize| -> Option<usize> {
match Number::try_from(heap[s]) { match Number::try_from(heap[s]) {
Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).ok(), 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).try_into().unwrap();
Some(value)
},
_ => None, _ => None,
} }
}; };

View File

@@ -1636,11 +1636,10 @@ impl Machine {
let arity = self.deref_register(3); let arity = self.deref_register(3);
let arity = match Number::try_from(arity) { let arity = match Number::try_from(arity) {
Ok(Number::Integer(n)) Ok(Number::Integer(n)) if &*n >= &Integer::from(0) && &*n <= &Integer::from(MAX_ARITY) => {
if &*n >= &Integer::from(0) && &*n <= &Integer::from(MAX_ARITY) => let value: usize = (&*n).try_into().unwrap();
{ Ok(value)
Ok(n.to_usize().unwrap()) },
}
Ok(Number::Fixnum(n)) if n.get_num() >= 0 && n.get_num() <= MAX_ARITY as i64 => { Ok(Number::Fixnum(n)) if n.get_num() >= 0 && n.get_num() <= MAX_ARITY as i64 => {
Ok(usize::try_from(n.get_num()).unwrap()) Ok(usize::try_from(n.get_num()).unwrap())
} }
@@ -2202,7 +2201,10 @@ impl Machine {
.store(self.machine_st.deref(self.machine_st[temp_v!(3)])); .store(self.machine_st.deref(self.machine_st[temp_v!(3)]));
let target_pos = match Number::try_from(target_pos) { 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).try_into().unwrap();
value
},
Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).unwrap(), Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).unwrap(),
_ => unreachable!(), _ => unreachable!(),
}; };

View File

@@ -885,8 +885,10 @@ impl MachineState {
} }
} }
Ok(Number::Integer(n)) => { Ok(Number::Integer(n)) => {
if let Some(n) = n.to_usize() { let result = (&*n).try_into();
printer.max_depth = n;
if let Ok(value) = result {
printer.max_depth = value;
} else { } else {
self.fail = true; self.fail = true;
return Ok(None); return Ok(None);

View File

@@ -16,6 +16,7 @@ use crate::parser::dashu::{Integer, Rational};
use crate::types::*; use crate::types::*;
use indexmap::IndexSet; use indexmap::IndexSet;
use num_order::NumOrd;
use std::cmp::Ordering; use std::cmp::Ordering;
use std::convert::TryFrom; use std::convert::TryFrom;
@@ -294,12 +295,12 @@ impl MachineState {
pub fn unify_big_int(&mut self, n1: TypedArenaPtr<Integer>, value: HeapCellValue) { pub fn unify_big_int(&mut self, n1: TypedArenaPtr<Integer>, value: HeapCellValue) {
let mut unifier = DefaultUnifier::from(self); 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) { pub fn unify_rational(&mut self, n1: TypedArenaPtr<Rational>, value: HeapCellValue) {
let mut unifier = DefaultUnifier::from(self); 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) { pub fn unify_f64(&mut self, f1: F64Ptr, value: HeapCellValue) {
@@ -1182,7 +1183,10 @@ impl MachineState {
let n = match n { let n = match n {
Number::Fixnum(n) => n.get_num() as usize, 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).try_into().unwrap();
value
},
_ => { _ => {
self.fail = true; self.fail = true;
return Ok(()); return Ok(());
@@ -1399,9 +1403,15 @@ impl MachineState {
let err = self.domain_error(DomainErrorType::NotLessThanZero, n); let err = self.domain_error(DomainErrorType::NotLessThanZero, n);
return Err(self.error_form(err, stub_gen())); 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::Fixnum(n)) => n.get_num(),
Ok(Number::Integer(n)) => n.to_i64().unwrap(), Ok(Number::Integer(n)) => {
let value: i64 = (&*n).try_into().unwrap();
value
},
Err(_) => { Err(_) => {
return type_error(arity); return type_error(arity);
} }
@@ -1678,9 +1688,9 @@ impl MachineState {
Err(_) => {} Err(_) => {}
}, },
Ok(Number::Integer(n)) => { Ok(Number::Integer(n)) => {
if let Some(b) = n.to_u8() { let b: u8 = (&*n).try_into().unwrap();
bytes.push(b);
} bytes.push(b);
} }
_ => {} _ => {}
} }

View File

@@ -58,7 +58,10 @@ fn setup_predicate_indicator(term: &mut Term) -> Result<PredicateKey, Compilatio
let name = terms.pop().unwrap(); let name = terms.pop().unwrap();
let arity = match arity { let arity = match arity {
Term::Literal(_, Literal::Integer(n)) => n.to_usize(), Term::Literal(_, Literal::Integer(n)) => {
let value: usize = (&*n).try_into().unwrap();
Some(value)
},
Term::Literal(_, Literal::Fixnum(n)) => usize::try_from(n.get_num()).ok(), Term::Literal(_, Literal::Fixnum(n)) => usize::try_from(n.get_num()).ok(),
_ => None, _ => None,
} }

View File

@@ -1,8 +1,10 @@
use crate::parser::ast::*; use crate::parser::ast::*;
use crate::parser::parser::*; use crate::parser::parser::*;
use dashu::integer::Sign;
use dashu::integer::UBig; use dashu::integer::UBig;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use num_order::NumOrd;
use crate::arena::*; use crate::arena::*;
use crate::atom_table::*; use crate::atom_table::*;
@@ -759,7 +761,11 @@ impl MachineState {
let max_steps_n = match max_steps { let max_steps_n = match max_steps {
Ok(Number::Fixnum(n)) => Some(n.get_num()), Ok(Number::Fixnum(n)) => Some(n.get_num()),
Ok(Number::Integer(n)) => n.to_i64(), Ok(Number::Integer(n)) => {
let value: i64 = (&*n).try_into().unwrap();
Some(value)
},
_ => None, _ => None,
}; };
@@ -1119,7 +1125,8 @@ impl MachineState {
_ => {} _ => {}
}, },
Ok(Number::Integer(n)) => { Ok(Number::Integer(n)) => {
if let Some(c) = n.to_u32().and_then(std::char::from_u32) { let n: u32 = (&*n).try_into().unwrap();
if let Some(c) = std::char::from_u32(n) {
string.push(c); string.push(c);
continue; continue;
} }
@@ -1782,7 +1789,10 @@ impl Machine {
let reg = self.deref_register(2); let reg = self.deref_register(2);
let n = match Number::try_from(reg) { let n = match Number::try_from(reg) {
Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).ok(), 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).try_into().unwrap();
Some(value)
},
_ => { _ => {
unreachable!() unreachable!()
} }
@@ -2530,8 +2540,9 @@ impl Machine {
addr if addr.is_var() => addr, addr if addr.is_var() => addr,
addr => match Number::try_from(addr) { addr => match Number::try_from(addr) {
Ok(Number::Integer(n)) => { Ok(Number::Integer(n)) => {
if let Some(nb) = n.to_u8() { let result: Result<u8, _> = (&*n).try_into();
fixnum_as_cell!(Fixnum::build_with(nb as i64)) if let Ok(value) = result {
fixnum_as_cell!(Fixnum::build_with(value as i64))
} else { } else {
let err = self.machine_st.type_error(ValidType::InByte, addr); let err = self.machine_st.type_error(ValidType::InByte, addr);
return Err(self.machine_st.error_form(err, stub_gen())); return Err(self.machine_st.error_form(err, stub_gen()));
@@ -2725,9 +2736,9 @@ impl Machine {
_ => { _ => {
match Number::try_from(a2) { match Number::try_from(a2) {
Ok(Number::Integer(n)) => { Ok(Number::Integer(n)) => {
let n = n let n: u32 = (&*n).try_into().unwrap();
.to_u32()
.and_then(|n| std::char::from_u32(n).and_then(|_| Some(n))); let n = std::char::from_u32(n).and_then(|_| Some(n));
if let Some(n) = n { if let Some(n) = n {
fixnum_as_cell!(Fixnum::build_with(n as i64)) fixnum_as_cell!(Fixnum::build_with(n as i64))
@@ -2901,7 +2912,9 @@ impl Machine {
_ => { _ => {
match Number::try_from(a2) { match Number::try_from(a2) {
Ok(Number::Integer(n)) => { Ok(Number::Integer(n)) => {
let c = match n.to_u32().and_then(std::char::from_u32) { let n: u32 = (&*n).try_into().unwrap();
let n = std::char::from_u32(n);
let c = match n {
Some(c) => c, Some(c) => c,
_ => { _ => {
let err = self.machine_st.representation_error(RepFlag::CharacterCode); let err = self.machine_st.representation_error(RepFlag::CharacterCode);
@@ -3136,7 +3149,9 @@ impl Machine {
} else { } else {
match Number::try_from(addr) { match Number::try_from(addr) {
Ok(Number::Integer(n)) => { Ok(Number::Integer(n)) => {
if let Some(c) = n.to_u32().and_then(|c| char::try_from(c).ok()) { let n: u32 = (&*n).try_into().unwrap();
let n = char::try_from(n);
if let Some(c) = n.ok() {
write!(&mut stream, "{}", c).unwrap(); write!(&mut stream, "{}", c).unwrap();
return Ok(()); return Ok(());
} }
@@ -3279,17 +3294,21 @@ impl Machine {
} else { } else {
match Number::try_from(addr) { match Number::try_from(addr) {
Ok(Number::Integer(n)) => { Ok(Number::Integer(n)) => {
if let Some(nb) = n.to_u8() { let n: u8 = (&*n).try_into().unwrap();
match stream.write(&mut [nb]) {
Ok(1) => { match n {
return Ok(()); nb => {
} match stream.write(&mut [nb]) {
_ => { Ok(1) => {
let err = self.machine_st.existence_error(ExistenceError::Stream( return Ok(());
stream_as_cell!(stream), }
)); _ => {
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()));
}
} }
} }
} }
@@ -3359,15 +3378,17 @@ impl Machine {
addr addr
} else { } else {
match Number::try_from(addr) { 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)) fixnum_as_cell!(Fixnum::build_with(-1))
} }
Ok(Number::Fixnum(n)) if n.get_num() == -1_i64 => { Ok(Number::Fixnum(n)) if n.get_num() == -1_i64 => {
fixnum_as_cell!(Fixnum::build_with(-1)) fixnum_as_cell!(Fixnum::build_with(-1))
} }
Ok(Number::Integer(n)) => { Ok(Number::Integer(n)) => {
if let Some(nb) = n.to_u8() { let n: Result<u8, _> = (&*n).try_into();
fixnum_as_cell!(Fixnum::build_with(nb as i64))
if let Ok(value) = n {
fixnum_as_cell!(Fixnum::build_with(value as i64))
} else { } else {
let err = self.machine_st.type_error(ValidType::InByte, addr); let err = self.machine_st.type_error(ValidType::InByte, addr);
return Err(self.machine_st.error_form(err, stub_gen())); return Err(self.machine_st.error_form(err, stub_gen()));
@@ -3519,8 +3540,10 @@ impl Machine {
let num = match Number::try_from(self.deref_register(2)) { let num = match Number::try_from(self.deref_register(2)) {
Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).unwrap(), Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).unwrap(),
Ok(Number::Integer(n)) => match n.to_usize() { Ok(Number::Integer(n)) => match (&*n).try_into() as Result<usize, _> {
Some(u) => u, Ok(u) => {
u
}
_ => { _ => {
self.machine_st.fail = true; self.machine_st.fail = true;
return Ok(()); return Ok(());
@@ -3613,7 +3636,8 @@ impl Machine {
} else { } else {
match Number::try_from(addr) { match Number::try_from(addr) {
Ok(Number::Integer(n)) => { Ok(Number::Integer(n)) => {
let n = n.to_u32().and_then(|n| std::char::from_u32(n)); let n: u32 = (&*n).try_into().unwrap();
let n = std::char::from_u32(n);
if let Some(n) = n { if let Some(n) = n {
fixnum_as_cell!(Fixnum::build_with(n as i64)) fixnum_as_cell!(Fixnum::build_with(n as i64))
@@ -3965,7 +3989,10 @@ impl Machine {
let arity = match Number::try_from(arity) { let arity = match Number::try_from(arity) {
Ok(Number::Fixnum(n)) => Some(n.get_num() as usize), 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).try_into().unwrap();
Some(value)
},
_ => None, _ => None,
}; };
@@ -4316,9 +4343,9 @@ impl Machine {
let n = match Number::try_from(len) { let n = match Number::try_from(len) {
Ok(Number::Fixnum(n)) => n.get_num() as usize, Ok(Number::Fixnum(n)) => n.get_num() as usize,
Ok(Number::Integer(n)) => match n.to_usize() { Ok(Number::Integer(n)) => match (&*n).try_into() as Result<usize, _> {
Some(n) => n, Ok(n) => n,
None => { Err(_) => {
let err = self.machine_st.resource_error(len); let err = self.machine_st.resource_error(len);
return Err(self.machine_st.error_form(err, stub_gen())); return Err(self.machine_st.error_form(err, stub_gen()));
} }
@@ -4628,24 +4655,24 @@ impl Machine {
#[cfg(feature = "http")] #[cfg(feature = "http")]
#[inline(always)] #[inline(always)]
pub(crate) fn http_answer(&mut self) -> CallResult { pub(crate) fn http_answer(&mut self) -> CallResult {
let culprit = self.deref_register(1); let culprit = self.deref_register(1);
let status_code = self.deref_register(2); let status_code = self.deref_register(2);
let status_code: u16 = match Number::try_from(status_code) { let status_code: u16 = match Number::try_from(status_code) {
Ok(Number::Fixnum(n)) => n.get_num() as u16, Ok(Number::Fixnum(n)) => n.get_num() as u16,
Ok(Number::Integer(n)) => match n.to_u16() { Ok(Number::Integer(n)) => {
Some(u) => u, let n: Result<u16, _> = (&*n).try_into();
_ => {
self.machine_st.fail = true; if let Ok(value) = n {
return Ok(()); value
} } else {
}, self.machine_st.fail = true;
_ => unreachable!(), return Ok(());
}; }
let stub_gen = || functor_stub(atom!("http_listen"), 2); }
let headers = match self _ => unreachable!()
.machine_st };
.try_from_list(self.machine_st.registers[3], stub_gen) let stub_gen = || functor_stub(atom!("http_listen"), 2);
{ let headers = match self.machine_st.try_from_list(self.machine_st.registers[3], stub_gen) {
Ok(addrs) => { Ok(addrs) => {
let mut header_map = HeaderMap::new(); let mut header_map = HeaderMap::new();
for heap_cell in addrs { for heap_cell in addrs {
@@ -4937,7 +4964,10 @@ impl Machine {
let specifier = cell_as_atom_cell!(self.deref_register(2)).get_name(); let specifier = cell_as_atom_cell!(self.deref_register(2)).get_name();
let priority = match Number::try_from(priority) { let priority = match Number::try_from(priority) {
Ok(Number::Integer(n)) => n.to_u16().unwrap(), Ok(Number::Integer(n)) => {
let n: u16 = (&*n).try_into().unwrap();
n
},
Ok(Number::Fixnum(n)) => u16::try_from(n.get_num()).unwrap(), Ok(Number::Fixnum(n)) => u16::try_from(n.get_num()).unwrap(),
_ => { _ => {
unreachable!(); unreachable!();
@@ -5094,7 +5124,10 @@ impl Machine {
let addr = self.deref_register(1); let addr = self.deref_register(1);
let b = match Number::try_from(addr) { let b = match Number::try_from(addr) {
Ok(Number::Integer(n)) => n.to_usize(), Ok(Number::Integer(n)) => {
let value: usize = (&*n).try_into().unwrap();
Some(value)
},
Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).ok(), Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).ok(),
_ => { _ => {
self.machine_st.fail = true; self.machine_st.fail = true;
@@ -5477,12 +5510,16 @@ impl Machine {
let code = match Number::try_from(code) { let code = match Number::try_from(code) {
Ok(Number::Fixnum(n)) => u8::try_from(n.get_num()).unwrap(), 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).try_into().unwrap();
n
},
Ok(Number::Rational(r)) => { Ok(Number::Rational(r)) => {
// n has already been confirmed as an integer, and // n has already been confirmed as an integer, and
// internally, Rational is assumed reduced, so its // internally, Rational is assumed reduced, so its
// denominator must be 1. // denominator must be 1.
r.numerator().to_u8().unwrap() let r = r.numerator().try_into().unwrap();
r
} }
_ => { _ => {
unreachable!() unreachable!()
@@ -5512,7 +5549,10 @@ impl Machine {
let n = match Number::try_from(a2) { let n = match Number::try_from(a2) {
Ok(Number::Fixnum(bp)) => bp.get_num() as usize, 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).try_into().unwrap();
value
},
_ => { _ => {
let stub = functor_stub(atom!("call_with_inference_limit"), 3); let stub = functor_stub(atom!("call_with_inference_limit"), 3);
@@ -5525,8 +5565,9 @@ impl Machine {
let a3 = self.deref_register(3); let a3 = self.deref_register(3);
let count = self.machine_st.cwil.add_limit(n, bp); let count = self.machine_st.cwil.add_limit(n, bp);
if let Some(count) = count.to_i64() { let result = count.try_into();
self.machine_st.unify_fixnum(Fixnum::build_with(count), a3); if let Ok(value) = result{
self.machine_st.unify_fixnum(Fixnum::build_with(value), a3);
} else { } else {
let count = arena_alloc!(count.clone(), &mut self.machine_st.arena); let count = arena_alloc!(count.clone(), &mut self.machine_st.arena);
self.machine_st.unify_big_int(count, a3); self.machine_st.unify_big_int(count, a3);
@@ -5553,8 +5594,10 @@ impl Machine {
let arity = match Number::try_from(a3) { let arity = match Number::try_from(a3) {
Ok(Number::Fixnum(n)) => n.get_num() as usize, Ok(Number::Fixnum(n)) => n.get_num() as usize,
Ok(Number::Integer(n)) => { Ok(Number::Integer(n)) => {
if let Some(n) = n.to_usize() { let result = (&*n).try_into();
n
if let Ok(value) = result {
value
} else { } else {
return false; return false;
} }
@@ -5677,8 +5720,9 @@ impl Machine {
let count = self.machine_st.cwil.remove_limit(bp).clone(); let count = self.machine_st.cwil.remove_limit(bp).clone();
if let Some(count) = count.to_i64() { let result = count.clone().try_into();
self.machine_st.unify_fixnum(Fixnum::build_with(count), a2); if let Ok(value) = result{
self.machine_st.unify_fixnum(Fixnum::build_with(value), a2);
} else { } else {
let count = arena_alloc!(count.clone(), &mut self.machine_st.arena); let count = arena_alloc!(count.clone(), &mut self.machine_st.arena);
self.machine_st.unify_big_int(count, a2); self.machine_st.unify_big_int(count, a2);
@@ -6222,14 +6266,17 @@ impl Machine {
match Number::try_from(seed) { match Number::try_from(seed) {
Ok(Number::Fixnum(n)) => { 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)) => { Ok(Number::Integer(n)) => {
let _: StdRng = SeedableRng::seed_from_u64(n.to_u64().unwrap()); let n: u64 = (&*n).try_into().unwrap();
} let _: StdRng = SeedableRng::seed_from_u64(n);
},
Ok(Number::Rational(n)) => { Ok(Number::Rational(n)) => {
if n.denominator() == &UBig::from(1 as u32) { 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);
} }
} }
_ => { _ => {
@@ -6664,7 +6711,8 @@ impl Machine {
let position = match Number::try_from(position) { let position = match Number::try_from(position) {
Ok(Number::Fixnum(n)) => n.get_num() as u64, Ok(Number::Fixnum(n)) => n.get_num() as u64,
Ok(Number::Integer(n)) => { Ok(Number::Integer(n)) => {
if let Some(n) = n.to_u64() { let n: Result<u64, _> = (&*n).try_into();
if let Ok(n) = n {
n n
} else { } else {
self.machine_st.fail = true; self.machine_st.fail = true;
@@ -6947,7 +6995,10 @@ impl Machine {
let arity = match Number::try_from(arity) { let arity = match Number::try_from(arity) {
Ok(Number::Fixnum(n)) => n.get_num() as usize, 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).try_into().unwrap();
value
},
_ => { _ => {
unreachable!() unreachable!()
} }
@@ -7000,7 +7051,10 @@ impl Machine {
let index_ptr = self.deref_register(1); let index_ptr = self.deref_register(1);
let index_ptr = match Number::try_from(index_ptr) { let index_ptr = match Number::try_from(index_ptr) {
Ok(Number::Fixnum(n)) => n.get_num() as usize, 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).try_into().unwrap();
value
},
_ => { _ => {
unreachable!() unreachable!()
} }
@@ -7287,8 +7341,8 @@ impl Machine {
let length = match Number::try_from(length) { let length = match Number::try_from(length) {
Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).unwrap(), Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).unwrap(),
Ok(Number::Integer(n)) => match n.to_usize() { Ok(Number::Integer(n)) => match (&*n).try_into() as Result<usize, _> {
Some(u) => u, Ok(u) => u,
_ => { _ => {
self.machine_st.fail = true; self.machine_st.fail = true;
return; return;
@@ -7351,11 +7405,14 @@ impl Machine {
let iterations = match Number::try_from(iterations) { let iterations = match Number::try_from(iterations) {
Ok(Number::Fixnum(n)) => u64::try_from(n.get_num()).unwrap(), Ok(Number::Fixnum(n)) => u64::try_from(n.get_num()).unwrap(),
Ok(Number::Integer(n)) => match n.to_u64() { Ok(Number::Integer(n)) => {
Some(i) => i, let n: Result<u64, _> = (&*n).try_into();
None => { match n {
self.machine_st.fail = true; Ok(i) => i,
return; _ => {
self.machine_st.fail = true;
return;
}
} }
}, },
_ => { _ => {
@@ -7991,7 +8048,10 @@ impl Machine {
Number::Fixnum(Fixnum::build_with(n.get_num().count_ones() as i64)) Number::Fixnum(Fixnum::build_with(n.get_num().count_ones() as i64))
} }
Ok(Number::Integer(n)) => { 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).clone().into_parts().1).count_ones()
} else { 0 };
Number::arena_from(value, &mut self.machine_st.arena)
} }
_ => { _ => {
unreachable!() unreachable!()

View File

@@ -12,6 +12,7 @@ use std::ops::{Deref, DerefMut};
use derive_deref::*; use derive_deref::*;
use fxhash::FxBuildHasher; use fxhash::FxBuildHasher;
use indexmap::IndexSet; use indexmap::IndexSet;
use num_order::NumOrd;
pub(crate) trait Unifier: DerefMut<Target = MachineState> { pub(crate) trait Unifier: DerefMut<Target = MachineState> {
fn unify_structure(&mut self, s1: usize, value: HeapCellValue) { fn unify_structure(&mut self, s1: usize, value: HeapCellValue) {
@@ -426,8 +427,8 @@ pub(crate) trait Unifier: DerefMut<Target = MachineState> {
match Number::try_from(value) { match Number::try_from(value) {
Ok(n2) => match n2 { Ok(n2) => match n2 {
Number::Fixnum(n2) if n1.get_num() == n2.get_num() => {} Number::Fixnum(n2) if n1.get_num() == n2.get_num() => {}
Number::Integer(n2) if n1.get_num() == *n2 => {} Number::Integer(n2) if (*n2).num_eq(&n1.get_num()) => {}
Number::Rational(n2) if n1.get_num() == *n2 => {} Number::Rational(n2) if (*n2).num_eq(&Integer::from(n1.get_num())) => {}
_ => { _ => {
self.fail = true; self.fail = true;
} }
@@ -462,6 +463,48 @@ pub(crate) trait Unifier: DerefMut<Target = MachineState> {
} }
} }
fn unify_big_integer(&mut self, n1: TypedArenaPtr<Integer>, value: HeapCellValue) {
if let Some(r) = value.as_var() {
Self::bind(self, r, typed_arena_ptr_as_cell!(n1));
return;
}
match Number::try_from(value) {
Ok(n2) => match n2 {
Number::Fixnum(n2) if (*n1).num_eq(&n2.get_num()) => {}
Number::Integer(n2) if (*n1).num_eq(&*n2) => {}
Number::Rational(n2) if (*n2).num_eq(&*n1) => {}
_ => {
self.fail = true;
}
},
Err(_) => {
self.fail = true;
}
}
}
fn unify_big_rational(&mut self, n1: TypedArenaPtr<Rational>, value: HeapCellValue) {
if let Some(r) = value.as_var() {
Self::bind(self, r, typed_arena_ptr_as_cell!(n1));
return;
}
match Number::try_from(value) {
Ok(n2) => match n2 {
Number::Fixnum(n2) if (*n1).num_eq(&Integer::from(n2.get_num())) => {}
Number::Integer(n2) if (*n1).num_eq(&*n2) => {}
Number::Rational(n2) if n1 == n2 => {}
_ => {
self.fail = true;
}
},
Err(_) => {
self.fail = true;
}
}
}
fn unify_f64(&mut self, f1: F64Ptr, value: HeapCellValue) { fn unify_f64(&mut self, f1: F64Ptr, value: HeapCellValue) {
if let Some(r) = value.as_var() { if let Some(r) = value.as_var() {
Self::bind(self, r, HeapCellValue::from(f1)); Self::bind(self, r, HeapCellValue::from(f1));
@@ -487,10 +530,10 @@ pub(crate) trait Unifier: DerefMut<Target = MachineState> {
match_untyped_arena_ptr!(ptr, match_untyped_arena_ptr!(ptr,
(ArenaHeaderTag::Integer, int_ptr) => { (ArenaHeaderTag::Integer, int_ptr) => {
Self::unify_big_num(self, int_ptr, value); Self::unify_big_integer(self, int_ptr, value);
} }
(ArenaHeaderTag::Rational, rat_ptr) => { (ArenaHeaderTag::Rational, rat_ptr) => {
Self::unify_big_num(self, rat_ptr, value); Self::unify_big_rational(self, rat_ptr, value);
} }
(ArenaHeaderTag::Stream, stream) => { (ArenaHeaderTag::Stream, stream) => {
read_heap_cell!(value, read_heap_cell!(value,