mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-24 18:32:28 -05:00
LibJS: Add left shift & right shift operator support for BigIntegers
Based on https://tc39.es/ecma262/#sec-numeric-types-bigint-leftShift (This commit also includes the matching tests)
This commit is contained in:
parent
4ee58d36c0
commit
67a5e9f018
2 changed files with 14 additions and 4 deletions
|
@ -787,8 +787,13 @@ Value left_shift(GlobalObject& global_object, Value lhs, Value rhs)
|
||||||
auto rhs_u32 = rhs_numeric.to_u32(global_object);
|
auto rhs_u32 = rhs_numeric.to_u32(global_object);
|
||||||
return Value(lhs_i32 << rhs_u32);
|
return Value(lhs_i32 << rhs_u32);
|
||||||
}
|
}
|
||||||
if (both_bigint(lhs_numeric, rhs_numeric))
|
if (both_bigint(lhs_numeric, rhs_numeric)) {
|
||||||
TODO();
|
auto multiplier_divisor = Crypto::SignedBigInteger { Crypto::NumberTheory::Power(Crypto::UnsignedBigInteger(2), rhs_numeric.as_bigint().big_integer().unsigned_value()) };
|
||||||
|
if (rhs_numeric.as_bigint().big_integer().is_negative())
|
||||||
|
return js_bigint(global_object.heap(), lhs_numeric.as_bigint().big_integer().divided_by(multiplier_divisor).quotient);
|
||||||
|
else
|
||||||
|
return js_bigint(global_object.heap(), lhs_numeric.as_bigint().big_integer().multiplied_by(multiplier_divisor));
|
||||||
|
}
|
||||||
global_object.vm().throw_exception<TypeError>(global_object, ErrorType::BigIntBadOperatorOtherType, "left-shift");
|
global_object.vm().throw_exception<TypeError>(global_object, ErrorType::BigIntBadOperatorOtherType, "left-shift");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -813,8 +818,11 @@ Value right_shift(GlobalObject& global_object, Value lhs, Value rhs)
|
||||||
auto rhs_u32 = rhs_numeric.to_u32(global_object);
|
auto rhs_u32 = rhs_numeric.to_u32(global_object);
|
||||||
return Value(lhs_i32 >> rhs_u32);
|
return Value(lhs_i32 >> rhs_u32);
|
||||||
}
|
}
|
||||||
if (both_bigint(lhs_numeric, rhs_numeric))
|
if (both_bigint(lhs_numeric, rhs_numeric)) {
|
||||||
TODO();
|
auto rhs_negated = rhs_numeric.as_bigint().big_integer();
|
||||||
|
rhs_negated.negate();
|
||||||
|
return left_shift(global_object, lhs, js_bigint(global_object.heap(), rhs_negated));
|
||||||
|
}
|
||||||
global_object.vm().throw_exception<TypeError>(global_object, ErrorType::BigIntBadOperatorOtherType, "right-shift");
|
global_object.vm().throw_exception<TypeError>(global_object, ErrorType::BigIntBadOperatorOtherType, "right-shift");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,8 @@ describe("correct behavior", () => {
|
||||||
expect(1n | 2n).toBe(3n);
|
expect(1n | 2n).toBe(3n);
|
||||||
expect(5n ^ 3n).toBe(6n);
|
expect(5n ^ 3n).toBe(6n);
|
||||||
expect(~1n).toBe(-2n);
|
expect(~1n).toBe(-2n);
|
||||||
|
expect(5n << 2n).toBe(20n);
|
||||||
|
expect(7n >> 1n).toBe(3n);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("increment operators", () => {
|
test("increment operators", () => {
|
||||||
|
|
Loading…
Add table
Reference in a new issue