-
-
Notifications
You must be signed in to change notification settings - Fork 407
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
19 changed files
with
736 additions
and
548 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
use super::BigInt; | ||
|
||
use crate::{ | ||
builtins::{Number, Value}, | ||
exec::Interpreter, | ||
}; | ||
use num_traits::cast::{FromPrimitive, ToPrimitive}; | ||
|
||
use std::convert::TryFrom; | ||
use std::str::FromStr; | ||
|
||
impl BigInt { | ||
/// This function takes a string and conversts it to BigInt type. | ||
/// | ||
/// More information: | ||
/// - [ECMAScript reference][spec] | ||
/// | ||
/// [spec]: https://tc39.es/ecma262/#sec-stringtobigint | ||
#[inline] | ||
pub(crate) fn from_string(string: &str, _ctx: &mut Interpreter) -> Result<Self, Value> { | ||
if string.is_empty() { | ||
return Ok(BigInt::from(0)); | ||
} | ||
|
||
match num_bigint::BigInt::from_str(string) { | ||
Ok(bigint) => Ok(Self(bigint)), | ||
_ => panic!("SyntaxError: cannot convert {} to a BigInt", string), | ||
} | ||
} | ||
|
||
/// Converts a string to a BigInt with the specified radix. | ||
#[inline] | ||
pub fn from_string_radix(buf: &str, radix: u32) -> Option<Self> { | ||
num_bigint::BigInt::parse_bytes(buf.as_bytes(), radix).map(Self) | ||
} | ||
|
||
/// Convert bigint to string with radix. | ||
#[inline] | ||
pub fn to_string_radix(&self, radix: u32) -> String { | ||
self.0.to_str_radix(radix) | ||
} | ||
|
||
/// Converts the BigInt to a f64 type. | ||
/// | ||
/// Returns `std::f64::INFINITY` if the BigInt is too big. | ||
#[inline] | ||
pub fn to_f64(&self) -> f64 { | ||
self.0.to_f64().unwrap_or(std::f64::INFINITY) | ||
} | ||
|
||
#[inline] | ||
pub(crate) fn from_str(string: &str) -> Option<Self> { | ||
match num_bigint::BigInt::from_str(string) { | ||
Ok(bigint) => Some(BigInt(bigint)), | ||
Err(_) => None, | ||
} | ||
} | ||
} | ||
|
||
impl From<i64> for BigInt { | ||
fn from(n: i64) -> BigInt { | ||
BigInt(num_bigint::BigInt::from(n)) | ||
} | ||
} | ||
|
||
impl From<i32> for BigInt { | ||
fn from(n: i32) -> BigInt { | ||
BigInt(num_bigint::BigInt::from(n)) | ||
} | ||
} | ||
|
||
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] | ||
pub struct TryFromF64Error; | ||
|
||
impl std::fmt::Display for TryFromF64Error { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
write!(f, "Could not convert f64 value to a BigInt type") | ||
} | ||
} | ||
|
||
impl TryFrom<f64> for BigInt { | ||
type Error = TryFromF64Error; | ||
|
||
fn try_from(n: f64) -> Result<Self, Self::Error> { | ||
// If the truncated version of the number is not the | ||
// same as the non-truncated version then the floating-point | ||
// number conains a fractional part. | ||
if !Number::equal(n.trunc(), n) { | ||
return Err(TryFromF64Error); | ||
} | ||
match num_bigint::BigInt::from_f64(n) { | ||
Some(bigint) => Ok(BigInt(bigint)), | ||
None => Err(TryFromF64Error), | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
use super::BigInt; | ||
|
||
impl BigInt { | ||
/// Checks for `SameValueZero` equality. | ||
/// | ||
/// More information: | ||
/// - [ECMAScript reference][spec] | ||
/// | ||
/// [spec]: https://tc39.es/ecma262/#sec-numeric-types-bigint-equal | ||
#[inline] | ||
pub(crate) fn same_value_zero(x: &Self, y: &Self) -> bool { | ||
// Return BigInt::equal(x, y) | ||
Self::equal(x, y) | ||
} | ||
|
||
/// Checks for `SameValue` equality. | ||
/// | ||
/// | ||
/// More information: | ||
/// - [ECMAScript reference][spec] | ||
/// | ||
/// [spec]: https://tc39.es/ecma262/#sec-numeric-types-bigint-sameValue | ||
#[inline] | ||
pub(crate) fn same_value(x: &Self, y: &Self) -> bool { | ||
// Return BigInt::equal(x, y) | ||
Self::equal(x, y) | ||
} | ||
|
||
/// Checks for mathematical equality. | ||
/// | ||
/// The abstract operation BigInt::equal takes arguments x (a `BigInt`) and y (a `BigInt`). | ||
/// It returns `true` if x and y have the same mathematical integer value and false otherwise. | ||
/// | ||
/// More information: | ||
/// - [ECMAScript reference][spec] | ||
/// | ||
/// [spec]: https://tc39.es/ecma262/#sec-numeric-types-bigint-sameValueZero | ||
#[inline] | ||
pub(crate) fn equal(x: &Self, y: &Self) -> bool { | ||
x == y | ||
} | ||
} | ||
|
||
impl PartialEq<i32> for BigInt { | ||
fn eq(&self, other: &i32) -> bool { | ||
self.0 == num_bigint::BigInt::from(*other) | ||
} | ||
} | ||
|
||
impl PartialEq<BigInt> for i32 { | ||
fn eq(&self, other: &BigInt) -> bool { | ||
num_bigint::BigInt::from(*self) == other.0 | ||
} | ||
} | ||
|
||
impl PartialEq<f64> for BigInt { | ||
fn eq(&self, other: &f64) -> bool { | ||
if other.fract() != 0.0 { | ||
return false; | ||
} | ||
|
||
self.0 == num_bigint::BigInt::from(*other as i64) | ||
} | ||
} | ||
|
||
impl PartialEq<BigInt> for f64 { | ||
fn eq(&self, other: &BigInt) -> bool { | ||
if self.fract() != 0.0 { | ||
return false; | ||
} | ||
|
||
num_bigint::BigInt::from(*self as i64) == other.0 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.