BigInts should be done
This commit is contained in:
parent
4a2c1927f5
commit
0cc19e0883
2 changed files with 133 additions and 3 deletions
|
@ -1,6 +1,135 @@
|
||||||
use num_bigint::BigInt;
|
use num_bigint::{BigInt, BigUint, ToBigInt};
|
||||||
|
|
||||||
#[derive(Debug)]
|
use super::{bool::JsBool, string::JsString};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
pub struct JsBigInt {
|
pub struct JsBigInt {
|
||||||
pub value: BigInt
|
pub value: BigInt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Implements https://tc39.es/ecma262/2023/#table-numeric-type-ops
|
||||||
|
impl JsBigInt {
|
||||||
|
pub fn unary_minus(&self) -> JsBigInt {
|
||||||
|
JsBigInt{
|
||||||
|
value: &self.value * -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bitwise_not(&self) -> JsBigInt {
|
||||||
|
JsBigInt{
|
||||||
|
value: !&self.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn exponentiate(&self, x: &JsBigInt) -> JsBigInt {
|
||||||
|
let (_, digits) = x.value.to_u32_digits();
|
||||||
|
JsBigInt{
|
||||||
|
value: self.value.pow(*digits.first().expect("Exponent bigint didn't have any digits"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn multiply(&self, x: &JsBigInt) -> JsBigInt {
|
||||||
|
JsBigInt{
|
||||||
|
value: &self.value * &x.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn divide(&self, x: &JsBigInt) -> JsBigInt {
|
||||||
|
JsBigInt{
|
||||||
|
value: &self.value / &x.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add(&self, x: &JsBigInt) -> JsBigInt {
|
||||||
|
JsBigInt{
|
||||||
|
value: &self.value + &x.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pre_add(&mut self) -> JsBigInt {
|
||||||
|
self.value += 1;
|
||||||
|
self.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn post_add(&mut self) -> JsBigInt {
|
||||||
|
let old = self.clone();
|
||||||
|
self.value += 1;
|
||||||
|
old
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn subtract(&self, x: &JsBigInt) -> JsBigInt {
|
||||||
|
JsBigInt{
|
||||||
|
value: &self.value - &x.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pre_subtract(&mut self) -> JsBigInt {
|
||||||
|
self.value -= 1;
|
||||||
|
self.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn post_subtract(&mut self) -> JsBigInt {
|
||||||
|
let old = self.clone();
|
||||||
|
self.value -= 1;
|
||||||
|
old
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn left_shift(&self, x: &JsBigInt) -> JsBigInt {
|
||||||
|
let (_, digits) = x.value.to_u32_digits();
|
||||||
|
JsBigInt{
|
||||||
|
value: &self.value << *digits.first().expect("Shift amount bigint didn't have any digits")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn right_shift_signed(&self, x: &JsBigInt) -> JsBigInt {
|
||||||
|
let (_, digits) = x.value.to_u32_digits();
|
||||||
|
JsBigInt{
|
||||||
|
value: &self.value >> *digits.first().expect("Shift amount bigint didn't have any digits")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn right_shift_unsigned(&self, x: &JsBigInt) -> JsBigInt {
|
||||||
|
let (_, digits) = x.value.to_u32_digits();
|
||||||
|
let (_, old_bytes) = self.value.to_bytes_be();
|
||||||
|
let u = BigUint::from_bytes_be(&old_bytes);
|
||||||
|
JsBigInt{
|
||||||
|
value: (u >> *digits.first().expect("Shift amount bigint didn't have any digits")).to_bigint().expect("Failed to convert BigUInt to BigInt")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn less_than(&self, x: &JsBigInt) -> JsBool {
|
||||||
|
JsBool { value: self.value < x.value }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn equal(&self, x: &JsBigInt) -> JsBool {
|
||||||
|
JsBool { value: self.value == x.value }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn same_value(&self, x: &JsBigInt) -> JsBool {
|
||||||
|
JsBool { value: std::ptr::eq(self, x) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bitwise_and(&self, x: &JsBigInt) -> JsBigInt {
|
||||||
|
JsBigInt{
|
||||||
|
value: &self.value & &x.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bitwise_xor(&self, x: &JsBigInt) -> JsBigInt {
|
||||||
|
JsBigInt{
|
||||||
|
value: &self.value ^ &x.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bitwise_or(&self, x: &JsBigInt) -> JsBigInt {
|
||||||
|
JsBigInt{
|
||||||
|
value: &self.value | &x.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_string(&self) -> JsString {
|
||||||
|
JsString {
|
||||||
|
value: self.value.to_string().into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use self::{big_int::JsBigInt, bool::JsBool, number::JsNumber, object::JsObject, string::JsString, symbol::JsSymbol};
|
use self::{big_int::JsBigInt, bool::JsBool, number::JsNumber, object::JsObject, string::JsString, symbol::JsSymbol};
|
||||||
|
|
||||||
|
// All Js primitive objects are wrappers around a single value
|
||||||
pub mod bool;
|
pub mod bool;
|
||||||
pub mod string;
|
pub mod string;
|
||||||
pub mod symbol;
|
pub mod symbol;
|
||||||
|
|
Loading…
Reference in a new issue