aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gleam/int.gleam54
-rw-r--r--src/gleam_stdlib.mjs29
2 files changed, 83 insertions, 0 deletions
diff --git a/src/gleam/int.gleam b/src/gleam/int.gleam
index c0e650e..2324bb0 100644
--- a/src/gleam/int.gleam
+++ b/src/gleam/int.gleam
@@ -800,3 +800,57 @@ pub fn multiply(a: Int, b: Int) -> Int {
pub fn subtract(a: Int, b: Int) -> Int {
a - b
}
+
+/// Calculates the bitwise AND of its arguments.
+pub fn bitwise_and(x: Int, y: Int) -> Int {
+ do_and(x, y)
+}
+
+@external(erlang, "erlang", "band")
+@external(javascript, "../gleam_stdlib.mjs", "bitwise_and")
+fn do_and(a: Int, b: Int) -> Int
+
+/// Calculates the bitwise NOT of its argument.
+pub fn bitwise_not(x: Int) -> Int {
+ do_not(x)
+}
+
+@external(erlang, "erlang", "bnot")
+@external(javascript, "../gleam_stdlib.mjs", "bitwise_not")
+fn do_not(a: Int) -> Int
+
+/// Calculates the bitwise OR of its arguments.
+pub fn bitwise_or(x: Int, y: Int) -> Int {
+ do_or(x, y)
+}
+
+@external(erlang, "erlang", "bor")
+@external(javascript, "../gleam_stdlib.mjs", "bitwise_or")
+fn do_or(a: Int, b: Int) -> Int
+
+/// Calculates the bitwise XOR of its arguments.
+pub fn bitwise_exclusive_or(x: Int, y: Int) -> Int {
+ do_exclusive_or(x, y)
+}
+
+@external(erlang, "erlang", "bxor")
+@external(javascript, "../gleam_stdlib.mjs", "bitwise_exclusive_or")
+fn do_exclusive_or(a: Int, b: Int) -> Int
+
+/// Calculates the result of an arithmetic left bitshift.
+pub fn bitwise_shift_left(x: Int, y: Int) -> Int {
+ do_shift_left(x, y)
+}
+
+@external(erlang, "erlang", "bsl")
+@external(javascript, "../gleam_stdlib.mjs", "bitwise_shift_left")
+fn do_shift_left(a: Int, b: Int) -> Int
+
+/// Calculates the result of an arithmetic right bitshift.
+pub fn bitwise_shift_right(x: Int, y: Int) -> Int {
+ do_shift_right(x, y)
+}
+
+@external(erlang, "erlang", "bsr")
+@external(javascript, "../gleam_stdlib.mjs", "bitwise_shift_right")
+fn do_shift_right(a: Int, b: Int) -> Int
diff --git a/src/gleam_stdlib.mjs b/src/gleam_stdlib.mjs
index a2fbaa6..fb255d9 100644
--- a/src/gleam_stdlib.mjs
+++ b/src/gleam_stdlib.mjs
@@ -752,3 +752,32 @@ function try_get_field(value, field, or_else) {
export function byte_size(string) {
return new TextEncoder().encode(string).length;
}
+
+// In Javascript bitwise operations convert numbers to a sequence of 32 bits
+// while Erlang uses arbitrary precision.
+// To get around this problem and get consistent results use BigInt and then
+// downcast the value back to a Number value.
+
+export function bitwise_and(x, y) {
+ return Number(BigInt(x) & BigInt(y));
+}
+
+export function bitwise_not(x) {
+ return Number(~BigInt(x));
+}
+
+export function bitwise_or(x, y) {
+ return Number(BigInt(x) | BigInt(y));
+}
+
+export function bitwise_exclusive_or(x, y) {
+ return Number(BigInt(x) ^ BigInt(y));
+}
+
+export function bitwise_shift_left(x, y) {
+ return Number(BigInt(x) << BigInt(y));
+}
+
+export function bitwise_shift_right(x, y) {
+ return Number(BigInt(x) >> BigInt(y));
+}