mirror of
https://github.com/enso-org/enso.git
synced 2024-12-23 13:02:07 +03:00
Merge Small_Integer and Big_Integer types (#7636)
Merge Small_Integer and Big_Integer types into a single Integer type
This commit is contained in:
parent
3c00cb400e
commit
e0ee8fdda7
@ -945,6 +945,7 @@
|
||||
- [Use `numpy` & co. from Enso!][7678]
|
||||
- [Changed layout of local libraries directory, making it easier to reference
|
||||
projects next to each other][7634]
|
||||
- [Merge `Small_Integer` and `Big_Integer` types][7636]
|
||||
|
||||
[3227]: https://github.com/enso-org/enso/pull/3227
|
||||
[3248]: https://github.com/enso-org/enso/pull/3248
|
||||
@ -1082,6 +1083,7 @@
|
||||
[7613]: https://github.com/enso-org/enso/pull/7613
|
||||
[7678]: https://github.com/enso-org/enso/pull/7678
|
||||
[7634]: https://github.com/enso-org/enso/pull/7634
|
||||
[7636]: https://github.com/enso-org/enso/pull/7636
|
||||
|
||||
# Enso 2.0.0-alpha.18 (2021-10-12)
|
||||
|
||||
|
@ -5092,7 +5092,7 @@ class RuntimeServerTest
|
||||
Api.ExecutionFailed(
|
||||
contextId,
|
||||
Api.ExecutionResult.Diagnostic.error(
|
||||
"Type error: expected `that` to be Number, but got Function.",
|
||||
"Type error: expected `that` to be Integer, but got Function.",
|
||||
Some(mainFile),
|
||||
Some(model.Range(model.Position(11, 8), model.Position(11, 17))),
|
||||
None,
|
||||
|
@ -187,7 +187,15 @@ class RuntimeVisualizationsTest
|
||||
Api.ExpressionUpdate(
|
||||
Main.idMainZ,
|
||||
Some(ConstantsGen.INTEGER),
|
||||
None,
|
||||
Some(
|
||||
Api.MethodCall(
|
||||
Api.MethodPointer(
|
||||
"Standard.Base.Data.Numbers",
|
||||
"Standard.Base.Data.Numbers.Integer",
|
||||
"+"
|
||||
)
|
||||
)
|
||||
),
|
||||
Vector(Api.ProfilingInfo.ExecutionTime(0)),
|
||||
fromCache,
|
||||
typeChanged,
|
||||
@ -209,7 +217,15 @@ class RuntimeVisualizationsTest
|
||||
Api.ExpressionUpdate(
|
||||
Main.idFooY,
|
||||
Some(ConstantsGen.INTEGER),
|
||||
None,
|
||||
Some(
|
||||
Api.MethodCall(
|
||||
Api.MethodPointer(
|
||||
"Standard.Base.Data.Numbers",
|
||||
"Standard.Base.Data.Numbers.Integer",
|
||||
"+"
|
||||
)
|
||||
)
|
||||
),
|
||||
Vector(Api.ProfilingInfo.ExecutionTime(0)),
|
||||
fromCache,
|
||||
typeChanged,
|
||||
@ -231,7 +247,15 @@ class RuntimeVisualizationsTest
|
||||
Api.ExpressionUpdate(
|
||||
Main.idFooZ,
|
||||
Some(ConstantsGen.INTEGER),
|
||||
None,
|
||||
Some(
|
||||
Api.MethodCall(
|
||||
Api.MethodPointer(
|
||||
"Standard.Base.Data.Numbers",
|
||||
"Standard.Base.Data.Numbers.Integer",
|
||||
"*"
|
||||
)
|
||||
)
|
||||
),
|
||||
Vector(Api.ProfilingInfo.ExecutionTime(0)),
|
||||
fromCache,
|
||||
typeChanged,
|
||||
@ -973,12 +997,30 @@ class RuntimeVisualizationsTest
|
||||
contextId,
|
||||
context.Main.idFooY,
|
||||
ConstantsGen.INTEGER,
|
||||
methodCall = Some(
|
||||
Api.MethodCall(
|
||||
Api.MethodPointer(
|
||||
"Standard.Base.Data.Numbers",
|
||||
"Standard.Base.Data.Numbers.Integer",
|
||||
"+"
|
||||
)
|
||||
)
|
||||
),
|
||||
typeChanged = false
|
||||
),
|
||||
TestMessages.update(
|
||||
contextId,
|
||||
context.Main.idFooZ,
|
||||
ConstantsGen.INTEGER,
|
||||
methodCall = Some(
|
||||
Api.MethodCall(
|
||||
Api.MethodPointer(
|
||||
"Standard.Base.Data.Numbers",
|
||||
"Standard.Base.Data.Numbers.Integer",
|
||||
"*"
|
||||
)
|
||||
)
|
||||
),
|
||||
typeChanged = false
|
||||
),
|
||||
context.executionComplete(contextId)
|
||||
|
@ -85,7 +85,7 @@ public abstract class IsValueOfTypeNode extends Node {
|
||||
@Specialization
|
||||
boolean doLongCheck(Type expectedType, long payload) {
|
||||
var numbers = EnsoContext.get(this).getBuiltins().number();
|
||||
return checkParentTypes(numbers.getSmallInteger(), expectedType);
|
||||
return checkParentTypes(numbers.getInteger(), expectedType);
|
||||
}
|
||||
|
||||
@Specialization
|
||||
@ -97,7 +97,7 @@ public abstract class IsValueOfTypeNode extends Node {
|
||||
@Specialization
|
||||
boolean doBigIntegerCheck(Type expectedType, EnsoBigInteger value) {
|
||||
var numbers = EnsoContext.get(this).getBuiltins().number();
|
||||
return checkParentTypes(numbers.getBigInteger(), expectedType);
|
||||
return checkParentTypes(numbers.getInteger(), expectedType);
|
||||
}
|
||||
|
||||
@Specialization
|
||||
|
@ -1,12 +0,0 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number;
|
||||
|
||||
import org.enso.interpreter.dsl.BuiltinType;
|
||||
import org.enso.interpreter.node.expression.builtin.Builtin;
|
||||
|
||||
@BuiltinType
|
||||
public class BigInteger extends Builtin {
|
||||
@Override
|
||||
protected Class<? extends Builtin> getSuperType() {
|
||||
return Integer.class;
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number;
|
||||
|
||||
import org.enso.interpreter.dsl.BuiltinType;
|
||||
import org.enso.interpreter.node.expression.builtin.Builtin;
|
||||
|
||||
@BuiltinType
|
||||
public class SmallInteger extends Builtin {
|
||||
@Override
|
||||
protected Class<? extends Builtin> getSuperType() {
|
||||
return Integer.class;
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.bigInteger;
|
||||
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Big_Integer", name = "abs", description = "Big integer absolute value.")
|
||||
public class AbsNode extends Node {
|
||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||
|
||||
Object execute(EnsoBigInteger self) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.abs(self.getValue()));
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.bigInteger;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Big_Integer", name = "+", description = "Big integer addition.")
|
||||
public abstract class AddNode extends Node {
|
||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||
|
||||
abstract Object execute(EnsoBigInteger self, Object that);
|
||||
|
||||
static AddNode build() {
|
||||
return AddNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doLong(EnsoBigInteger self, long that) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.add(self.getValue(), that));
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doBigInteger(EnsoBigInteger self, EnsoBigInteger that) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.add(self.getValue(), that.getValue()));
|
||||
}
|
||||
|
||||
@Specialization
|
||||
double doDouble(EnsoBigInteger self, double that) {
|
||||
return BigIntegerOps.toDouble(self.getValue()) + that;
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(EnsoBigInteger self, Object that) {
|
||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
||||
var number = builtins.number().getNumber();
|
||||
throw new PanicException(builtins.error().makeTypeError(number, that, "that"), this);
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.bigInteger;
|
||||
|
||||
import com.oracle.truffle.api.CompilerDirectives;
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Big_Integer", name = "bit_not", description = "Bitwise negation.")
|
||||
public abstract class BitNotNode extends Node {
|
||||
abstract Object execute(Object self);
|
||||
|
||||
static BitNotNode build() {
|
||||
return BitNotNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
EnsoBigInteger doBigInteger(EnsoBigInteger self) {
|
||||
return new EnsoBigInteger(self.getValue().not());
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(Object self) {
|
||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
||||
var integer = builtins.number().getInteger();
|
||||
throw new PanicException(builtins.error().makeTypeError(integer, self, "this"), this);
|
||||
}
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.bigInteger;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.ImportStatic;
|
||||
import com.oracle.truffle.api.dsl.NeverDefault;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import com.oracle.truffle.api.profiles.CountingConditionProfile;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.error.DataflowError;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@ImportStatic(BigIntegerOps.class)
|
||||
@BuiltinMethod(type = "Big_Integer", name = "bit_shift", description = "Bitwise shift.")
|
||||
public abstract class BitShiftNode extends Node {
|
||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||
private final CountingConditionProfile fitsInIntProfileLeftShift =
|
||||
CountingConditionProfile.create();
|
||||
private final CountingConditionProfile fitsInIntProfileRightShift =
|
||||
CountingConditionProfile.create();
|
||||
|
||||
abstract Object execute(Object self, Object that);
|
||||
|
||||
@NeverDefault
|
||||
static BitShiftNode build() {
|
||||
return BitShiftNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization(guards = {"that >= 0", "fitsInInt(that)"})
|
||||
EnsoBigInteger doBigIntShiftLeft(EnsoBigInteger self, long that) {
|
||||
return new EnsoBigInteger(BigIntegerOps.bitShiftLeft(self.getValue(), (int) that));
|
||||
}
|
||||
|
||||
@Specialization(guards = "that >= 0", replaces = "doBigIntShiftLeft")
|
||||
Object doBigIntShiftLeftExplicit(EnsoBigInteger self, long that) {
|
||||
if (fitsInIntProfileLeftShift.profile(BigIntegerOps.fitsInInt(that))) {
|
||||
return doBigIntShiftLeft(self, that);
|
||||
} else {
|
||||
return DataflowError.withoutTrace(
|
||||
EnsoContext.get(this).getBuiltins().error().getShiftAmountTooLargeError(), this);
|
||||
}
|
||||
}
|
||||
|
||||
@Specialization(guards = {"that < 0", "fitsInInt(that)"})
|
||||
Object doBigIntShiftRight(EnsoBigInteger self, long that) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.bitShiftRight(self.getValue(), (int) -that));
|
||||
}
|
||||
|
||||
@Specialization(guards = "that < 0", replaces = "doBigIntShiftRight")
|
||||
Object doBigIntShiftRightExplicit(EnsoBigInteger self, long that) {
|
||||
if (fitsInIntProfileRightShift.profile(BigIntegerOps.fitsInInt(that))) {
|
||||
return doBigIntShiftRight(self, -that);
|
||||
} else {
|
||||
return BigIntegerOps.nonNegative(self.getValue()) ? 0L : -1L;
|
||||
}
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doBigIntThat(EnsoBigInteger self, EnsoBigInteger that) {
|
||||
if (!BigIntegerOps.nonNegative(that.getValue())) {
|
||||
return BigIntegerOps.nonNegative(self.getValue()) ? 0L : -1L;
|
||||
} else {
|
||||
// Note [Well-Formed BigIntegers]
|
||||
return DataflowError.withoutTrace(
|
||||
EnsoContext.get(this).getBuiltins().error().getShiftAmountTooLargeError(), this);
|
||||
}
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(Object self, Object that) {
|
||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
||||
var integer = builtins.number().getInteger();
|
||||
throw new PanicException(builtins.error().makeTypeError(integer, that, "that"), this);
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.bigInteger;
|
||||
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Big_Integer", name = "ceil", description = "Big integer ceiling.")
|
||||
public class CeilNode extends Node {
|
||||
Object execute(EnsoBigInteger self) {
|
||||
return self;
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.bigInteger;
|
||||
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Big_Integer", name = "floor", description = "Big integer floor.")
|
||||
public class FloorNode extends Node {
|
||||
Object execute(EnsoBigInteger self) {
|
||||
return self;
|
||||
}
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.bigInteger;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.error.DataflowError;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Big_Integer", name = "%", description = "Big integer modulo division.")
|
||||
public abstract class ModNode extends Node {
|
||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||
|
||||
abstract Object execute(EnsoBigInteger self, Object that);
|
||||
|
||||
static ModNode build() {
|
||||
return ModNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doLong(EnsoBigInteger self, long that) {
|
||||
try {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.modulo(self.getValue(), that));
|
||||
} catch (ArithmeticException e) {
|
||||
return DataflowError.withoutTrace(
|
||||
EnsoContext.get(this).getBuiltins().error().getDivideByZeroError(), this);
|
||||
}
|
||||
}
|
||||
|
||||
@Specialization
|
||||
double doDouble(EnsoBigInteger self, double that) {
|
||||
// No need to trap, as floating-point modulo returns NaN for division by zero instead of
|
||||
// throwing.
|
||||
return BigIntegerOps.toDouble(self.getValue()) % that;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doBigInteger(EnsoBigInteger self, EnsoBigInteger that) {
|
||||
// No need to trap, as 0 is never represented as an EnsoBigInteger.
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.modulo(self.getValue(), that.getValue()));
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(EnsoBigInteger self, Object that) {
|
||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
||||
var number = builtins.number().getNumber();
|
||||
throw new PanicException(builtins.error().makeTypeError(number, that, "that"), this);
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.bigInteger;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Big_Integer", name = "*", description = "Big integer multiplication.")
|
||||
public abstract class MultiplyNode extends Node {
|
||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||
|
||||
public abstract Object execute(EnsoBigInteger self, Object that);
|
||||
|
||||
public static MultiplyNode build() {
|
||||
return MultiplyNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doLong(EnsoBigInteger self, long that) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.multiply(self.getValue(), that));
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doBigInteger(EnsoBigInteger self, EnsoBigInteger that) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.multiply(self.getValue(), that.getValue()));
|
||||
}
|
||||
|
||||
@Specialization
|
||||
double doDouble(EnsoBigInteger self, double that) {
|
||||
return BigIntegerOps.toDouble(self.getValue()) * that;
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(EnsoBigInteger self, Object that) {
|
||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
||||
var number = builtins.number().getNumber();
|
||||
throw new PanicException(builtins.error().makeTypeError(number, that, "that"), this);
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.bigInteger;
|
||||
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Big_Integer", name = "negate", description = "Big integer negation.")
|
||||
public class NegateNode extends Node {
|
||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||
|
||||
Object execute(EnsoBigInteger self) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.negate(self.getValue()));
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.bigInteger;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Big_Integer", name = "-", description = "Big integer subtraction.")
|
||||
public abstract class SubtractNode extends Node {
|
||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||
|
||||
abstract Object execute(EnsoBigInteger self, Object that);
|
||||
|
||||
static SubtractNode build() {
|
||||
return SubtractNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doLong(EnsoBigInteger self, long that) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.subtract(self.getValue(), that));
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doBigInteger(EnsoBigInteger self, EnsoBigInteger that) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.subtract(self.getValue(), that.getValue()));
|
||||
}
|
||||
|
||||
@Specialization
|
||||
double doDouble(EnsoBigInteger self, double that) {
|
||||
return BigIntegerOps.toDouble(self.getValue()) - that;
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(EnsoBigInteger self, Object that) {
|
||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
||||
var number = builtins.number().getNumber();
|
||||
throw new PanicException(builtins.error().makeTypeError(number, that, "that"), this);
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.bigInteger;
|
||||
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(
|
||||
type = "Big_Integer",
|
||||
name = "to_decimal",
|
||||
description = "Conversion of integers to decimals")
|
||||
public class ToDecimalNode extends Node {
|
||||
double execute(EnsoBigInteger self) {
|
||||
return BigIntegerOps.toDouble(self.getValue());
|
||||
}
|
||||
}
|
@ -1,23 +1,25 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.smallInteger;
|
||||
package org.enso.interpreter.node.expression.builtin.number.integer;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Small_Integer", name = "abs", description = "Absolute value of a number")
|
||||
@BuiltinMethod(type = "Integer", name = "abs", description = "Absolute value of a number")
|
||||
public abstract class AbsNode extends Node {
|
||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||
|
||||
static AbsNode build() {
|
||||
public static AbsNode build() {
|
||||
return AbsNodeGen.create();
|
||||
}
|
||||
|
||||
abstract Object execute(long self);
|
||||
public abstract Object execute(Object self);
|
||||
|
||||
@Specialization(rewriteOn = ArithmeticException.class)
|
||||
long doNormal(long self) {
|
||||
long doLong(long self) {
|
||||
if (self < 0) {
|
||||
return Math.negateExact(self);
|
||||
} else {
|
||||
@ -25,8 +27,18 @@ public abstract class AbsNode extends Node {
|
||||
}
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doOverflow(long self) {
|
||||
@Specialization(replaces = "doLong")
|
||||
Object doLongOverflow(long self) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.abs(self));
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doBigInt(EnsoBigInteger self) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.abs(self.getValue()));
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(Object self) {
|
||||
throw IntegerUtils.throwTypeErrorIfNotInt(self, this);
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.integer;
|
||||
|
||||
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Integer", name = "+", description = "Addition of numbers.")
|
||||
public abstract class AddNode extends Node {
|
||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||
|
||||
public abstract Object execute(Object self, Object that);
|
||||
|
||||
public static AddNode build() {
|
||||
return AddNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization(rewriteOn = ArithmeticException.class)
|
||||
long doLong(long self, long that) {
|
||||
return Math.addExact(self, that);
|
||||
}
|
||||
|
||||
@Specialization(replaces = "doLong")
|
||||
Object doOverflow(long self, long that) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.add(self, that));
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doDouble(long self, double that) {
|
||||
return self + that;
|
||||
}
|
||||
|
||||
@TruffleBoundary
|
||||
@Specialization
|
||||
Object doBigIntegers(EnsoBigInteger self, EnsoBigInteger that) {
|
||||
return toEnsoNumberNode.execute(self.asBigInteger().add(that.asBigInteger()));
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doLongBigInteger(long self, EnsoBigInteger that) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.add(that.getValue(), self));
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doBigIntegerLong(EnsoBigInteger self, long that) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.add(self.getValue(), that));
|
||||
}
|
||||
|
||||
@Specialization
|
||||
double doBigIntDouble(EnsoBigInteger self, double that) {
|
||||
return self.asDouble() + that;
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(Object self, Object that) {
|
||||
throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this);
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.bigInteger;
|
||||
package org.enso.interpreter.node.expression.builtin.number.integer;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
@ -6,35 +6,40 @@ import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Big_Integer", name = "bit_and", description = "Bitwise and.")
|
||||
@BuiltinMethod(type = "Integer", name = "bit_and", description = "Bitwise and.")
|
||||
public abstract class BitAndNode extends Node {
|
||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||
|
||||
abstract Object execute(Object self, Object that);
|
||||
public abstract Object execute(Object self, Object that);
|
||||
|
||||
static BitAndNode build() {
|
||||
public static BitAndNode build() {
|
||||
return BitAndNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doLong(EnsoBigInteger self, long that) {
|
||||
long doLongLong(long self, long that) {
|
||||
return self & that;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doLongBigInt(long self, EnsoBigInteger that) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.bitAnd(self, that.getValue()));
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doBigIntLong(EnsoBigInteger self, long that) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.bitAnd(self.getValue(), that));
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doBigInteger(EnsoBigInteger self, EnsoBigInteger that) {
|
||||
Object doBigIntBigInt(EnsoBigInteger self, EnsoBigInteger that) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.bitAnd(self.getValue(), that.getValue()));
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(Object self, Object that) {
|
||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
||||
var integer = builtins.number().getInteger();
|
||||
throw new PanicException(builtins.error().makeTypeError(integer, that, "that"), this);
|
||||
throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this);
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.integer;
|
||||
|
||||
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Integer", name = "bit_not", description = "Bitwise negation.")
|
||||
public abstract class BitNotNode extends Node {
|
||||
abstract Object execute(Object self);
|
||||
|
||||
static BitNotNode build() {
|
||||
return BitNotNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
long doLong(long self) {
|
||||
return ~self;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
@TruffleBoundary
|
||||
EnsoBigInteger doBigInteger(EnsoBigInteger self) {
|
||||
return new EnsoBigInteger(self.getValue().not());
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(Object self) {
|
||||
throw IntegerUtils.throwTypeErrorIfNotInt(self, this);
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.bigInteger;
|
||||
package org.enso.interpreter.node.expression.builtin.number.integer;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
@ -6,12 +6,9 @@ import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Big_Integer", name = "bit_or", description = "Bitwise or.")
|
||||
@BuiltinMethod(type = "Integer", name = "bit_or", description = "Bitwise or.")
|
||||
public abstract class BitOrNode extends Node {
|
||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||
|
||||
@ -21,6 +18,16 @@ public abstract class BitOrNode extends Node {
|
||||
return BitOrNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
long doLong(long self, long that) {
|
||||
return self | that;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doBigInteger(long self, EnsoBigInteger that) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.bitOr(self, that.getValue()));
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doLong(EnsoBigInteger self, long that) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.bitOr(self.getValue(), that));
|
||||
@ -33,8 +40,6 @@ public abstract class BitOrNode extends Node {
|
||||
|
||||
@Fallback
|
||||
Object doOther(Object self, Object that) {
|
||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
||||
var integer = builtins.number().getInteger();
|
||||
throw new PanicException(builtins.error().makeTypeError(integer, that, "that"), this);
|
||||
throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this);
|
||||
}
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.smallInteger;
|
||||
package org.enso.interpreter.node.expression.builtin.number.integer;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Cached;
|
||||
import com.oracle.truffle.api.dsl.Cached.Exclusive;
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.ImportStatic;
|
||||
import com.oracle.truffle.api.dsl.NeverDefault;
|
||||
@ -10,13 +12,11 @@ import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.error.DataflowError;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@ImportStatic(BigIntegerOps.class)
|
||||
@BuiltinMethod(type = "Small_Integer", name = "bit_shift", description = "Bitwise shift.")
|
||||
@BuiltinMethod(type = "Integer", name = "bit_shift", description = "Bitwise shift.")
|
||||
public abstract class BitShiftNode extends Node {
|
||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||
private final CountingConditionProfile canShiftLeftInLongProfile =
|
||||
@ -26,7 +26,7 @@ public abstract class BitShiftNode extends Node {
|
||||
private final CountingConditionProfile rightShiftExceedsLongWidth =
|
||||
CountingConditionProfile.create();
|
||||
|
||||
abstract Object execute(long self, Object that);
|
||||
abstract Object execute(Object self, Object that);
|
||||
|
||||
@NeverDefault
|
||||
static BitShiftNode build() {
|
||||
@ -79,11 +79,54 @@ public abstract class BitShiftNode extends Node {
|
||||
}
|
||||
}
|
||||
|
||||
@Specialization(guards = {"that >= 0", "fitsInInt(that)"})
|
||||
EnsoBigInteger doBigIntShiftLeft(EnsoBigInteger self, long that) {
|
||||
return new EnsoBigInteger(BigIntegerOps.bitShiftLeft(self.getValue(), (int) that));
|
||||
}
|
||||
|
||||
@Specialization(guards = "that >= 0", replaces = "doBigIntShiftLeft")
|
||||
Object doBigIntShiftLeftExplicit(
|
||||
EnsoBigInteger self,
|
||||
long that,
|
||||
@Exclusive @Cached CountingConditionProfile fitsInIntProfileLeftShift) {
|
||||
if (fitsInIntProfileLeftShift.profile(BigIntegerOps.fitsInInt(that))) {
|
||||
return doBigIntShiftLeft(self, that);
|
||||
} else {
|
||||
return DataflowError.withoutTrace(
|
||||
EnsoContext.get(this).getBuiltins().error().getShiftAmountTooLargeError(), this);
|
||||
}
|
||||
}
|
||||
|
||||
@Specialization(guards = {"that < 0", "fitsInInt(that)"})
|
||||
Object doBigIntShiftRight(EnsoBigInteger self, long that) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.bitShiftRight(self.getValue(), (int) -that));
|
||||
}
|
||||
|
||||
@Specialization(guards = "that < 0", replaces = "doBigIntShiftRight")
|
||||
Object doBigIntShiftRightExplicit(
|
||||
EnsoBigInteger self,
|
||||
long that,
|
||||
@Exclusive @Cached CountingConditionProfile fitsInIntProfileRightShift) {
|
||||
if (fitsInIntProfileRightShift.profile(BigIntegerOps.fitsInInt(that))) {
|
||||
return doBigIntShiftRight(self, -that);
|
||||
} else {
|
||||
return BigIntegerOps.nonNegative(self.getValue()) ? 0L : -1L;
|
||||
}
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doBigIntThat(EnsoBigInteger self, EnsoBigInteger that) {
|
||||
if (!BigIntegerOps.nonNegative(that.getValue())) {
|
||||
return BigIntegerOps.nonNegative(self.getValue()) ? 0L : -1L;
|
||||
} else {
|
||||
return DataflowError.withoutTrace(
|
||||
EnsoContext.get(this).getBuiltins().error().getShiftAmountTooLargeError(), this);
|
||||
}
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(long self, Object that) {
|
||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
||||
var integer = builtins.number().getInteger();
|
||||
throw new PanicException(builtins.error().makeTypeError(integer, that, "that"), this);
|
||||
Object doOther(Object self, Object that) {
|
||||
throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this);
|
||||
}
|
||||
|
||||
boolean hasFreeBitsLeftShift(long number, long shift) {
|
@ -1,4 +1,4 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.bigInteger;
|
||||
package org.enso.interpreter.node.expression.builtin.number.integer;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Cached;
|
||||
import com.oracle.truffle.api.dsl.Cached.Shared;
|
||||
@ -7,19 +7,30 @@ import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Big_Integer", name = "bit_shift_r", description = "Bitwise right-shift.")
|
||||
@BuiltinMethod(type = "Integer", name = "bit_shift_r", description = "Bitwise right-shift.")
|
||||
public abstract class BitShiftRightNode extends Node {
|
||||
abstract Object execute(EnsoBigInteger self, Object that);
|
||||
abstract Object execute(Object self, Object that);
|
||||
|
||||
static BitShiftRightNode build() {
|
||||
return BitShiftRightNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doBigInteger(
|
||||
long self, long that, @Shared("bitShiftNode") @Cached("build()") BitShiftNode bitShiftNode) {
|
||||
return bitShiftNode.execute(self, -1L * that);
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doBigInteger(
|
||||
long self,
|
||||
EnsoBigInteger that,
|
||||
@Shared("bitShiftNode") @Cached("build()") BitShiftNode bitShiftNode) {
|
||||
return bitShiftNode.execute(self, new EnsoBigInteger(BigIntegerOps.negate(that.getValue())));
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doBigInteger(
|
||||
EnsoBigInteger self,
|
||||
@ -37,9 +48,7 @@ public abstract class BitShiftRightNode extends Node {
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(EnsoBigInteger self, Object that) {
|
||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
||||
var integer = builtins.number().getInteger();
|
||||
throw new PanicException(builtins.error().makeTypeError(integer, that, "that"), this);
|
||||
Object doOther(Object self, Object that) {
|
||||
throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this);
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.bigInteger;
|
||||
package org.enso.interpreter.node.expression.builtin.number.integer;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
@ -6,21 +6,28 @@ import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Big_Integer", name = "bit_xor", description = "Bitwise exclusive or.")
|
||||
@BuiltinMethod(type = "Integer", name = "bit_xor", description = "Bitwise exclusive or.")
|
||||
public abstract class BitXorNode extends Node {
|
||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||
|
||||
abstract Object execute(EnsoBigInteger self, Object that);
|
||||
abstract Object execute(Object self, Object that);
|
||||
|
||||
static BitXorNode build() {
|
||||
return BitXorNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
long doLong(long self, long that) {
|
||||
return self ^ that;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doBigInteger(long self, EnsoBigInteger that) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.bitXor(self, that.getValue()));
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doLong(EnsoBigInteger self, long that) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.bitXor(self.getValue(), that));
|
||||
@ -32,9 +39,7 @@ public abstract class BitXorNode extends Node {
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(EnsoBigInteger self, Object that) {
|
||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
||||
var integer = builtins.number().getInteger();
|
||||
throw new PanicException(builtins.error().makeTypeError(integer, that, "that"), this);
|
||||
Object doOther(Object self, Object that) {
|
||||
throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this);
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.integer;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Integer", name = "ceil", description = "Small integer ceiling.")
|
||||
public abstract class CeilNode extends Node {
|
||||
abstract Object execute(Object self);
|
||||
|
||||
public static CeilNode build() {
|
||||
return CeilNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
long doLong(long self) {
|
||||
return self;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
EnsoBigInteger doBigInt(EnsoBigInteger self) {
|
||||
return self;
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(Object self) {
|
||||
throw IntegerUtils.throwTypeErrorIfNotInt(self, this);
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.bigInteger;
|
||||
package org.enso.interpreter.node.expression.builtin.number.integer;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
@ -7,21 +7,36 @@ import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.error.DataflowError;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Big_Integer", name = "div", description = "Big integer integral division.")
|
||||
@BuiltinMethod(type = "Integer", name = "div", description = "Division of numbers.")
|
||||
public abstract class DivNode extends Node {
|
||||
|
||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||
|
||||
abstract Object execute(EnsoBigInteger self, Object that);
|
||||
abstract Object execute(Object self, Object that);
|
||||
|
||||
static DivNode build() {
|
||||
return DivNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doLong(long self, long that) {
|
||||
try {
|
||||
return self / that;
|
||||
} catch (ArithmeticException e) {
|
||||
return DataflowError.withoutTrace(
|
||||
EnsoContext.get(this).getBuiltins().error().getDivideByZeroError(), this);
|
||||
}
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doBigInteger(long self, EnsoBigInteger that) {
|
||||
// No need to trap, as 0 is never represented as an EnsoBigInteger.
|
||||
return 0L;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doLong(EnsoBigInteger self, long that) {
|
||||
try {
|
||||
@ -39,9 +54,7 @@ public abstract class DivNode extends Node {
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(EnsoBigInteger self, Object that) {
|
||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
||||
var integer = builtins.number().getInteger();
|
||||
throw new PanicException(builtins.error().makeTypeError(integer, that, "that"), this);
|
||||
Object doOther(Object self, Object that) {
|
||||
throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this);
|
||||
}
|
||||
}
|
@ -1,23 +1,35 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.bigInteger;
|
||||
package org.enso.interpreter.node.expression.builtin.number.integer;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Big_Integer", name = "/", description = "Big integer division.")
|
||||
@BuiltinMethod(type = "Integer", name = "/", description = "Division of numbers.")
|
||||
public abstract class DivideNode extends Node {
|
||||
abstract double execute(EnsoBigInteger self, Object that);
|
||||
abstract double execute(Object self, Object that);
|
||||
|
||||
static DivideNode build() {
|
||||
return DivideNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
double doLong(long self, long that) {
|
||||
return ((double) self) / ((double) that);
|
||||
}
|
||||
|
||||
@Specialization
|
||||
double doDouble(long self, double that) {
|
||||
return self / that;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
double doBigInteger(long self, EnsoBigInteger that) {
|
||||
return ((double) self) / BigIntegerOps.toDouble(that.getValue());
|
||||
}
|
||||
|
||||
@Specialization
|
||||
double doBigInteger(EnsoBigInteger self, EnsoBigInteger that) {
|
||||
return BigIntegerOps.toDouble(self.getValue()) / BigIntegerOps.toDouble(that.getValue());
|
||||
@ -34,9 +46,7 @@ public abstract class DivideNode extends Node {
|
||||
}
|
||||
|
||||
@Fallback
|
||||
double doOther(EnsoBigInteger self, Object that) {
|
||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
||||
var number = builtins.number().getNumber();
|
||||
throw new PanicException(builtins.error().makeTypeError(number, that, "that"), this);
|
||||
double doOther(Object self, Object that) {
|
||||
throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this);
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.integer;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Integer", name = "floor", description = "Small integer floor.")
|
||||
public abstract class FloorNode extends Node {
|
||||
|
||||
public abstract Object execute(Object self);
|
||||
|
||||
public static FloorNode build() {
|
||||
return FloorNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
long doLong(long self) {
|
||||
return self;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
EnsoBigInteger doBigInt(EnsoBigInteger self) {
|
||||
return self;
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(Object self) {
|
||||
throw IntegerUtils.throwTypeErrorIfNotInt(self, this);
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.bigInteger;
|
||||
package org.enso.interpreter.node.expression.builtin.number.integer;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
@ -9,15 +9,30 @@ import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.error.DataflowError;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Big_Integer", name = ">", description = "Comparison of numbers.")
|
||||
@BuiltinMethod(type = "Integer", name = ">", description = "Comparison of numbers.")
|
||||
public abstract class GreaterNode extends Node {
|
||||
|
||||
abstract Object execute(EnsoBigInteger self, Object that);
|
||||
abstract Object execute(Object self, Object that);
|
||||
|
||||
static GreaterNode build() {
|
||||
return GreaterNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
boolean doLong(long self, long that) {
|
||||
return self > that;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
boolean doDouble(long self, double that) {
|
||||
return (double) self > that;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
boolean doBigInteger(long self, EnsoBigInteger that) {
|
||||
return that.getValue().signum() < 0;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
boolean doDouble(EnsoBigInteger self, double that) {
|
||||
return BigIntegerOps.toDouble(self.getValue()) > that;
|
||||
@ -34,7 +49,7 @@ public abstract class GreaterNode extends Node {
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(EnsoBigInteger self, Object that) {
|
||||
Object doOther(Object self, Object that) {
|
||||
var builtins = EnsoContext.get(this).getBuiltins();
|
||||
var incomparableValsErr = builtins.error().makeIncomparableValues(self, that);
|
||||
return DataflowError.withoutTrace(incomparableValsErr, this);
|
@ -1,4 +1,4 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.bigInteger;
|
||||
package org.enso.interpreter.node.expression.builtin.number.integer;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
@ -9,15 +9,30 @@ import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.error.DataflowError;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Big_Integer", name = ">=", description = "Comparison of numbers.")
|
||||
@BuiltinMethod(type = "Integer", name = ">=", description = "Comparison of numbers.")
|
||||
public abstract class GreaterOrEqualNode extends Node {
|
||||
|
||||
abstract Object execute(EnsoBigInteger self, Object that);
|
||||
abstract Object execute(Object self, Object that);
|
||||
|
||||
static GreaterOrEqualNode build() {
|
||||
return GreaterOrEqualNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
boolean doLong(long self, long that) {
|
||||
return self >= that;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
boolean doDouble(long self, double that) {
|
||||
return (double) self >= that;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
boolean doBigInteger(long self, EnsoBigInteger that) {
|
||||
return that.getValue().signum() < 0;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
boolean doDouble(EnsoBigInteger self, double that) {
|
||||
return BigIntegerOps.toDouble(self.getValue()) >= that;
|
||||
@ -34,7 +49,7 @@ public abstract class GreaterOrEqualNode extends Node {
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(EnsoBigInteger self, Object that) {
|
||||
Object doOther(Object self, Object that) {
|
||||
var builtins = EnsoContext.get(this).getBuiltins();
|
||||
var incomparableValsErr = builtins.error().makeIncomparableValues(self, that);
|
||||
return DataflowError.withoutTrace(incomparableValsErr, this);
|
@ -0,0 +1,30 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.integer;
|
||||
|
||||
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
|
||||
|
||||
public final class IntegerUtils {
|
||||
private IntegerUtils() {}
|
||||
|
||||
@TruffleBoundary
|
||||
static PanicException throwTypeErrorIfNotInt(Object self, Object that, Node node) {
|
||||
var builtins = EnsoContext.get(node).getBuiltins();
|
||||
var intType = builtins.number().getInteger();
|
||||
var selfType = TypesLibrary.getUncached().getType(self);
|
||||
if (selfType != intType) {
|
||||
return new PanicException(builtins.error().makeTypeError(intType, self, "self"), node);
|
||||
} else {
|
||||
return new PanicException(builtins.error().makeTypeError(intType, that, "that"), node);
|
||||
}
|
||||
}
|
||||
|
||||
@TruffleBoundary
|
||||
static PanicException throwTypeErrorIfNotInt(Object self, Node node) {
|
||||
var builtins = EnsoContext.get(node).getBuiltins();
|
||||
var intType = builtins.number().getInteger();
|
||||
return new PanicException(builtins.error().makeTypeError(intType, self, "self"), node);
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.bigInteger;
|
||||
package org.enso.interpreter.node.expression.builtin.number.integer;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
@ -9,15 +9,30 @@ import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.error.DataflowError;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Big_Integer", name = "<", description = "Comparison of numbers.")
|
||||
@BuiltinMethod(type = "Integer", name = "<", description = "Comparison of numbers.")
|
||||
public abstract class LessNode extends Node {
|
||||
|
||||
abstract Object execute(EnsoBigInteger self, Object that);
|
||||
abstract Object execute(Object self, Object that);
|
||||
|
||||
static LessNode build() {
|
||||
return LessNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
boolean doLong(long self, long that) {
|
||||
return self < that;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
boolean doDouble(long self, double that) {
|
||||
return (double) self < that;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
boolean doBigInteger(long self, EnsoBigInteger that) {
|
||||
return that.getValue().signum() > 0;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
boolean doDouble(EnsoBigInteger self, double that) {
|
||||
return BigIntegerOps.toDouble(self.getValue()) < that;
|
||||
@ -34,7 +49,7 @@ public abstract class LessNode extends Node {
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(EnsoBigInteger self, Object that) {
|
||||
Object doOther(Object self, Object that) {
|
||||
var builtins = EnsoContext.get(this).getBuiltins();
|
||||
var incomparableValsErr = builtins.error().makeIncomparableValues(self, that);
|
||||
return DataflowError.withoutTrace(incomparableValsErr, this);
|
@ -1,4 +1,4 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.bigInteger;
|
||||
package org.enso.interpreter.node.expression.builtin.number.integer;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
@ -9,15 +9,30 @@ import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.error.DataflowError;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Big_Integer", name = "<=", description = "Comparison of numbers.")
|
||||
@BuiltinMethod(type = "Integer", name = "<=", description = "Comparison of numbers.")
|
||||
public abstract class LessOrEqualNode extends Node {
|
||||
|
||||
abstract Object execute(EnsoBigInteger self, Object that);
|
||||
abstract Object execute(Object self, Object that);
|
||||
|
||||
static LessOrEqualNode build() {
|
||||
return LessOrEqualNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
boolean doLong(long self, long that) {
|
||||
return self <= that;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
boolean doDouble(long self, double that) {
|
||||
return (double) self <= that;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
boolean doBigInteger(long self, EnsoBigInteger that) {
|
||||
return that.getValue().signum() > 0;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
boolean doDouble(EnsoBigInteger self, double that) {
|
||||
return BigIntegerOps.toDouble(self.getValue()) <= that;
|
||||
@ -34,7 +49,7 @@ public abstract class LessOrEqualNode extends Node {
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(EnsoBigInteger self, Object that) {
|
||||
Object doOther(Object self, Object that) {
|
||||
var builtins = EnsoContext.get(this).getBuiltins();
|
||||
var incomparableValsErr = builtins.error().makeIncomparableValues(self, that);
|
||||
return DataflowError.withoutTrace(incomparableValsErr, this);
|
@ -0,0 +1,85 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.integer;
|
||||
|
||||
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import java.math.BigInteger;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.error.DataflowError;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Integer", name = "%", description = "Modulo division of numbers.")
|
||||
public abstract class ModNode extends Node {
|
||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||
|
||||
abstract Object execute(Object self, Object that);
|
||||
|
||||
static ModNode build() {
|
||||
return ModNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doLong(long self, long that) {
|
||||
try {
|
||||
return self % that;
|
||||
} catch (ArithmeticException e) {
|
||||
return DataflowError.withoutTrace(
|
||||
EnsoContext.get(this).getBuiltins().error().getDivideByZeroError(), this);
|
||||
}
|
||||
}
|
||||
|
||||
@Specialization
|
||||
double doDouble(long self, double that) {
|
||||
// No need to try-catch, as floating-point modulo returns NaN for division by zero instead of
|
||||
// throwing.
|
||||
return self % that;
|
||||
}
|
||||
|
||||
@TruffleBoundary
|
||||
@Specialization
|
||||
Object doBigInteger(long self, EnsoBigInteger that) {
|
||||
var selfBigInt = BigInteger.valueOf(self);
|
||||
try {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.modulo(selfBigInt, that.getValue()));
|
||||
} catch (ArithmeticException e) {
|
||||
return DataflowError.withoutTrace(
|
||||
EnsoContext.get(this).getBuiltins().error().getDivideByZeroError(), this);
|
||||
}
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doLong(EnsoBigInteger self, long that) {
|
||||
try {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.modulo(self.getValue(), that));
|
||||
} catch (ArithmeticException e) {
|
||||
return DataflowError.withoutTrace(
|
||||
EnsoContext.get(this).getBuiltins().error().getDivideByZeroError(), this);
|
||||
}
|
||||
}
|
||||
|
||||
@Specialization
|
||||
double doDouble(EnsoBigInteger self, double that) {
|
||||
// No need to trap, as floating-point modulo returns NaN for division by zero instead of
|
||||
// throwing.
|
||||
return BigIntegerOps.toDouble(self.getValue()) % that;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doBigInteger(EnsoBigInteger self, EnsoBigInteger that) {
|
||||
try {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.modulo(self.getValue(), that.getValue()));
|
||||
} catch (ArithmeticException e) {
|
||||
return DataflowError.withoutTrace(
|
||||
EnsoContext.get(this).getBuiltins().error().getDivideByZeroError(), this);
|
||||
}
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(Object self, Object that) {
|
||||
throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this);
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.smallInteger;
|
||||
package org.enso.interpreter.node.expression.builtin.number.integer;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
@ -6,16 +6,13 @@ import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Small_Integer", name = "*", description = "Multiplication of numbers.")
|
||||
@BuiltinMethod(type = "Integer", name = "*", description = "Multiplication of numbers.")
|
||||
public abstract class MultiplyNode extends Node {
|
||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||
|
||||
abstract Object execute(long self, Object that);
|
||||
abstract Object execute(Object self, Object that);
|
||||
|
||||
static MultiplyNode build() {
|
||||
return MultiplyNodeGen.create();
|
||||
@ -41,10 +38,23 @@ public abstract class MultiplyNode extends Node {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.multiply(that.getValue(), self));
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doLong(EnsoBigInteger self, long that) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.multiply(self.getValue(), that));
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doBigInteger(EnsoBigInteger self, EnsoBigInteger that) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.multiply(self.getValue(), that.getValue()));
|
||||
}
|
||||
|
||||
@Specialization
|
||||
double doDouble(EnsoBigInteger self, double that) {
|
||||
return BigIntegerOps.toDouble(self.getValue()) * that;
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(long self, Object that) {
|
||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
||||
var number = builtins.number().getNumber();
|
||||
throw new PanicException(builtins.error().makeTypeError(number, that, "that"), this);
|
||||
Object doOther(Object self, Object that) {
|
||||
throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this);
|
||||
}
|
||||
}
|
@ -1,12 +1,14 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.smallInteger;
|
||||
package org.enso.interpreter.node.expression.builtin.number.integer;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Small_Integer", name = "negate", description = "Negation for numbers.")
|
||||
@BuiltinMethod(type = "Integer", name = "negate", description = "Negation for numbers.")
|
||||
public abstract class NegateNode extends Node {
|
||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||
|
||||
@ -14,15 +16,25 @@ public abstract class NegateNode extends Node {
|
||||
return NegateNodeGen.create();
|
||||
}
|
||||
|
||||
abstract Object execute(long self);
|
||||
abstract Object execute(Object self);
|
||||
|
||||
@Specialization(rewriteOn = ArithmeticException.class)
|
||||
long doNormal(long self) {
|
||||
return Math.negateExact(self);
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doBigInt(EnsoBigInteger self) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.negate(self.getValue()));
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doOverflow(long self) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.negate(self));
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(Object self) {
|
||||
throw IntegerUtils.throwTypeErrorIfNotInt(self, this);
|
||||
}
|
||||
}
|
@ -1,26 +1,58 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.bigInteger;
|
||||
package org.enso.interpreter.node.expression.builtin.number.integer;
|
||||
|
||||
import com.oracle.truffle.api.CompilerDirectives;
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import java.math.BigInteger;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Big_Integer", name = "^", description = "Big integer exponentiation.")
|
||||
@BuiltinMethod(type = "Integer", name = "^", description = "Exponentiation of numbers.")
|
||||
public abstract class PowNode extends Node {
|
||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||
private @Child MultiplyNode multiplyNode = MultiplyNode.build();
|
||||
|
||||
public abstract Object execute(EnsoBigInteger self, Object that);
|
||||
abstract Object execute(Object self, Object that);
|
||||
|
||||
public static PowNode build() {
|
||||
static PowNode build() {
|
||||
return PowNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doLong(long self, long that) {
|
||||
if (that < 0) {
|
||||
return Math.pow(self, that);
|
||||
} else if (that == 0) {
|
||||
return 1L;
|
||||
} else {
|
||||
Object res = 1L;
|
||||
Object base = self;
|
||||
while (that > 0) {
|
||||
if (that % 2 == 0) {
|
||||
base = multiplyNode.execute(base, base);
|
||||
that /= 2;
|
||||
} else {
|
||||
res = multiplyNode.execute(res, base);
|
||||
that--;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
@Specialization
|
||||
double doDouble(long self, double that) {
|
||||
return Math.pow(self, that);
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doBigInteger(long self, EnsoBigInteger that) {
|
||||
return doBigInteger(toBigInteger(self), that);
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doLong(EnsoBigInteger self, long that) {
|
||||
if (that == 0) {
|
||||
@ -49,10 +81,13 @@ public abstract class PowNode extends Node {
|
||||
return Math.pow(BigIntegerOps.toDouble(self.getValue()), that);
|
||||
}
|
||||
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
private static EnsoBigInteger toBigInteger(long self) {
|
||||
return new EnsoBigInteger(BigInteger.valueOf(self));
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(EnsoBigInteger self, Object that) {
|
||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
||||
var number = builtins.number().getNumber();
|
||||
throw new PanicException(builtins.error().makeTypeError(number, that, "that"), this);
|
||||
Object doOther(Object self, Object that) {
|
||||
throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this);
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.smallInteger;
|
||||
package org.enso.interpreter.node.expression.builtin.number.integer;
|
||||
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import com.oracle.truffle.api.profiles.BranchProfile;
|
@ -1,4 +1,4 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.smallInteger;
|
||||
package org.enso.interpreter.node.expression.builtin.number.integer;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
@ -6,16 +6,13 @@ import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Small_Integer", name = "-", description = "Subtraction of numbers.")
|
||||
@BuiltinMethod(type = "Integer", name = "-", description = "Subtraction of numbers.")
|
||||
public abstract class SubtractNode extends Node {
|
||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||
|
||||
abstract Object execute(long self, Object that);
|
||||
abstract Object execute(Object self, Object that);
|
||||
|
||||
static SubtractNode build() {
|
||||
return SubtractNodeGen.create();
|
||||
@ -41,10 +38,23 @@ public abstract class SubtractNode extends Node {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.subtract(self, that.getValue()));
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doLong(EnsoBigInteger self, long that) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.subtract(self.getValue(), that));
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doBigInteger(EnsoBigInteger self, EnsoBigInteger that) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.subtract(self.getValue(), that.getValue()));
|
||||
}
|
||||
|
||||
@Specialization
|
||||
double doDouble(EnsoBigInteger self, double that) {
|
||||
return BigIntegerOps.toDouble(self.getValue()) - that;
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(long self, Object that) {
|
||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
||||
var number = builtins.number().getNumber();
|
||||
throw new PanicException(builtins.error().makeTypeError(number, that, "that"), this);
|
||||
Object doOther(Object self, Object that) {
|
||||
throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this);
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.integer;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(
|
||||
type = "Integer",
|
||||
name = "to_decimal",
|
||||
description = "Conversion of integers to decimals.")
|
||||
public abstract class ToDecimalNode extends Node {
|
||||
public abstract Object execute(Object self);
|
||||
|
||||
public static ToDecimalNode build() {
|
||||
return ToDecimalNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
double doLong(long self) {
|
||||
return self;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
double doBigInt(EnsoBigInteger self) {
|
||||
return BigIntegerOps.toDouble(self.getValue());
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(Object self) {
|
||||
throw IntegerUtils.throwTypeErrorIfNotInt(self, this);
|
||||
}
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.smallInteger;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Small_Integer", name = "+", description = "Addition of numbers.")
|
||||
public abstract class AddNode extends Node {
|
||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||
|
||||
abstract Object execute(long self, Object that);
|
||||
|
||||
static AddNode build() {
|
||||
return AddNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization(rewriteOn = ArithmeticException.class)
|
||||
long doLong(long self, long that) {
|
||||
return Math.addExact(self, that);
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doOverflow(long self, long that) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.add(self, that));
|
||||
}
|
||||
|
||||
@Specialization
|
||||
double doDouble(long self, double that) {
|
||||
return self + that;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doBigInteger(long self, EnsoBigInteger that) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.add(that.getValue(), self));
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(long self, Object that) {
|
||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
||||
var number = builtins.number().getNumber();
|
||||
throw new PanicException(builtins.error().makeTypeError(number, that, "that"), this);
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.smallInteger;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Small_Integer", name = "bit_and", description = "Bitwise and.")
|
||||
public abstract class BitAndNode extends Node {
|
||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||
|
||||
abstract Object execute(Object self, Object that);
|
||||
|
||||
static BitAndNode build() {
|
||||
return BitAndNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
long doLong(long self, long that) {
|
||||
return self & that;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doBigInteger(long self, EnsoBigInteger that) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.bitAnd(self, that.getValue()));
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(Object self, Object that) {
|
||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
||||
var integer = builtins.number().getInteger();
|
||||
throw new PanicException(builtins.error().makeTypeError(integer, that, "that"), this);
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.smallInteger;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
|
||||
@BuiltinMethod(type = "Small_Integer", name = "bit_not", description = "Bitwise negation.")
|
||||
public abstract class BitNotNode extends Node {
|
||||
abstract Object execute(Object self);
|
||||
|
||||
static BitNotNode build() {
|
||||
return BitNotNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
long doLong(long self) {
|
||||
return ~self;
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(Object self) {
|
||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
||||
var integer = builtins.number().getInteger();
|
||||
throw new PanicException(builtins.error().makeTypeError(integer, self, "this"), this);
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.smallInteger;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Small_Integer", name = "bit_or", description = "Bitwise or.")
|
||||
public abstract class BitOrNode extends Node {
|
||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||
|
||||
abstract Object execute(long self, Object that);
|
||||
|
||||
static BitOrNode build() {
|
||||
return BitOrNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
long doLong(long self, long that) {
|
||||
return self | that;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doBigInteger(long self, EnsoBigInteger that) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.bitOr(self, that.getValue()));
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(long self, Object that) {
|
||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
||||
var integer = builtins.number().getInteger();
|
||||
throw new PanicException(builtins.error().makeTypeError(integer, that, "that"), this);
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.smallInteger;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Cached;
|
||||
import com.oracle.truffle.api.dsl.Cached.Shared;
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Small_Integer", name = "bit_shift_r", description = "Bitwise right-shift.")
|
||||
public abstract class BitShiftRightNode extends Node {
|
||||
abstract Object execute(long self, Object that);
|
||||
|
||||
static BitShiftRightNode build() {
|
||||
return BitShiftRightNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doBigInteger(
|
||||
long self, long that, @Shared("bitShiftNode") @Cached("build()") BitShiftNode bitShiftNode) {
|
||||
return bitShiftNode.execute(self, -1L * that);
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doBigInteger(
|
||||
long self,
|
||||
EnsoBigInteger that,
|
||||
@Shared("bitShiftNode") @Cached("build()") BitShiftNode bitShiftNode) {
|
||||
return bitShiftNode.execute(self, new EnsoBigInteger(BigIntegerOps.negate(that.getValue())));
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(long self, Object that) {
|
||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
||||
var integer = builtins.number().getInteger();
|
||||
throw new PanicException(builtins.error().makeTypeError(integer, that, "that"), this);
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.smallInteger;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Small_Integer", name = "bit_xor", description = "Bitwise exclusive or.")
|
||||
public abstract class BitXorNode extends Node {
|
||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||
|
||||
abstract Object execute(long self, Object that);
|
||||
|
||||
static BitXorNode build() {
|
||||
return BitXorNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
long doLong(long self, long that) {
|
||||
return self ^ that;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doBigInteger(long self, EnsoBigInteger that) {
|
||||
return toEnsoNumberNode.execute(BigIntegerOps.bitXor(self, that.getValue()));
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(long self, Object that) {
|
||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
||||
var integer = builtins.number().getInteger();
|
||||
throw new PanicException(builtins.error().makeTypeError(integer, that, "that"), this);
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.smallInteger;
|
||||
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
|
||||
@BuiltinMethod(type = "Small_Integer", name = "ceil", description = "Small integer ceiling.")
|
||||
public class CeilNode extends Node {
|
||||
long execute(long self) {
|
||||
return self;
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.smallInteger;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.error.DataflowError;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Small_Integer", name = "div", description = "Division of numbers.")
|
||||
public abstract class DivNode extends Node {
|
||||
abstract Object execute(long self, Object that);
|
||||
|
||||
static DivNode build() {
|
||||
return DivNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doLong(long self, long that) {
|
||||
try {
|
||||
return self / that;
|
||||
} catch (ArithmeticException e) {
|
||||
return DataflowError.withoutTrace(
|
||||
EnsoContext.get(this).getBuiltins().error().getDivideByZeroError(), this);
|
||||
}
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doBigInteger(long self, EnsoBigInteger that) {
|
||||
// No need to trap, as 0 is never represented as an EnsoBigInteger.
|
||||
return 0L;
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(long self, Object that) {
|
||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
||||
var integer = builtins.number().getInteger();
|
||||
throw new PanicException(builtins.error().makeTypeError(integer, that, "that"), this);
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.smallInteger;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Small_Integer", name = "/", description = "Division of numbers.")
|
||||
public abstract class DivideNode extends Node {
|
||||
abstract double execute(long self, Object that);
|
||||
|
||||
static DivideNode build() {
|
||||
return DivideNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
double doLong(long self, long that) {
|
||||
return ((double) self) / ((double) that);
|
||||
}
|
||||
|
||||
@Specialization
|
||||
double doDouble(long self, double that) {
|
||||
return self / that;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
double doBigInteger(long self, EnsoBigInteger that) {
|
||||
return ((double) self) / BigIntegerOps.toDouble(that.getValue());
|
||||
}
|
||||
|
||||
@Fallback
|
||||
double doOther(long self, Object that) {
|
||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
||||
var number = builtins.number().getNumber();
|
||||
throw new PanicException(builtins.error().makeTypeError(number, that, "that"), this);
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.smallInteger;
|
||||
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
|
||||
@BuiltinMethod(type = "Small_Integer", name = "floor", description = "Small integer floor.")
|
||||
public class FloorNode extends Node {
|
||||
long execute(long self) {
|
||||
return self;
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.smallInteger;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.error.DataflowError;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Small_Integer", name = ">", description = "Comparison of numbers.")
|
||||
public abstract class GreaterNode extends Node {
|
||||
|
||||
abstract Object execute(long self, Object that);
|
||||
|
||||
static GreaterNode build() {
|
||||
return GreaterNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
boolean doLong(long self, long that) {
|
||||
return self > that;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
boolean doDouble(long self, double that) {
|
||||
return (double) self > that;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
boolean doBigInteger(long self, EnsoBigInteger that) {
|
||||
return that.getValue().signum() < 0;
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(long self, Object that) {
|
||||
var builtins = EnsoContext.get(this).getBuiltins();
|
||||
var incomparableValsErr = builtins.error().makeIncomparableValues(self, that);
|
||||
return DataflowError.withoutTrace(incomparableValsErr, this);
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.smallInteger;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.error.DataflowError;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Small_Integer", name = ">=", description = "Comparison of numbers.")
|
||||
public abstract class GreaterOrEqualNode extends Node {
|
||||
|
||||
abstract Object execute(long self, Object that);
|
||||
|
||||
static GreaterOrEqualNode build() {
|
||||
return GreaterOrEqualNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
boolean doLong(long self, long that) {
|
||||
return self >= that;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
boolean doDouble(long self, double that) {
|
||||
return (double) self >= that;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
boolean doBigInteger(long self, EnsoBigInteger that) {
|
||||
return that.getValue().signum() < 0;
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(long self, Object that) {
|
||||
var builtins = EnsoContext.get(this).getBuiltins();
|
||||
var incomparableValsErr = builtins.error().makeIncomparableValues(self, that);
|
||||
return DataflowError.withoutTrace(incomparableValsErr, this);
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.smallInteger;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.error.DataflowError;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Small_Integer", name = "<", description = "Comparison of numbers.")
|
||||
public abstract class LessNode extends Node {
|
||||
|
||||
abstract Object execute(long self, Object that);
|
||||
|
||||
static LessNode build() {
|
||||
return LessNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
boolean doLong(long self, long that) {
|
||||
return self < that;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
boolean doDouble(long self, double that) {
|
||||
return (double) self < that;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
boolean doBigInteger(long self, EnsoBigInteger that) {
|
||||
return that.getValue().signum() > 0;
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(long self, Object that) {
|
||||
var builtins = EnsoContext.get(this).getBuiltins();
|
||||
var incomparableValsErr = builtins.error().makeIncomparableValues(self, that);
|
||||
return DataflowError.withoutTrace(incomparableValsErr, this);
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.smallInteger;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.error.DataflowError;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Small_Integer", name = "<=", description = "Comparison of numbers.")
|
||||
public abstract class LessOrEqualNode extends Node {
|
||||
|
||||
abstract Object execute(long self, Object that);
|
||||
|
||||
static LessOrEqualNode build() {
|
||||
return LessOrEqualNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
boolean doLong(long self, long that) {
|
||||
return self <= that;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
boolean doDouble(long self, double that) {
|
||||
return (double) self <= that;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
boolean doBigInteger(long self, EnsoBigInteger that) {
|
||||
return that.getValue().signum() > 0;
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(long self, Object that) {
|
||||
var builtins = EnsoContext.get(this).getBuiltins();
|
||||
var incomparableValsErr = builtins.error().makeIncomparableValues(self, that);
|
||||
return DataflowError.withoutTrace(incomparableValsErr, this);
|
||||
}
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.smallInteger;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.error.DataflowError;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Small_Integer", name = "%", description = "Modulo division of numbers.")
|
||||
public abstract class ModNode extends Node {
|
||||
abstract Object execute(long self, Object that);
|
||||
|
||||
static ModNode build() {
|
||||
return ModNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doLong(long self, long that) {
|
||||
try {
|
||||
return self % that;
|
||||
} catch (ArithmeticException e) {
|
||||
return DataflowError.withoutTrace(
|
||||
EnsoContext.get(this).getBuiltins().error().getDivideByZeroError(), this);
|
||||
}
|
||||
}
|
||||
|
||||
@Specialization
|
||||
double doDouble(long self, double that) {
|
||||
// No need to trap, as floating-point modulo returns NaN for division by zero instead of
|
||||
// throwing.
|
||||
return self % that;
|
||||
}
|
||||
|
||||
@Specialization
|
||||
long doBigInteger(long self, EnsoBigInteger that) {
|
||||
// No need to trap, as 0 is never represented as an EnsoBigInteger.
|
||||
return self;
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(long self, Object that) {
|
||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
||||
var number = builtins.number().getNumber();
|
||||
throw new PanicException(builtins.error().makeTypeError(number, that, "that"), this);
|
||||
}
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.smallInteger;
|
||||
|
||||
import com.oracle.truffle.api.CompilerDirectives;
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import java.math.BigInteger;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
|
||||
@BuiltinMethod(type = "Small_Integer", name = "^", description = "Exponentiation of numbers.")
|
||||
public abstract class PowNode extends Node {
|
||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||
private @Child org.enso.interpreter.node.expression.builtin.number.smallInteger.MultiplyNode
|
||||
longMultiplyNode =
|
||||
org.enso.interpreter.node.expression.builtin.number.smallInteger.MultiplyNode.build();
|
||||
private @Child org.enso.interpreter.node.expression.builtin.number.bigInteger.MultiplyNode
|
||||
bigIntMultiplyNode =
|
||||
org.enso.interpreter.node.expression.builtin.number.bigInteger.MultiplyNode.build();
|
||||
private @Child org.enso.interpreter.node.expression.builtin.number.bigInteger.PowNode
|
||||
bigIntPowNode =
|
||||
org.enso.interpreter.node.expression.builtin.number.bigInteger.PowNode.build();
|
||||
|
||||
abstract Object execute(long self, Object that);
|
||||
|
||||
static PowNode build() {
|
||||
return PowNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doLong(long self, long that) {
|
||||
if (that < 0) {
|
||||
return Math.pow(self, that);
|
||||
} else if (that == 0) {
|
||||
return 1L;
|
||||
} else {
|
||||
Object res = 1L;
|
||||
Object base = self;
|
||||
while (that > 0) {
|
||||
if (that % 2 == 0) {
|
||||
if (base instanceof Long) {
|
||||
base = longMultiplyNode.execute((long) base, base);
|
||||
} else {
|
||||
base = bigIntMultiplyNode.execute((EnsoBigInteger) base, base);
|
||||
}
|
||||
that /= 2;
|
||||
} else {
|
||||
if (res instanceof Long) {
|
||||
res = longMultiplyNode.execute((long) res, base);
|
||||
} else {
|
||||
res = bigIntMultiplyNode.execute((EnsoBigInteger) res, base);
|
||||
}
|
||||
that--;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
@Specialization
|
||||
double doDouble(long self, double that) {
|
||||
return Math.pow(self, that);
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doBigInteger(long self, EnsoBigInteger that) {
|
||||
return bigIntPowNode.execute(toBigInteger(self), that);
|
||||
}
|
||||
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
private static EnsoBigInteger toBigInteger(long self) {
|
||||
return new EnsoBigInteger(BigInteger.valueOf(self));
|
||||
}
|
||||
|
||||
@Fallback
|
||||
Object doOther(long self, Object that) {
|
||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
||||
var number = builtins.number().getNumber();
|
||||
throw new PanicException(builtins.error().makeTypeError(number, that, "that"), this);
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
package org.enso.interpreter.node.expression.builtin.number.smallInteger;
|
||||
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
|
||||
@BuiltinMethod(
|
||||
type = "Small_Integer",
|
||||
name = "to_decimal",
|
||||
description = "Conversion of integers to decimals.")
|
||||
public class ToDecimalNode extends Node {
|
||||
double execute(long self) {
|
||||
return self;
|
||||
}
|
||||
}
|
@ -1,40 +1,24 @@
|
||||
package org.enso.interpreter.runtime.builtin;
|
||||
|
||||
import org.enso.interpreter.node.expression.builtin.Builtin;
|
||||
import org.enso.interpreter.node.expression.builtin.number.BigInteger;
|
||||
import org.enso.interpreter.node.expression.builtin.number.Decimal;
|
||||
import org.enso.interpreter.node.expression.builtin.number.Integer;
|
||||
import org.enso.interpreter.node.expression.builtin.number.SmallInteger;
|
||||
import org.enso.interpreter.runtime.data.Type;
|
||||
|
||||
/** A container for all number-related builtins. */
|
||||
public class Number {
|
||||
private final Builtin smallInteger;
|
||||
private final Builtin bigInteger;
|
||||
private final Builtin integer;
|
||||
private final Builtin number;
|
||||
private final Builtin decimal;
|
||||
|
||||
/** Creates builders for number Atom Constructors. */
|
||||
public Number(Builtins builtins) {
|
||||
smallInteger = builtins.getBuiltinType(SmallInteger.class);
|
||||
bigInteger = builtins.getBuiltinType(BigInteger.class);
|
||||
integer = builtins.getBuiltinType(Integer.class);
|
||||
number =
|
||||
builtins.getBuiltinType(org.enso.interpreter.node.expression.builtin.number.Number.class);
|
||||
decimal = builtins.getBuiltinType(Decimal.class);
|
||||
}
|
||||
|
||||
/** @return the Int64 atom constructor. */
|
||||
public Type getSmallInteger() {
|
||||
return smallInteger.getType();
|
||||
}
|
||||
|
||||
/** @return the Big_Integer atom constructor. */
|
||||
public Type getBigInteger() {
|
||||
return bigInteger.getType();
|
||||
}
|
||||
|
||||
/** @return the Integer atom constructor */
|
||||
public Type getInteger() {
|
||||
return integer.getType();
|
||||
|
@ -17,6 +17,6 @@ public class DefaultLongExports {
|
||||
@ExportMessage
|
||||
static Type getType(
|
||||
Long receiver, @CachedLibrary("receiver") TypesLibrary thisLib, @Cached("1") int ignore) {
|
||||
return EnsoContext.get(thisLib).getBuiltins().number().getSmallInteger();
|
||||
return EnsoContext.get(thisLib).getBuiltins().number().getInteger();
|
||||
}
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ public final class EnsoBigInteger implements EnsoObject {
|
||||
|
||||
@ExportMessage
|
||||
Type getMetaObject(@CachedLibrary("this") InteropLibrary thisLib) {
|
||||
return EnsoContext.get(thisLib).getBuiltins().number().getBigInteger();
|
||||
return EnsoContext.get(thisLib).getBuiltins().number().getInteger();
|
||||
}
|
||||
|
||||
@ExportMessage
|
||||
@ -146,7 +146,7 @@ public final class EnsoBigInteger implements EnsoObject {
|
||||
|
||||
@ExportMessage
|
||||
Type getType(@CachedLibrary("this") TypesLibrary thisLib, @Cached("1") int ignore) {
|
||||
return EnsoContext.get(thisLib).getBuiltins().number().getBigInteger();
|
||||
return EnsoContext.get(thisLib).getBuiltins().number().getInteger();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,71 @@
|
||||
package org.enso.interpreter.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import org.enso.interpreter.node.expression.builtin.number.integer.AbsNode;
|
||||
import org.enso.interpreter.node.expression.builtin.number.integer.AddNode;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
import org.graalvm.polyglot.Context;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.experimental.theories.Theories;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
/** Tests Truffle nodes for integer operations. */
|
||||
@RunWith(Theories.class)
|
||||
public class IntegerTest extends TestBase {
|
||||
|
||||
private static AbsNode absNode;
|
||||
private static AddNode addNode;
|
||||
private static Context ctx;
|
||||
|
||||
@BeforeClass
|
||||
public static void setup() {
|
||||
ctx = createDefaultContext();
|
||||
executeInContext(
|
||||
ctx,
|
||||
() -> {
|
||||
absNode = AbsNode.build();
|
||||
addNode = AddNode.build();
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
private static final EnsoBigInteger bigInt =
|
||||
new EnsoBigInteger(new BigInteger("1000000000000000000000000000000000000"));
|
||||
private static final EnsoBigInteger bigIntNegative =
|
||||
new EnsoBigInteger(new BigInteger("-1000000000000000000000000000000000000"));
|
||||
|
||||
@Test
|
||||
public void testAbs() {
|
||||
executeInContext(
|
||||
ctx,
|
||||
() -> {
|
||||
assertEquals(23L, absNode.execute(23L));
|
||||
assertEquals(23L, absNode.execute(-23L));
|
||||
assertTrue(absNode.execute(Long.MIN_VALUE) instanceof EnsoBigInteger);
|
||||
assertEquals(bigInt, absNode.execute(bigInt));
|
||||
assertEquals(bigInt, absNode.execute(bigIntNegative));
|
||||
assertThrows(
|
||||
"Decimals are not supported", PanicException.class, () -> absNode.execute(23.0));
|
||||
assertThrows(
|
||||
"Java int is not supported", PanicException.class, () -> absNode.execute(23));
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdd() {
|
||||
executeInContext(
|
||||
ctx,
|
||||
() -> {
|
||||
assertEquals(23L, addNode.execute(22L, 1L));
|
||||
assertThrows(PanicException.class, () -> addNode.execute(23L, "Hello"));
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
@ -133,7 +133,7 @@ class TextTest extends InterpreterTest {
|
||||
"Compile error: error :(.",
|
||||
"Inexhaustive pattern match: no branch matches 32.",
|
||||
"Arithmetic error: cannot frobnicate quaternions.",
|
||||
"Type error: expected `that` to be Number, but got Text.",
|
||||
"Type error: expected `that` to be Integer, but got Text.",
|
||||
"Type error: expected a function, but got 7.",
|
||||
"Wrong number of arguments. Expected 10, but got 20."
|
||||
)
|
||||
|
@ -225,6 +225,13 @@ spec =
|
||||
Integer.parse "-101021010" 2 . should_fail_with Number_Parse_Error
|
||||
Integer.parse "123" 128 . should_fail_with Number_Parse_Error
|
||||
|
||||
Test.specify "should be able to invoke methods on Integer via static method call" <|
|
||||
Integer.+ 1 2 . should_equal 3
|
||||
Integer.+ 1 2.5 . should_equal 3.5
|
||||
Test.expect_panic_with (Integer.+ 1.5 1) Type_Error
|
||||
Test.expect_panic_with (Integer.+ 1.5 2.5) Type_Error
|
||||
Test.expect_panic_with (Integer.+ 1 "hello") Type_Error
|
||||
|
||||
Test.group "Decimals" <|
|
||||
|
||||
Test.specify "should exist and expose basic arithmetic operations" <|
|
||||
@ -297,6 +304,10 @@ spec =
|
||||
1/0 . is_infinite . should_be_true
|
||||
-1/0 . is_infinite . should_be_true
|
||||
|
||||
hundred_factorial%0 . should_fail_with Arithmetic_Error
|
||||
hundred_factorial%hundred_factorial . should_equal 0
|
||||
10%hundred_factorial . should_equal 10
|
||||
|
||||
Test.specify "should support less than operator" <|
|
||||
(1 < 2).should_be_true
|
||||
(1 < 1).should_be_false
|
||||
|
@ -258,10 +258,10 @@ spec =
|
||||
methods.sort . should_equal ['Value', 'create', 'factory', 'first_method', 'my_method', 'other_method', 'second_method']
|
||||
|
||||
Test.specify "methods of Integer" <|
|
||||
Meta.meta Integer . methods . sort . should_equal ['bit_shift_l', 'round', 'truncate']
|
||||
Meta.meta Integer . methods . sort . should_equal ['%', '*', '+', '-', '/', '<', '<=', '>', '>=', '^', 'abs', 'bit_and', 'bit_not', 'bit_or', 'bit_shift', 'bit_shift_l', 'bit_shift_r', 'bit_xor', 'ceil', 'div', 'floor', 'negate', 'round', 'to_decimal', 'truncate']
|
||||
|
||||
Test.specify "static methods of Integer" <|
|
||||
Meta.meta (Meta.type_of Integer) . methods . sort . should_equal ['bit_shift_l', 'parse', 'parse_builtin', 'round', 'round_integer_builtin', 'truncate']
|
||||
Meta.meta (Meta.type_of Integer) . methods . sort . should_equal ['%', '*', '+', '-', '/', '<', '<=', '>', '>=', '^', 'abs', 'bit_and', 'bit_not', 'bit_or', 'bit_shift', 'bit_shift_l', 'bit_shift_r', 'bit_xor', 'ceil', 'div', 'floor', 'negate', 'parse', 'parse_builtin', 'round', 'round_integer_builtin', 'to_decimal', 'truncate']
|
||||
|
||||
Test.specify "methods of Any" <|
|
||||
Meta.meta Any . methods . should_contain "to_text"
|
||||
|
Loading…
Reference in New Issue
Block a user