Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
360 lines (312 sloc) 7.19 KB
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
native value class Int uses Number, Integral {
fun ==<I: Integral>(other: I): Bool {
this.eqImpl(other.toInt())
}
@intrinsic
private native fun eqImpl(other: Int): Bool;
fun !=<I: Integral>(other: I): Bool {
this.neImpl(other.toInt())
}
@intrinsic
private native fun neImpl(other: Int): Bool;
fun +<I: Integral>(other: I): Int {
this.plusImpl(other.toInt())
}
@intrinsic
private native fun plusImpl(other: Int): Int;
fun -<I: Integral>(other: I): Int {
this.minusImpl(other.toInt())
}
@intrinsic
private native fun minusImpl(other: Int): Int;
fun *<I: Integral>(other: I): Int {
this.timesImpl(other.toInt())
}
@intrinsic
private native fun timesImpl(other: Int): Int;
fun /<I: Integral>(other: I): Int {
n = other.toInt();
if (n == 0) {
throw DivisionByZeroException()
} else {
this.unsafe_divImpl(n)
}
}
// Behavior is undefined if the argument is zero.
@intrinsic
private native fun unsafe_divImpl(other: Int): Int;
fun %<I: Integral>(other: I): Int {
n = other.toInt();
if (n == 0) {
throw DivisionByZeroException()
} else {
this.unsafe_remImpl(n)
}
}
// Behavior is undefined if the argument is zero.
@intrinsic
private native fun unsafe_remImpl(other: Int): Int;
fun <<I: Integral>(other: I): Bool {
this.ltImpl(other.toInt())
}
@intrinsic
private native fun ltImpl(other: Int): Bool;
fun ><I: Integral>(other: I): Bool {
this.gtImpl(other.toInt())
}
@intrinsic
private native fun gtImpl(other: Int): Bool;
fun <=<I: Integral>(other: I): Bool {
this.leImpl(other.toInt())
}
@intrinsic
private native fun leImpl(other: Int): Bool;
fun >=<I: Integral>(other: I): Bool {
this.geImpl(other.toInt())
}
@intrinsic
private native fun geImpl(other: Int): Bool;
// Unsigned comparison operators (treats both operands as unsigned numbers).
fun ult<I: Integral>(other: I): Bool {
this.ultImpl(other.toInt())
}
@intrinsic
private fun ultImpl(other: Int): Bool {
this + Int::min < other + Int::min
}
fun ugt<I: Integral>(other: I): Bool {
this.ugtImpl(other.toInt())
}
@intrinsic
private fun ugtImpl(other: Int): Bool {
this + Int::min > other + Int::min
}
fun ule<I: Integral>(other: I): Bool {
this.uleImpl(other.toInt())
}
@intrinsic
private fun uleImpl(other: Int): Bool {
this + Int::min <= other + Int::min
}
fun uge<I: Integral>(other: I): Bool {
this.ugeImpl(other.toInt())
}
@intrinsic
private fun ugeImpl(other: Int): Bool {
this + Int::min >= other + Int::min
}
// bitwise &
fun and<I: Integral>(other: I): Int {
this.andImpl(other.toInt())
}
@intrinsic
private native fun andImpl(other: Int): Int;
// bitwise |
fun or<I: Integral>(other: I): Int {
this.orImpl(other.toInt())
}
@intrinsic
private native fun orImpl(other: Int): Int;
// bitwise ^
fun xor<I: Integral>(other: I): Int {
this.xorImpl(other.toInt())
}
@intrinsic
private native fun xorImpl(other: Int): Int;
// bitwise <<
fun shl<I: Integral>(other: I): Int {
this.shlImpl(other.toInt())
}
@intrinsic
private native fun shlImpl(other: Int): Int;
// bitwise >>
fun shr<I: Integral>(other: I): Int {
this.shrImpl(other.toInt())
}
@intrinsic
private native fun shrImpl(other: Int): Int;
// bitwise >>>
fun ushr<I: Integral>(other: I): Int {
this.ushrImpl(other.toInt())
}
@intrinsic
private native fun ushrImpl(other: Int): Int;
// bitwise ~
fun not(): Int {
this.xor(-1)
}
// This is super hacky, gets a random unary magic operator `-`
// -x ~> x.negate()
fun negate(): Int {
0 - this
}
// Returns number of leading zeroes (MSB), or 64 if the value is 0.
// NOTE: Overridden in some back ends with a faster version.
fun clz(): Int {
this.clzImpl()
}
@intrinsic
private fun clzImpl(): Int {
if (this == 0) {
64
} else {
n = 0;
x = this;
while (x > 0) {
!n = n + 1;
!x = x.shl(1)
};
n
}
}
// Returns number of trailing zeroes (LSB), or 64 if the value is 0.
// NOTE: Overridden in some back ends with a faster version.
fun ctz(): Int {
this.ctzImpl()
}
@intrinsic
private fun ctzImpl(): Int {
if (this == 0) {
64
} else {
n = 0;
x = this;
while (x.and(1) == 0) {
!n = n + 1;
!x = x.ushr(1)
};
n
}
}
// Returns the number of "one" bits in the value.
// NOTE: Overridden in some back ends with a faster version.
fun popcount(): Int {
this.popcountImpl()
}
@intrinsic
private fun popcountImpl(): Int {
n = 0;
x = this;
while (x != 0) {
!n = n + 1;
!x = x.and(x - 1)
};
n
}
const max: Int = 0x7FFFFFFFFFFFFFFF;
const min: Int = 0x8000000000000000;
fun fromInt(x: Int): Int {
x
}
fun fromFloat(x: Float): Int {
x.toInt()
}
fun toStringBinary(): String {
String::tabulate(64, i ~> {
if (this.and(Int::min.ushr(i)) != 0) {
'1'
} else {
'0'
}
});
}
fun toStringHex(): String {
String::tabulate(16, i ~> {
Chars.intToHexDigit(this.ushr((15 - i) * 4).and(0xF))
})
}
fun toString(): String {
this.toStringImpl()
}
@intrinsic
private fun toStringImpl(): String {
compare(this, 0) match {
| LT() -> "-" + this.toStringNegative()
| EQ() -> "0"
| GT() -> this.toStringPositive()
}
}
fun toFloat(): Float {
this.toFloatImpl()
}
@intrinsic
private native fun toFloatImpl(): Float;
private fun toStringPositive(): String {
if (this == 0) {
""
} else {
(rest, r) = (this / 10, this % 10);
rest.toStringPositive() + static::digit(r)
}
}
private fun toStringNegative(): String {
if (this == 0) {
""
} else {
(rest, r) = (this / 10, -(this % 10));
rest.toStringNegative() + static::digit(r)
}
}
private static fun digit(d: Int): String {
if (d == 0) {
"0"
} else if (d == 1) {
"1"
} else if (d == 2) {
"2"
} else if (d == 3) {
"3"
} else if (d == 4) {
"4"
} else if (d == 5) {
"5"
} else if (d == 6) {
"6"
} else if (d == 7) {
"7"
} else if (d == 8) {
"8"
} else {
"9"
}
}
fun compare<I: Integral>(other: I): Order {
n = other.toInt();
if (this < n) LT() else if (this == n) EQ() else GT()
}
fun chr(): Char {
if (!Char::isValidCharCodePoint(this)) {
invariant_violation("Chr called on invalid Unicode code point: " + this)
};
this.unsafe_chr()
}
private fun unsafe_chr(): Char {
this.unsafe_chrImpl()
}
@intrinsic
private native fun unsafe_chrImpl(): Char;
fun hash(): Int {
this
}
fun toInt(): Int {
this
}
static fun create(int: Int): Int {
int
}
static fun truncate(int: Int): Int {
int
}
fun inspect(): Inspect {
InspectLiteral(this.toString())
}
}
module Int;
const low32BitMask: Int = 0xFFFFFFFF;
module end;