Fixed missing functionality in dashu with their methods still has some issue with move

This commit is contained in:
Fayeed Pawaskar
2023-07-21 14:21:32 +05:30
parent cf345d8174
commit b4e7000eb2
12 changed files with 328 additions and 97 deletions

View File

@@ -1,3 +1,6 @@
use dashu::base::Abs;
use dashu::base::Gcd;
use dashu::integer::IBig;
use divrem::*;
use crate::arena::*;
@@ -159,7 +162,7 @@ pub(crate) fn add(lhs: Number, rhs: Number, arena: &mut Arena) -> Result<Number,
Ok(Number::Float(add_f(float_fn_to_f(n1.get_num())?, n2)?))
}
(Number::Integer(n1), Number::Integer(n2)) => {
Ok(Number::arena_from(Integer::from(&*n1) + &*n2, arena)) // add_i
Ok(Number::arena_from(&*n1 + &*n2, arena)) // add_i
}
(Number::Integer(n1), Number::Float(OrderedFloat(n2)))
| (Number::Float(OrderedFloat(n2)), Number::Integer(n1)) => {
@@ -167,7 +170,7 @@ pub(crate) fn add(lhs: Number, rhs: Number, arena: &mut Arena) -> Result<Number,
}
(Number::Integer(n1), Number::Rational(n2))
| (Number::Rational(n2), Number::Integer(n1)) => {
Ok(Number::arena_from(Rational::from(&*n1) + &*n2, arena))
Ok(Number::arena_from(&*n1 + &*n2, arena))
}
(Number::Rational(n1), Number::Float(OrderedFloat(n2)))
| (Number::Float(OrderedFloat(n2)), Number::Rational(n1)) => {
@@ -177,7 +180,7 @@ pub(crate) fn add(lhs: Number, rhs: Number, arena: &mut Arena) -> Result<Number,
Ok(Number::Float(add_f(f1, f2)?))
}
(Number::Rational(r1), Number::Rational(r2)) => {
Ok(Number::arena_from(Rational::from(&*r1) + &*r2, arena))
Ok(Number::arena_from(&*r1 + &*r2, arena))
}
}
}
@@ -191,9 +194,9 @@ pub(crate) fn neg(n: Number, arena: &mut Arena) -> Number {
Number::arena_from(-Integer::from(n.get_num()), arena)
}
}
Number::Integer(n) => Number::arena_from(-Integer::from(&*n), arena),
Number::Integer(n) => Number::arena_from(-Integer::from(*n.clone()), arena),
Number::Float(OrderedFloat(f)) => Number::Float(OrderedFloat(-f)),
Number::Rational(r) => Number::arena_from(-Rational::from(&*r), arena),
Number::Rational(r) => Number::arena_from(-Rational::from(*r), arena),
}
}
@@ -203,12 +206,13 @@ pub(crate) fn abs(n: Number, arena: &mut Arena) -> Number {
if let Some(n) = n.get_num().checked_abs() {
fixnum!(Number, n, arena)
} else {
Number::arena_from(Integer::from(n.get_num()).abs(), arena)
let arena_int = Integer::from(n.get_num());
Number::arena_from(arena_int.abs(), arena)
}
}
Number::Integer(n) => Number::arena_from(Integer::from(n.abs_ref()), arena),
Number::Integer(n) => Number::arena_from(Integer::from(n.abs()), arena),
Number::Float(f) => Number::Float(f.abs()),
Number::Rational(r) => Number::arena_from(Rational::from(r.abs_ref()), arena),
Number::Rational(r) => Number::arena_from(Rational::from(r.abs()), arena),
}
}
@@ -247,7 +251,7 @@ pub(crate) fn mul(lhs: Number, rhs: Number, arena: &mut Arena) -> Result<Number,
Ok(Number::Float(mul_f(float_fn_to_f(n1.get_num())?, n2)?))
}
(Number::Integer(n1), Number::Integer(n2)) => {
Ok(Number::arena_from(Integer::from(&*n1) * &*n2, arena)) // mul_i
Ok(Number::arena_from(Integer::from(*n1) * &*n2, arena)) // mul_i
}
(Number::Integer(n1), Number::Float(OrderedFloat(n2)))
| (Number::Float(OrderedFloat(n2)), Number::Integer(n1)) => {
@@ -255,7 +259,7 @@ pub(crate) fn mul(lhs: Number, rhs: Number, arena: &mut Arena) -> Result<Number,
}
(Number::Integer(n1), Number::Rational(n2))
| (Number::Rational(n2), Number::Integer(n1)) => {
Ok(Number::arena_from(Rational::from(&*n1) * &*n2, arena))
Ok(Number::arena_from(Rational::from(*n1) * &*n2, arena))
}
(Number::Rational(n1), Number::Float(OrderedFloat(n2)))
| (Number::Float(OrderedFloat(n2)), Number::Rational(n1)) => {
@@ -265,7 +269,7 @@ pub(crate) fn mul(lhs: Number, rhs: Number, arena: &mut Arena) -> Result<Number,
Ok(Number::Float(mul_f(f1, f2)?))
}
(Number::Rational(r1), Number::Rational(r2)) => {
Ok(Number::arena_from(Rational::from(&*r1) * &*r2, arena))
Ok(Number::arena_from(Rational::from(*r1) * &*r2, arena))
}
}
}
@@ -521,7 +525,7 @@ pub fn rational_from_number(
match n {
Number::Fixnum(n) => Ok(arena_alloc!(Rational::from(n.get_num()), arena)),
Number::Rational(r) => Ok(r),
Number::Float(OrderedFloat(f)) => match Rational::from_f64(f) {
Number::Float(OrderedFloat(f)) => match Rational::simplest_from_f64(f) {
Some(r) => Ok(arena_alloc!(r, arena)),
None => Err(Box::new(move |machine_st| {
let instantiation_error = machine_st.instantiation_error();
@@ -530,7 +534,7 @@ pub fn rational_from_number(
machine_st.error_form(instantiation_error, stub)
})),
},
Number::Integer(n) => Ok(arena_alloc!(Rational::from(&*n), arena)),
Number::Integer(n) => Ok(arena_alloc!(Rational::from(*n), arena)),
}
}
@@ -590,7 +594,7 @@ pub(crate) fn idiv(n1: Number, n2: Number, arena: &mut Arena) -> Result<Number,
Err(zero_divisor_eval_error(stub_gen))
} else {
Ok(Number::arena_from(
<(Integer, Integer)>::from(n1.div_rem_ref(&*n2)).0,
<(Integer, Integer)>::from(n1.div_rem_floor_ref(&*n2)).0,
arena,
))
}
@@ -696,7 +700,7 @@ pub(crate) fn shl(n1: Number, n2: Number, arena: &mut Arena) -> Result<Number, M
let n1 = Integer::from(n1.get_num());
match n2.to_u32() {
Some(n2) => Ok(Number::arena_from(n1 << n2, arena)),
Some(n2) => Ok(Number::arena_from(n1.to_u64().unwrap() << n2, arena)),
_ => {
Ok(Number::arena_from(n1 << usize::max_value(), arena))
}
@@ -709,7 +713,7 @@ pub(crate) fn shl(n1: Number, n2: Number, arena: &mut Arena) -> Result<Number, M
}
},
(Number::Integer(n1), Number::Integer(n2)) => match n2.to_u32() {
Some(n2) => Ok(Number::arena_from(Integer::from(&*n1 << n2), arena)),
Some(n2) => Ok(Number::arena_from(Integer::from(n1.to_u64().unwrap() << n2), arena)),
_ => {
Ok(Number::arena_from(Integer::from(&*n1 << usize::max_value()),arena))
}
@@ -926,18 +930,19 @@ pub(crate) fn gcd(n1: Number, n2: Number, arena: &mut Arena) -> Result<Number, M
if let Some(result) = isize_gcd(n1_i, n2_i) {
Ok(Number::arena_from(result, arena))
} else {
let value: IBig = Integer::from(n1_i).gcd(&Integer::from(n2_i)).into();
Ok(Number::arena_from(
Integer::from(n1_i).gcd(&Integer::from(n2_i)),
value,
arena,
))
}
}
(Number::Fixnum(n1), Number::Integer(n2)) | (Number::Integer(n2), Number::Fixnum(n1)) => {
let n1 = Integer::from(n1.get_num());
Ok(Number::arena_from(Integer::from(n2.gcd_ref(&n1)), arena))
Ok(Number::arena_from(Integer::from(n2.gcd(&n1)), arena))
}
(Number::Integer(n1), Number::Integer(n2)) => {
Ok(Number::arena_from(Integer::from(n1.gcd_ref(&n2)), arena))
Ok(Number::arena_from(Integer::from(n1.gcd(&Integer::from(n2.to_isize().unwrap()))) as IBig, arena))
}
(Number::Float(f), _) | (_, Number::Float(f)) => {
let n = Number::Float(f);

View File

@@ -6,9 +6,10 @@ use crate::machine::loader::*;
use crate::machine::machine_errors::CompilationError;
use crate::machine::preprocessor::*;
use crate::parser::ast::*;
use crate::parser::dashu::{Rational, Integer};
use crate::parser::dashu::Rational;
use crate::variable_records::*;
use dashu::Integer;
use indexmap::{IndexMap, IndexSet};
use std::cell::Cell;

View File

@@ -2540,7 +2540,7 @@ impl Machine {
self.machine_st.p += 1;
}
Ok(Number::Rational(n)) => {
if n.denom() == &1 {
if n.denominator().is_one() {
self.machine_st.p += 1;
} else {
self.machine_st.backtrack();
@@ -2559,7 +2559,7 @@ impl Machine {
self.machine_st.p = self.machine_st.cp;
}
Ok(Number::Rational(n)) => {
if n.denom() == &1 {
if n.denominator().is_one() {
self.machine_st.p = self.machine_st.cp;
} else {
self.machine_st.backtrack();

View File

@@ -1387,7 +1387,7 @@ impl MachineState {
Ok(Number::Float(_)) => {
return type_error(arity);
}
Ok(Number::Rational(n)) if n.denom() != &1 => {
Ok(Number::Rational(n)) if !n.denominator().is_one() => {
return type_error(arity);
}
Ok(n) if n > MAX_ARITY => {
@@ -1400,7 +1400,7 @@ impl MachineState {
let err = self.domain_error(DomainErrorType::NotLessThanZero, n);
return Err(self.error_form(err, stub_gen()));
}
Ok(Number::Rational(n)) => n.numer().to_i64().unwrap(),
Ok(Number::Rational(n)) => n.numerator().to_i64().unwrap(),
Ok(Number::Fixnum(n)) => n.get_num(),
Ok(Number::Integer(n)) => n.to_i64().unwrap(),
Err(_) => {

View File

@@ -905,4 +905,4 @@ impl Machine {
}
}
}
}
}

View File

@@ -1,6 +1,7 @@
use crate::parser::ast::*;
use crate::parser::parser::*;
use dashu::integer::UBig;
use lazy_static::lazy_static;
use crate::arena::*;
@@ -28,6 +29,8 @@ use crate::parser::dashu::Integer;
use crate::parser::rug::rand::RandState;
use crate::read::*;
use crate::types::*;
use rand::{Rng, SeedableRng};
use rand::rngs::StdRng;
use ordered_float::OrderedFloat;
@@ -36,10 +39,12 @@ use indexmap::IndexSet;
use ref_thread_local::{RefThreadLocal, ref_thread_local};
use std::borrow::BorrowMut;
use std::cell::Cell;
use std::cmp::Ordering;
use std::collections::BTreeSet;
use std::convert::{TryFrom, Infallible};
use std::convert::Infallible;
use std::convert::TryFrom;
use std::env;
use std::ffi::CString;
use std::fs;
@@ -2727,7 +2732,7 @@ impl Machine {
// n has already been confirmed as an integer, and
// internally, Rational is assumed reduced, so its denominator
// must be 1.
r.numer().to_string()
r.numerator().to_string()
}
_ => {
unreachable!()
@@ -2756,7 +2761,7 @@ impl Machine {
// n has already been confirmed as an integer, and
// internally, Rational is assumed reduced, so its
// denominator must be 1.
r.numer().to_string()
r.numerator().to_string()
}
_ => {
unreachable!()
@@ -4103,10 +4108,25 @@ impl Machine {
}
#[inline(always)]
pub(crate) fn maybe(&mut self) {
pub(crate) fn maybe(&mut self) {
fn generate_random_bits(num_bits: usize) -> u64 {
let mut rng = rand::thread_rng();
let rand = rng.borrow_mut();
let mut random_bits: u64 = 0;
for _ in 0..num_bits {
random_bits <<= 1;
if rand.gen_bool(0.5) {
random_bits |= 1;
}
}
random_bits
}
let result = {
let mut rand = RANDOM_STATE.borrow_mut();
rand.bits(1) == 0
generate_random_bits(1) == 0
};
self.machine_st.fail = result;
@@ -5189,7 +5209,7 @@ impl Machine {
// n has already been confirmed as an integer, and
// internally, Rational is assumed reduced, so its
// denominator must be 1.
r.numer().to_i32().unwrap()
r.numerator().to_i32().unwrap()
}
_ => {
unreachable!()
@@ -5804,12 +5824,20 @@ impl Machine {
#[inline(always)]
pub(crate) fn set_seed(&mut self) {
let seed = self.deref_register(1);
let mut rand = RANDOM_STATE.borrow_mut();
match Number::try_from(seed) {
Ok(Number::Fixnum(n)) => rand.seed(&Integer::from(n)),
Ok(Number::Integer(n)) => rand.seed(&*n),
Ok(Number::Rational(n)) if n.denom() == &1 => rand.seed(n.numer()),
Ok(Number::Fixnum(n)) => {
let _: StdRng = SeedableRng::seed_from_u64(Integer::from(n).to_u64().unwrap());
},
Ok(Number::Integer(n)) => {
let _: StdRng = SeedableRng::seed_from_u64(n.to_u64().unwrap());
},
Ok(Number::Rational(n)) => {
if n.denominator() == &UBig::from(1 as u32) {
let _: StdRng = SeedableRng::seed_from_u64(n.numerator().to_u64().unwrap());
}
},
_ => {
self.machine_st.fail = true;
}
@@ -5823,7 +5851,7 @@ impl Machine {
let time = match Number::try_from(time) {
Ok(Number::Float(n)) => n.into_inner(),
Ok(Number::Fixnum(n)) => n.get_num() as f64,
Ok(Number::Integer(n)) => n.to_f64(),
Ok(Number::Integer(n)) => n.to_f64().value(),
_ => {
unreachable!()
}
@@ -7469,7 +7497,7 @@ impl Machine {
Number::Fixnum(Fixnum::build_with(n.get_num().count_ones() as i64))
}
Ok(Number::Integer(n)) => {
Number::arena_from(n.count_ones().unwrap(), &mut self.machine_st.arena)
Number::arena_from(n.count_ones(), &mut self.machine_st.arena)
}
_ => {
unreachable!()