|
|
|
@ -28,7 +28,7 @@ impl Value {
|
|
|
|
|
(Self::Null, Self::Null) => true, |
|
|
|
|
|
|
|
|
|
// 3. Return ! SameValueNonNumeric(x, y).
|
|
|
|
|
(_, _) => same_value_non_numeric(self, other), |
|
|
|
|
(_, _) => Self::same_value_non_numeric(self, other), |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -111,6 +111,74 @@ impl Value {
|
|
|
|
|
_ => false, |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// The internal comparison abstract operation SameValue(x, y),
|
|
|
|
|
/// where x and y are ECMAScript language values, produces true or false.
|
|
|
|
|
///
|
|
|
|
|
/// More information:
|
|
|
|
|
/// - [ECMAScript][spec]
|
|
|
|
|
///
|
|
|
|
|
/// [spec]: https://tc39.es/ecma262/#sec-samevalue
|
|
|
|
|
pub fn same_value(x: &Value, y: &Value) -> bool { |
|
|
|
|
// 1. If Type(x) is different from Type(y), return false.
|
|
|
|
|
if x.get_type() != y.get_type() { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
match (x, y) { |
|
|
|
|
// 2. If Type(x) is Number or BigInt, then
|
|
|
|
|
// a. Return ! Type(x)::SameValue(x, y).
|
|
|
|
|
(Value::BigInt(x), Value::BigInt(y)) => BigInt::same_value(x, y), |
|
|
|
|
(Value::Rational(x), Value::Rational(y)) => Number::same_value(*x, *y), |
|
|
|
|
(Value::Rational(x), Value::Integer(y)) => Number::same_value(*x, f64::from(*y)), |
|
|
|
|
(Value::Integer(x), Value::Rational(y)) => Number::same_value(f64::from(*x), *y), |
|
|
|
|
(Value::Integer(x), Value::Integer(y)) => x == y, |
|
|
|
|
|
|
|
|
|
// 3. Return ! SameValueNonNumeric(x, y).
|
|
|
|
|
(_, _) => Self::same_value_non_numeric(x, y), |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// The internal comparison abstract operation `SameValueZero(x, y)`,
|
|
|
|
|
/// where `x` and `y` are ECMAScript language values, produces `true` or `false`.
|
|
|
|
|
///
|
|
|
|
|
/// `SameValueZero` differs from SameValue only in its treatment of `+0` and `-0`.
|
|
|
|
|
///
|
|
|
|
|
/// More information:
|
|
|
|
|
/// - [ECMAScript][spec]
|
|
|
|
|
///
|
|
|
|
|
/// [spec]: https://tc39.es/ecma262/#sec-samevaluezero
|
|
|
|
|
pub fn same_value_zero(x: &Value, y: &Value) -> bool { |
|
|
|
|
if x.get_type() != y.get_type() { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
match (x, y) { |
|
|
|
|
// 2. If Type(x) is Number or BigInt, then
|
|
|
|
|
// a. Return ! Type(x)::SameValueZero(x, y).
|
|
|
|
|
(Value::BigInt(x), Value::BigInt(y)) => BigInt::same_value_zero(x, y), |
|
|
|
|
|
|
|
|
|
(Value::Rational(x), Value::Rational(y)) => Number::same_value_zero(*x, *y), |
|
|
|
|
(Value::Rational(x), Value::Integer(y)) => Number::same_value_zero(*x, f64::from(*y)), |
|
|
|
|
(Value::Integer(x), Value::Rational(y)) => Number::same_value_zero(f64::from(*x), *y), |
|
|
|
|
(Value::Integer(x), Value::Integer(y)) => x == y, |
|
|
|
|
|
|
|
|
|
// 3. Return ! SameValueNonNumeric(x, y).
|
|
|
|
|
(_, _) => Self::same_value_non_numeric(x, y), |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn same_value_non_numeric(x: &Value, y: &Value) -> bool { |
|
|
|
|
debug_assert!(x.get_type() == y.get_type()); |
|
|
|
|
match (x, y) { |
|
|
|
|
(Value::Null, Value::Null) | (Value::Undefined, Value::Undefined) => true, |
|
|
|
|
(Value::String(ref x), Value::String(ref y)) => x == y, |
|
|
|
|
(Value::Boolean(x), Value::Boolean(y)) => x == y, |
|
|
|
|
(Value::Object(ref x), Value::Object(ref y)) => GcObject::equals(x, y), |
|
|
|
|
(Value::Symbol(ref x), Value::Symbol(ref y)) => x == y, |
|
|
|
|
_ => false, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// This function takes a string and conversts it to BigInt type.
|
|
|
|
@ -128,71 +196,3 @@ pub fn string_to_bigint(string: &str) -> Option<BigInt> {
|
|
|
|
|
|
|
|
|
|
BigInt::from_str(string) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// The internal comparison abstract operation SameValue(x, y),
|
|
|
|
|
/// where x and y are ECMAScript language values, produces true or false.
|
|
|
|
|
///
|
|
|
|
|
/// More information:
|
|
|
|
|
/// - [ECMAScript][spec]
|
|
|
|
|
///
|
|
|
|
|
/// [spec]: https://tc39.es/ecma262/#sec-samevalue
|
|
|
|
|
pub fn same_value(x: &Value, y: &Value) -> bool { |
|
|
|
|
// 1. If Type(x) is different from Type(y), return false.
|
|
|
|
|
if x.get_type() != y.get_type() { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
match (x, y) { |
|
|
|
|
// 2. If Type(x) is Number or BigInt, then
|
|
|
|
|
// a. Return ! Type(x)::SameValue(x, y).
|
|
|
|
|
(Value::BigInt(x), Value::BigInt(y)) => BigInt::same_value(x, y), |
|
|
|
|
(Value::Rational(x), Value::Rational(y)) => Number::same_value(*x, *y), |
|
|
|
|
(Value::Rational(x), Value::Integer(y)) => Number::same_value(*x, f64::from(*y)), |
|
|
|
|
(Value::Integer(x), Value::Rational(y)) => Number::same_value(f64::from(*x), *y), |
|
|
|
|
(Value::Integer(x), Value::Integer(y)) => x == y, |
|
|
|
|
|
|
|
|
|
// 3. Return ! SameValueNonNumeric(x, y).
|
|
|
|
|
(_, _) => same_value_non_numeric(x, y), |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// The internal comparison abstract operation `SameValueZero(x, y)`,
|
|
|
|
|
/// where `x` and `y` are ECMAScript language values, produces `true` or `false`.
|
|
|
|
|
///
|
|
|
|
|
/// `SameValueZero` differs from SameValue only in its treatment of `+0` and `-0`.
|
|
|
|
|
///
|
|
|
|
|
/// More information:
|
|
|
|
|
/// - [ECMAScript][spec]
|
|
|
|
|
///
|
|
|
|
|
/// [spec]: https://tc39.es/ecma262/#sec-samevaluezero
|
|
|
|
|
pub fn same_value_zero(x: &Value, y: &Value) -> bool { |
|
|
|
|
if x.get_type() != y.get_type() { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
match (x, y) { |
|
|
|
|
// 2. If Type(x) is Number or BigInt, then
|
|
|
|
|
// a. Return ! Type(x)::SameValueZero(x, y).
|
|
|
|
|
(Value::BigInt(x), Value::BigInt(y)) => BigInt::same_value_zero(x, y), |
|
|
|
|
|
|
|
|
|
(Value::Rational(x), Value::Rational(y)) => Number::same_value_zero(*x, *y), |
|
|
|
|
(Value::Rational(x), Value::Integer(y)) => Number::same_value_zero(*x, f64::from(*y)), |
|
|
|
|
(Value::Integer(x), Value::Rational(y)) => Number::same_value_zero(f64::from(*x), *y), |
|
|
|
|
(Value::Integer(x), Value::Integer(y)) => x == y, |
|
|
|
|
|
|
|
|
|
// 3. Return ! SameValueNonNumeric(x, y).
|
|
|
|
|
(_, _) => same_value_non_numeric(x, y), |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn same_value_non_numeric(x: &Value, y: &Value) -> bool { |
|
|
|
|
debug_assert!(x.get_type() == y.get_type()); |
|
|
|
|
match (x, y) { |
|
|
|
|
(Value::Null, Value::Null) | (Value::Undefined, Value::Undefined) => true, |
|
|
|
|
(Value::String(ref x), Value::String(ref y)) => x == y, |
|
|
|
|
(Value::Boolean(x), Value::Boolean(y)) => x == y, |
|
|
|
|
(Value::Object(ref x), Value::Object(ref y)) => GcObject::equals(x, y), |
|
|
|
|
(Value::Symbol(ref x), Value::Symbol(ref y)) => x == y, |
|
|
|
|
_ => false, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|