diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gleam/int.gleam | 54 | ||||
-rw-r--r-- | src/gleam_stdlib.mjs | 29 |
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)); +} |