Skip to content

Commit

Permalink
feat(stdlib)!: Replace Int32 arithmatic functions with operators (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
spotandjake authored Dec 29, 2023
1 parent a4016f1 commit 8a69dd3
Show file tree
Hide file tree
Showing 3 changed files with 287 additions and 153 deletions.
54 changes: 29 additions & 25 deletions compiler/test/stdlib/int32.test.gr
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module Int32Test
include "int32"
from Int32 use *

from Pervasives use { (==) }
// Suppress warnings about using `fromNumber` on constants, since that's what we want to test.
let fromNumber = fromNumber
assert fromNumber(5) == 5l
Expand All @@ -16,50 +17,53 @@ assert toNumber(0l) == 0
assert fromUint32(1ul) == 1l
assert fromUint32(0xfffffffful) == -1l

from Int32 use { (==) }

assert lnot(0xffffffffl) == 0l
assert lnot(0l) == 0xffffffffl
assert lnot(0xf0f0f0f0l) == 0x0f0f0f0fl

assert land(0b1010l, 0b10l) == 0b10l
assert land(0b1010l, 0l) == 0l
assert (0b1010l & 0b10l) == 0b10l
assert (0b1010l & 0l) == 0l

assert lor(0b1010l, 0b0101l) == 0b1111l
assert lor(0b1010l, 0l) == 0b1010l
assert (0b1010l | 0b0101l) == 0b1111l
assert (0b1010l | 0l) == 0b1010l

assert lxor(0b1010l, 0b1101l) == 0b0111l
assert lxor(0b1010l, 0l) == 0b1010l
assert (0b1010l ^ 0b1101l) == 0b0111l
assert (0b1010l ^ 0l) == 0b1010l

assert shl(-1l, 1l) == -2l
assert shl(-1l, 2l) == -4l
assert shl(-1l, 3l) == -8l
assert shl(-2l, 63l) == 0l
assert shl(24l, 1l) == 48l
assert -1l << 1l == -2l
assert -1l << 2l == -4l
assert -1l << 3l == -8l
assert -2l << 63l == 0l
assert 24l << 1l == 48l

assert shr(-1l, 63l) == -1l
assert shr(-24l, 1l) == -12l
assert -1l >> 63l == -1l
assert -24l >> 1l == -12l

assert gt(5l, 4l)
assert gte(5l, 5l)
assert lt(5l, 17l)
assert lte(5l, 5l)
assert !gt(5l, 5l)
assert !gte(5l, 22l)
assert !lt(5l, -17l)
assert !lte(5l, 4l)
assert 5l > 4l
assert 5l >= 5l
assert 5l < 17l
assert 5l <= 5l
assert !(5l > 5l)
assert !(5l >= 22l)
assert !(5l < -17l)
assert !(5l <= 4l)

assert clz(0b11l) == 30l
assert ctz(0b11000l) == 3l
assert popcnt(0b1100110011l) == 6l
assert rotl(0b11l, 3l) == 0b11000l
assert rotr(0b110000l, 3l) == 0b110l

assert eq(5l, 5l)
assert !eq(5l, 55l)
assert ne(5l, 55l)
assert !ne(5l, 5l)
assert 5l == 5l
assert !(5l == 55l)
assert 5l != 55l
assert !(5l != 5l)
assert eqz(0l)
assert !eqz(-42l)

from Pervasives use { (==) }
// Regression #1339
let arr = [> 1, 2, 3]
assert arr[toNumber(1l)] == 2
82 changes: 50 additions & 32 deletions stdlib/int32.gr
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,11 @@ provide let decr = (value: Int32) => {
* @param y: The second operand
* @returns The sum of the two operands
*
* @since v0.2.0
* @since v0.6.0
* @history v0.2.0: Originally named `add`
*/
@unsafe
provide let add = (x: Int32, y: Int32) => {
provide let (+) = (x: Int32, y: Int32) => {
let xv = WasmI32.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
let yv = WasmI32.load(WasmI32.fromGrain(y), _VALUE_OFFSET)
let ptr = newInt32(xv + yv)
Expand All @@ -112,10 +113,11 @@ provide let add = (x: Int32, y: Int32) => {
* @param y: The second operand
* @returns The difference of the two operands
*
* @since v0.2.0
* @since v0.6.0
* @history v0.2.0: Originally named `sub`
*/
@unsafe
provide let sub = (x: Int32, y: Int32) => {
provide let (-) = (x: Int32, y: Int32) => {
let xv = WasmI32.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
let yv = WasmI32.load(WasmI32.fromGrain(y), _VALUE_OFFSET)
let ptr = newInt32(xv - yv)
Expand All @@ -129,10 +131,11 @@ provide let sub = (x: Int32, y: Int32) => {
* @param y: The second operand
* @returns The product of the two operands
*
* @since v0.2.0
* @since v0.6.0
* @history v0.2.0: Originally named `mul`
*/
@unsafe
provide let mul = (x: Int32, y: Int32) => {
provide let (*) = (x: Int32, y: Int32) => {
let xv = WasmI32.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
let yv = WasmI32.load(WasmI32.fromGrain(y), _VALUE_OFFSET)
let ptr = newInt32(xv * yv)
Expand All @@ -146,10 +149,11 @@ provide let mul = (x: Int32, y: Int32) => {
* @param y: The second operand
* @returns The quotient of its operands
*
* @since v0.2.0
* @since v0.6.0
* @history v0.2.0: Originally named `div`
*/
@unsafe
provide let div = (x: Int32, y: Int32) => {
provide let (/) = (x: Int32, y: Int32) => {
let xv = WasmI32.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
let yv = WasmI32.load(WasmI32.fromGrain(y), _VALUE_OFFSET)
let ptr = newInt32(xv / yv)
Expand All @@ -175,6 +179,7 @@ provide let rem = (x: Int32, y: Int32) => {

@unsafe
let abs = n => {
from WasmI32 use { (-) }
let mask = n >> 31n
(n ^ mask) - mask
}
Expand All @@ -189,10 +194,12 @@ let abs = n => {
*
* @throws ModuloByZero: When `y` is zero
*
* @since v0.2.0
* @since v0.6.0
* @history v0.2.0: Originally named `mod`
*/
@unsafe
provide let mod = (x: Int32, y: Int32) => {
provide let (%) = (x: Int32, y: Int32) => {
from WasmI32 use { (-) }
let xval = WasmI32.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
let yval = WasmI32.load(WasmI32.fromGrain(y), _VALUE_OFFSET)

Expand Down Expand Up @@ -253,10 +260,11 @@ provide let rotr = (value: Int32, amount: Int32) => {
* @param amount: The number of bits to shift by
* @returns The shifted value
*
* @since v0.2.0
* @since v0.6.0
* @history v0.2.0: Originally named `shl`
*/
@unsafe
provide let shl = (value: Int32, amount: Int32) => {
provide let (<<) = (value: Int32, amount: Int32) => {
let xv = WasmI32.load(WasmI32.fromGrain(value), _VALUE_OFFSET)
let yv = WasmI32.load(WasmI32.fromGrain(amount), _VALUE_OFFSET)
let ptr = newInt32(xv << yv)
Expand All @@ -270,10 +278,11 @@ provide let shl = (value: Int32, amount: Int32) => {
* @param amount: The amount to shift by
* @returns The shifted value
*
* @since v0.2.0
* @since v0.6.0
* @history v0.2.0: Originally named `shr`
*/
@unsafe
provide let shr = (value: Int32, amount: Int32) => {
provide let (>>) = (value: Int32, amount: Int32) => {
let xv = WasmI32.load(WasmI32.fromGrain(value), _VALUE_OFFSET)
let yv = WasmI32.load(WasmI32.fromGrain(amount), _VALUE_OFFSET)
let ptr = newInt32(xv >> yv)
Expand All @@ -287,10 +296,11 @@ provide let shr = (value: Int32, amount: Int32) => {
* @param y: The second value
* @returns `true` if the first value is equal to the second value or `false` otherwise
*
* @since v0.4.0
* @since v0.6.0
* @history v0.4.0: Originally named `eq`
*/
@unsafe
provide let eq = (x: Int32, y: Int32) => {
provide let (==) = (x: Int32, y: Int32) => {
let xv = WasmI32.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
let yv = WasmI32.load(WasmI32.fromGrain(y), _VALUE_OFFSET)
xv == yv
Expand All @@ -303,10 +313,11 @@ provide let eq = (x: Int32, y: Int32) => {
* @param y: The second value
* @returns `true` if the first value is not equal to the second value or `false` otherwise
*
* @since v0.4.0
* @since v0.6.0
* @history v0.4.0: Originally named `ne`
*/
@unsafe
provide let ne = (x: Int32, y: Int32) => {
provide let (!=) = (x: Int32, y: Int32) => {
let xv = WasmI32.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
let yv = WasmI32.load(WasmI32.fromGrain(y), _VALUE_OFFSET)
xv != yv
Expand All @@ -333,10 +344,11 @@ provide let eqz = (value: Int32) => {
* @param y: The second value
* @returns `true` if the first value is less than the second value or `false` otherwise
*
* @since v0.2.0
* @since v0.6.0
* @history v0.2.0: Originally named `lt`
*/
@unsafe
provide let lt = (x: Int32, y: Int32) => {
provide let (<) = (x: Int32, y: Int32) => {
let xv = WasmI32.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
let yv = WasmI32.load(WasmI32.fromGrain(y), _VALUE_OFFSET)
xv < yv
Expand All @@ -349,10 +361,11 @@ provide let lt = (x: Int32, y: Int32) => {
* @param y: The second value
* @returns `true` if the first value is greater than the second value or `false` otherwise
*
* @since v0.2.0
* @since v0.6.0
* @history v0.2.0: Originally named `gt`
*/
@unsafe
provide let gt = (x: Int32, y: Int32) => {
provide let (>) = (x: Int32, y: Int32) => {
let xv = WasmI32.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
let yv = WasmI32.load(WasmI32.fromGrain(y), _VALUE_OFFSET)
xv > yv
Expand All @@ -365,10 +378,11 @@ provide let gt = (x: Int32, y: Int32) => {
* @param y: The second value
* @returns `true` if the first value is less than or equal to the second value or `false` otherwise
*
* @since v0.2.0
* @since v0.6.0
* @history v0.2.0: Originally named `lte`
*/
@unsafe
provide let lte = (x: Int32, y: Int32) => {
provide let (<=) = (x: Int32, y: Int32) => {
let xv = WasmI32.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
let yv = WasmI32.load(WasmI32.fromGrain(y), _VALUE_OFFSET)
xv <= yv
Expand All @@ -381,10 +395,11 @@ provide let lte = (x: Int32, y: Int32) => {
* @param y: The second value
* @returns `true` if the first value is greater than or equal to the second value or `false` otherwise
*
* @since v0.2.0
* @since v0.6.0
* @history v0.2.0: Originally named `gte`
*/
@unsafe
provide let gte = (x: Int32, y: Int32) => {
provide let (>=) = (x: Int32, y: Int32) => {
let xv = WasmI32.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
let yv = WasmI32.load(WasmI32.fromGrain(y), _VALUE_OFFSET)
xv >= yv
Expand Down Expand Up @@ -412,10 +427,11 @@ provide let lnot = (value: Int32) => {
* @param y: The second operand
* @returns Containing a `1` in each bit position for which the corresponding bits of both operands are `1`
*
* @since v0.2.0
* @since v0.6.0
* @history v0.2.0: Originally named `land`
*/
@unsafe
provide let land = (x: Int32, y: Int32) => {
provide let (&) = (x: Int32, y: Int32) => {
let xv = WasmI32.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
let yv = WasmI32.load(WasmI32.fromGrain(y), _VALUE_OFFSET)
let ptr = newInt32(xv & yv)
Expand All @@ -429,10 +445,11 @@ provide let land = (x: Int32, y: Int32) => {
* @param y: The second operand
* @returns Containing a `1` in each bit position for which the corresponding bits of either or both operands are `1`
*
* @since v0.2.0
* @since v0.6.0
* @history v0.2.0: Originally named `lor`
*/
@unsafe
provide let lor = (x: Int32, y: Int32) => {
provide let (|) = (x: Int32, y: Int32) => {
let xv = WasmI32.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
let yv = WasmI32.load(WasmI32.fromGrain(y), _VALUE_OFFSET)
let ptr = newInt32(xv | yv)
Expand All @@ -446,10 +463,11 @@ provide let lor = (x: Int32, y: Int32) => {
* @param y: The second operand
* @returns Containing a `1` in each bit position for which the corresponding bits of either but not both operands are `1`
*
* @since v0.2.0
* @since v0.6.0
* @history v0.2.0: Originally named `lxor`
*/
@unsafe
provide let lxor = (x: Int32, y: Int32) => {
provide let (^) = (x: Int32, y: Int32) => {
let xv = WasmI32.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
let yv = WasmI32.load(WasmI32.fromGrain(y), _VALUE_OFFSET)
let ptr = newInt32(xv ^ yv)
Expand Down
Loading

0 comments on commit 8a69dd3

Please sign in to comment.