/* * Copyright 2016 Liam Palmer * * Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE.md file. */instanceLowerBound[Int32] {pubdefminValue(): Int32 = Int32.minValue()}instanceUpperBound[Int32] {pubdefmaxValue(): Int32 = Int32.maxValue()}pubmod Int32 {import java.lang.Integerimport java.lang.NumberFormatExceptionimport java.math.BigDecimalimport java.math.BigInteger////// Returns the number of bits used to represent an `Int32`.///pubdefsize(): Int32 = 32////// Returns the minimum number representable by an `Int32`.///pubdefminValue(): Int32 = leftShift(1, size()-1)////// Returns the maximum number representable by an `Int32`.///pubdefmaxValue(): Int32 = bitwiseNot(minValue())////// Returns the smaller of `x` and `y`.///pubdefmin(x: Int32, y: Int32): Int32 = if (x<=y) xelsey////// Returns the larger of `x` and `y`.///pubdefmax(x: Int32, y: Int32): Int32 = if (x>=y) xelsey////// Returns the absolute value of `x`./// If the absolute value exceeds maxValue(), -1 is returned.///pubdefabs(x: Int32): Int32 = {if (x>=0)xelseif (x==minValue()) -1else-x }////// Returns the Euclidean modulo of `x` and `n`./// The result is always non-negative.///pubdefmodulo(x: Int32, n: Int32): Int32 =if (n==0i32)0i32else %%INT32_REM%%(%%INT32_REM%%(x, n) +n, n)////// Returns the remainder of `x / n`./// The result can be negative.////// See also `Int32.modulo`.///pubdefremainder(x: Int32, n: Int32): Int32 =if (n==0i32)0i32else %%INT32_REM%%(x, n)////// Returns the distance between `x` and `y`./// If this distance exceeds maxValue(), -1 is returned.///pubdefdist(x: Int32, y: Int32): Int32 = {if (x>=0andy>=0)abs(x-y)elseif (x<0andy<0)abs(x-y)elseif (x==minValue()ory==minValue()) -1elseif (minValue()+abs(x) +abs(y) >=0) -1elseabs(x-y) }////// Returns 1 if x > y, -1 if x < y, and 0 if x = y./// The sign of x - y.///pubdefcompare(x: Int32, y: Int32): Int32 = {if (x==y)0elseif (x<y) -1else1 }////// Returns 1 if x > 0, -1 if x < 0, and 0 if x = 0./// The sign of x.///pubdefsignum(x: Int32): Int32 = compare(x, 0)////// Returns `base` raised to the power of `n`.///pubdefpow(base: {base = Int32}, n: Int32): Int32 = %%INT32_EXP%%(base#base, n)////// Returns the logical right shift of `x` by `dist`./// Only the rightmost 5 bits of `dist` are considered (ie. `dist rem 32`)./// A zero is shifted into the leftmost position regardless of sign extension.///pubdeflogicalRightShift(dist: {dist = Int32}, x: Int32): Int32 =if (x<0andremainder(dist#dist, size()) !=0)rightShift(bitwiseAnd(rightShift(x, 1), maxValue()), dist#dist -1)elserightShift(x, dist#dist)////// Returns the number of one-bits in the two's complement binary/// representation of `x`.///pubdefbitCount(x: Int32): Int32 = {if (x==0)0elseif (x`remainder`2!=0)bitCount(logicalRightShift(dist = 1, x)) +1elsebitCount(logicalRightShift(dist = 1, x)) }////// Returns the value obtained by rotating the two's complement/// binary representation of `x` right by `dist` bits.///pubdefrotateRight(dist: {dist = Int32}, x: Int32): Int32 =bitwiseOr(logicalRightShift(dist = dist#dist, x), leftShift(x, -dist#dist))////// Returns the value obtained by rotating the two's complement/// binary representation of `x` left by `dist` bits.///pubdefrotateLeft(dist: {dist = Int32}, x: Int32): Int32 =bitwiseOr(logicalRightShift(dist = -dist#dist, x), leftShift(x, dist#dist))////// Returns the value obtained by reversing the bits in the/// two's complement binary representation of `x`.///pubdefreverse(x: Int32): Int32 = reverseHelper(x, 0, size()-1)////// Helper function for `reverse`.///defreverseHelper(x: Int32, l: Int32, r: Int32): Int32 =if (l>=r) xelsereverseHelper(swap(x, l, r), l+1, r-1)////// Helper function for `reverse`.///defswap(x: Int32, l: Int32, r: Int32): Int32 = match (getBit(pos = l, x), getBit(pos = r, x)) {case (1, 0) => clearBit(pos = l, setBit(pos = r, x))case (0, 1) => clearBit(pos = r, setBit(pos = l, x))case_ => x }////// Returns the position of the highest-order/leftmost one-bit in `x`./// Possible return values: 0 (rightmost bit) - 31 (leftmost bit)/// -1 if x = 0///pubdefhighestOneBitPosition(x: Int32): Int32 =// Start at bit 31 and scan rightoneBitPositionHelper(x, size()-1, -1)////// Returns the position of the lowest-order/rightmost one-bit in `x`./// Possible return values: 0 (rightmost bit) - 31 (leftmost bit)/// -1 if x = 0///pubdeflowestOneBitPosition(x: Int32): Int32 =// Start at bit 0 and scan leftoneBitPositionHelper(x, 0, 1)////// Helper function for highestOneBitPosition and lowestOneBitPosition./// If `x` has a one-bit at `position`, return that position./// Otherwise recursively check the next bit in the same way.///defoneBitPositionHelper(x: Int32, position: Int32, delta: Int32): Int32 = {if (position<0) -1elseif (position>size()-1) -1elseif (getBit(pos = position, x) ==1)positionelseif (delta==0) -1elseoneBitPositionHelper(x, position+delta, delta) }////// Returns a value with at most a single one-bit, in the position/// of the highest-order/leftmost one-bit in `x`./// Returns 0 if x=0.///pubdefhighestOneBit(x: Int32): Int32 =bitPositionToInt32(highestOneBitPosition(x))////// Returns a value with at most a single one-bit, in the position/// of the highest-order/leftmost one-bit in `x`./// Returns 0 if x=0.///pubdeflowestOneBit(x: Int32): Int32 =bitPositionToInt32(lowestOneBitPosition(x))////// Helper function for highestOneBit and lowestOneBit./// Returns a value with a single one-bit at bit number `position`./// Returns 0 if `position` is outside the range 0-31 inclusive.///defbitPositionToInt32(position: Int32): Int32 =if (position<0orposition>size()-1) 0elseleftShift(1, position)////// Returns the number of zero bits preceding the/// highest-order/leftmost one-bit in `x`./// Returns 32 if x=0.///pubdefnumberOfLeadingZeros(x: Int32): Int32 =size()-1-highestOneBitPosition(x)////// Returns the number of zero bits following the/// lowest-order/rightmost one-bit in `x`./// Returns 32 if x=0.///pubdefnumberOfTrailingZeros(x: Int32): Int32 =if (x==0) 32elselowestOneBitPosition(x)////// Returns the bit of `x` at position `pos` (either 0 or 1)./// Considers the 5 rightmost bits of `pos` (`pos` modulo 32)./// The bits of x have positions: 0 (rightmost bit) - 31 (leftmost bit)///pubdefgetBit(pos: {pos = Int32}, x: Int32): Int32 =if (rightShift(x, pos#pos) `remainder`2==0) 0else1////// Returns `x` with the bit at position `pos` set (to 1)./// Considers the 5 rightmost bits of `pos` (`pos` modulo 32)./// The bits of x have positions: 0 (rightmost bit) - 31 (leftmost bit)///pubdefsetBit(pos: {pos = Int32}, x: Int32): Int32 = bitwiseOr(x, leftShift(1, pos#pos))////// Returns `x` with the bit at position `pos` cleared (to 0)./// Considers the 5 rightmost bits of `pos` (`pos` modulo 32)./// The bits of x have positions: 0 (rightmost bit) - 31 (leftmost bit)///pubdefclearBit(pos: {pos = Int32}, x: Int32): Int32 = bitwiseAnd(x, bitwiseNot(leftShift(1, pos#pos)))////// Returns `x` with the bit at position `pos` flipped./// Considers the 5 rightmost bits of `pos` (`pos` modulo 32)./// The bits of x have positions: 0 (rightmost bit) - 31 (leftmost bit)///pubdefflipBit(pos: {pos = Int32}, x: Int32): Int32 = bitwiseXor(x, leftShift(1, pos#pos))////// Returns the integer binary logarithm of `x`./// If the given value is 0 or negative, 0 is returned.///pubdeflog2(x: Int32): Int32 =if (x<=0) {0 } else {highestOneBitPosition(x) }////// Returns `x` with the bits shifted left by `y` places///pubdefleftShift(x: Int32, y: Int32): Int32 = %%INT32_SHL%%(x, y)////// Returns `x` with the bits shifted right by `y` places///pubdefrightShift(x: Int32, y: Int32): Int32 = %%INT32_SHR%%(x, y)////// Returns the bitwise AND of `x` and `y`.///pubdefbitwiseAnd(x: Int32, y: Int32): Int32 = %%INT32_AND%%(x, y)////// Returns the bitwise NOT of `x`.///pubdefbitwiseNot(x: Int32): Int32 = %%INT32_NOT%%(x)////// Returns the bitwise OR of `x` and `y`.///pubdefbitwiseOr(x: Int32, y: Int32): Int32 = %%INT32_OR%%(x, y)////// Returns the bitwise XOR of `x` and `y`.///pubdefbitwiseXor(x: Int32, y: Int32): Int32 = %%INT32_XOR%%(x, y)////// Returns the factorial of `x`./// If the given value is negative, 0 is returned.///pubdeffactorial(x: Int32): Int32 =if (x<0) {0 } else {defloop(y, acc) = matchy {case 0 => acccase_ => loop(y-1, y*acc) };loop(x, 1) }////// Return a string representation of `x`.///pubdeftoString(x: Int32): String = ToString.toString(x)////// Parse the string `s` as an Int32, leading or trailing whitespace is trimmed./// A successful parse is wrapped with `Some(x)`, a parse failure is indicated by `None`.///pubdeffromString(s: String): Option[Int32] = try { Some(Integer.parseInt(s.strip())) } catch {case_: NumberFormatException => None }////// Parse the string `s` as an Int32, where the `radix` is used while parsing./// Leading or trailing whitespace is trimmed./// A successful parse is wrapped with `Ok(x)`, a parse failure is indicated by `Err(_)`.///pubdefparse(radix: Int32, s: String): Result[String, Int32] =try { Ok(Integer.parseInt(s.strip(), radix)) } catch {case_: NumberFormatException => Err("Int32.parse") }////// Convert `x` to an `Option[Int8]`.////// Returns `Some(x as Int8)` if the numeric value of `x` can be represented exactly.////// Returns `None` if the numeric value of `x` is outside the range of Int8/// (i.e. -128 to 127).///pubdeftryToInt8(x: Int32): Option[Int8] =if (x<Int8.toInt32(Int8.minValue()) orx>Int8.toInt32(Int8.maxValue())) Noneelse Some(Integer.valueOf(x).byteValue())////// Convert `x` to an `Option[Int16]`.////// Returns `Some(x as Int16)` if the numeric value of `x` can be represented exactly.////// Returns `None` if the numeric value of `x` is outside the range of Int16/// (i.e. -32768 to 32767).///pubdeftryToInt16(x: Int32): Option[Int16] =if (x<Int16.toInt32(Int16.minValue()) orx>Int16.toInt32(Int16.maxValue())) Noneelse Some(Integer.valueOf(x).shortValue())////// Convert `x` to a Int64.////// The numeric value of `x` is preserved exactly.///pubdeftoInt64(x: Int32): Int64 = Integer.valueOf(x).longValue()////// Convert `x` to a BigInt.////// The numeric value of `x` is preserved exactly.///pubdeftoBigInt(x: Int32): BigInt = BigInteger.valueOf(Integer.valueOf(x).longValue())////// Convert `x` to an Float32.////// The numeric value of `x` may lose precision.///pubdeftoFloat32(x: Int32): Float32 = Integer.valueOf(x).floatValue()////// Convert `x` to a Float64.////// The numeric value of `x` is preserved exactly.///pubdeftoFloat64(x: Int32): Float64 = Integer.valueOf(x).doubleValue()////// Convert `x` to a BigDecimal.////// The numeric value of `x` is preserved exactly.///pubdeftoBigDecimal(x: Int32): BigDecimal =new BigDecimal(x)////// Helper function for the `clamp` conversion functions.///defclamp(min: {min = Int32}, max: {max = Int32}, x: Int32): Int32 =if (x<min#min)min#minelseif (x>max#max)max#maxelsex////// Convert `x` to an `Int8`.////// Returns `x` clamped within the Int8 range `min` to `max`.///pubdefclampToInt8(min: {min = Int8}, max: {max = Int8}, x: Int32): Int8 =letmini32 = Int8.toInt32(min#min);letmaxi32 = Int8.toInt32(max#max); Integer.valueOf(clamp(min = mini32, max = maxi32, x)).byteValue()////// Convert `x` to an `Int16`.////// Returns `x` clamped within the Int16 range `min` to `max`.///pubdefclampToInt16(min: {min = Int16}, max: {max = Int16}, x: Int32): Int16 =letmini32 = Int16.toInt32(min#min);letmaxi32 = Int16.toInt32(max#max); Integer.valueOf(clamp(min = mini32, max = maxi32, x)).shortValue()////// Convert `x` to an Int8 by truncation.////// Discards all but the lowest 8 bits.///pubdeftruncateToInt8(x: Int32): Int8 = Integer.valueOf(x).byteValue()////// Convert `x` to an Int16 by truncation.////// Discards all but the lowest 16 bits.///pubdeftruncateToInt16(x: Int32): Int16 = Integer.valueOf(x).shortValue()////// Convert `x` to a Char by truncation.////// Discards all but the lowest 16 bits.///pubdeftruncateToChar(x: Int32): Char =unchecked_cast(Integer.valueOf(x).shortValue() asChar)////// Get the primitive Int32 value from its object representation (i.e. Integer).////// This function is expected to be used when marshaling Int32s from Java. Generally in Flix/// code you should not need to use `Integer`.///pubdefintValue(i: Integer): Int32 =i.intValue()////// Convert an Int32 value to its object representation (i.e. Integer).////// This function is expected to be used when marshaling Int32s to Java. Generally in Flix/// code you should not need to use `Integer`.///pubdefvalueOf(i: Int32): Integer = Integer.valueOf(i)}