mirror of
https://github.com/enso-org/enso.git
synced 2024-11-22 22:10:15 +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]
|
- [Use `numpy` & co. from Enso!][7678]
|
||||||
- [Changed layout of local libraries directory, making it easier to reference
|
- [Changed layout of local libraries directory, making it easier to reference
|
||||||
projects next to each other][7634]
|
projects next to each other][7634]
|
||||||
|
- [Merge `Small_Integer` and `Big_Integer` types][7636]
|
||||||
|
|
||||||
[3227]: https://github.com/enso-org/enso/pull/3227
|
[3227]: https://github.com/enso-org/enso/pull/3227
|
||||||
[3248]: https://github.com/enso-org/enso/pull/3248
|
[3248]: https://github.com/enso-org/enso/pull/3248
|
||||||
@ -1082,6 +1083,7 @@
|
|||||||
[7613]: https://github.com/enso-org/enso/pull/7613
|
[7613]: https://github.com/enso-org/enso/pull/7613
|
||||||
[7678]: https://github.com/enso-org/enso/pull/7678
|
[7678]: https://github.com/enso-org/enso/pull/7678
|
||||||
[7634]: https://github.com/enso-org/enso/pull/7634
|
[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)
|
# Enso 2.0.0-alpha.18 (2021-10-12)
|
||||||
|
|
||||||
|
@ -5092,7 +5092,7 @@ class RuntimeServerTest
|
|||||||
Api.ExecutionFailed(
|
Api.ExecutionFailed(
|
||||||
contextId,
|
contextId,
|
||||||
Api.ExecutionResult.Diagnostic.error(
|
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(mainFile),
|
||||||
Some(model.Range(model.Position(11, 8), model.Position(11, 17))),
|
Some(model.Range(model.Position(11, 8), model.Position(11, 17))),
|
||||||
None,
|
None,
|
||||||
|
@ -187,7 +187,15 @@ class RuntimeVisualizationsTest
|
|||||||
Api.ExpressionUpdate(
|
Api.ExpressionUpdate(
|
||||||
Main.idMainZ,
|
Main.idMainZ,
|
||||||
Some(ConstantsGen.INTEGER),
|
Some(ConstantsGen.INTEGER),
|
||||||
None,
|
Some(
|
||||||
|
Api.MethodCall(
|
||||||
|
Api.MethodPointer(
|
||||||
|
"Standard.Base.Data.Numbers",
|
||||||
|
"Standard.Base.Data.Numbers.Integer",
|
||||||
|
"+"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
Vector(Api.ProfilingInfo.ExecutionTime(0)),
|
Vector(Api.ProfilingInfo.ExecutionTime(0)),
|
||||||
fromCache,
|
fromCache,
|
||||||
typeChanged,
|
typeChanged,
|
||||||
@ -209,7 +217,15 @@ class RuntimeVisualizationsTest
|
|||||||
Api.ExpressionUpdate(
|
Api.ExpressionUpdate(
|
||||||
Main.idFooY,
|
Main.idFooY,
|
||||||
Some(ConstantsGen.INTEGER),
|
Some(ConstantsGen.INTEGER),
|
||||||
None,
|
Some(
|
||||||
|
Api.MethodCall(
|
||||||
|
Api.MethodPointer(
|
||||||
|
"Standard.Base.Data.Numbers",
|
||||||
|
"Standard.Base.Data.Numbers.Integer",
|
||||||
|
"+"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
Vector(Api.ProfilingInfo.ExecutionTime(0)),
|
Vector(Api.ProfilingInfo.ExecutionTime(0)),
|
||||||
fromCache,
|
fromCache,
|
||||||
typeChanged,
|
typeChanged,
|
||||||
@ -231,7 +247,15 @@ class RuntimeVisualizationsTest
|
|||||||
Api.ExpressionUpdate(
|
Api.ExpressionUpdate(
|
||||||
Main.idFooZ,
|
Main.idFooZ,
|
||||||
Some(ConstantsGen.INTEGER),
|
Some(ConstantsGen.INTEGER),
|
||||||
None,
|
Some(
|
||||||
|
Api.MethodCall(
|
||||||
|
Api.MethodPointer(
|
||||||
|
"Standard.Base.Data.Numbers",
|
||||||
|
"Standard.Base.Data.Numbers.Integer",
|
||||||
|
"*"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
Vector(Api.ProfilingInfo.ExecutionTime(0)),
|
Vector(Api.ProfilingInfo.ExecutionTime(0)),
|
||||||
fromCache,
|
fromCache,
|
||||||
typeChanged,
|
typeChanged,
|
||||||
@ -973,12 +997,30 @@ class RuntimeVisualizationsTest
|
|||||||
contextId,
|
contextId,
|
||||||
context.Main.idFooY,
|
context.Main.idFooY,
|
||||||
ConstantsGen.INTEGER,
|
ConstantsGen.INTEGER,
|
||||||
|
methodCall = Some(
|
||||||
|
Api.MethodCall(
|
||||||
|
Api.MethodPointer(
|
||||||
|
"Standard.Base.Data.Numbers",
|
||||||
|
"Standard.Base.Data.Numbers.Integer",
|
||||||
|
"+"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
typeChanged = false
|
typeChanged = false
|
||||||
),
|
),
|
||||||
TestMessages.update(
|
TestMessages.update(
|
||||||
contextId,
|
contextId,
|
||||||
context.Main.idFooZ,
|
context.Main.idFooZ,
|
||||||
ConstantsGen.INTEGER,
|
ConstantsGen.INTEGER,
|
||||||
|
methodCall = Some(
|
||||||
|
Api.MethodCall(
|
||||||
|
Api.MethodPointer(
|
||||||
|
"Standard.Base.Data.Numbers",
|
||||||
|
"Standard.Base.Data.Numbers.Integer",
|
||||||
|
"*"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
typeChanged = false
|
typeChanged = false
|
||||||
),
|
),
|
||||||
context.executionComplete(contextId)
|
context.executionComplete(contextId)
|
||||||
|
@ -85,7 +85,7 @@ public abstract class IsValueOfTypeNode extends Node {
|
|||||||
@Specialization
|
@Specialization
|
||||||
boolean doLongCheck(Type expectedType, long payload) {
|
boolean doLongCheck(Type expectedType, long payload) {
|
||||||
var numbers = EnsoContext.get(this).getBuiltins().number();
|
var numbers = EnsoContext.get(this).getBuiltins().number();
|
||||||
return checkParentTypes(numbers.getSmallInteger(), expectedType);
|
return checkParentTypes(numbers.getInteger(), expectedType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Specialization
|
@Specialization
|
||||||
@ -97,7 +97,7 @@ public abstract class IsValueOfTypeNode extends Node {
|
|||||||
@Specialization
|
@Specialization
|
||||||
boolean doBigIntegerCheck(Type expectedType, EnsoBigInteger value) {
|
boolean doBigIntegerCheck(Type expectedType, EnsoBigInteger value) {
|
||||||
var numbers = EnsoContext.get(this).getBuiltins().number();
|
var numbers = EnsoContext.get(this).getBuiltins().number();
|
||||||
return checkParentTypes(numbers.getBigInteger(), expectedType);
|
return checkParentTypes(numbers.getInteger(), expectedType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Specialization
|
@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.dsl.Specialization;
|
||||||
import com.oracle.truffle.api.nodes.Node;
|
import com.oracle.truffle.api.nodes.Node;
|
||||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
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.BigIntegerOps;
|
||||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
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 {
|
public abstract class AbsNode extends Node {
|
||||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||||
|
|
||||||
static AbsNode build() {
|
public static AbsNode build() {
|
||||||
return AbsNodeGen.create();
|
return AbsNodeGen.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract Object execute(long self);
|
public abstract Object execute(Object self);
|
||||||
|
|
||||||
@Specialization(rewriteOn = ArithmeticException.class)
|
@Specialization(rewriteOn = ArithmeticException.class)
|
||||||
long doNormal(long self) {
|
long doLong(long self) {
|
||||||
if (self < 0) {
|
if (self < 0) {
|
||||||
return Math.negateExact(self);
|
return Math.negateExact(self);
|
||||||
} else {
|
} else {
|
||||||
@ -25,8 +27,18 @@ public abstract class AbsNode extends Node {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Specialization
|
@Specialization(replaces = "doLong")
|
||||||
Object doOverflow(long self) {
|
Object doLongOverflow(long self) {
|
||||||
return toEnsoNumberNode.execute(BigIntegerOps.abs(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.Fallback;
|
||||||
import com.oracle.truffle.api.dsl.Specialization;
|
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.dsl.BuiltinMethod;
|
||||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
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;
|
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 {
|
public abstract class BitAndNode extends Node {
|
||||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
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();
|
return BitAndNodeGen.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Specialization
|
@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));
|
return toEnsoNumberNode.execute(BigIntegerOps.bitAnd(self.getValue(), that));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Specialization
|
@Specialization
|
||||||
Object doBigInteger(EnsoBigInteger self, EnsoBigInteger that) {
|
Object doBigIntBigInt(EnsoBigInteger self, EnsoBigInteger that) {
|
||||||
return toEnsoNumberNode.execute(BigIntegerOps.bitAnd(self.getValue(), that.getValue()));
|
return toEnsoNumberNode.execute(BigIntegerOps.bitAnd(self.getValue(), that.getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Fallback
|
@Fallback
|
||||||
Object doOther(Object self, Object that) {
|
Object doOther(Object self, Object that) {
|
||||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this);
|
||||||
var integer = builtins.number().getInteger();
|
|
||||||
throw new PanicException(builtins.error().makeTypeError(integer, that, "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.Fallback;
|
||||||
import com.oracle.truffle.api.dsl.Specialization;
|
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.dsl.BuiltinMethod;
|
||||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
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;
|
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 {
|
public abstract class BitOrNode extends Node {
|
||||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||||
|
|
||||||
@ -21,6 +18,16 @@ public abstract class BitOrNode extends Node {
|
|||||||
return BitOrNodeGen.create();
|
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
|
@Specialization
|
||||||
Object doLong(EnsoBigInteger self, long that) {
|
Object doLong(EnsoBigInteger self, long that) {
|
||||||
return toEnsoNumberNode.execute(BigIntegerOps.bitOr(self.getValue(), that));
|
return toEnsoNumberNode.execute(BigIntegerOps.bitOr(self.getValue(), that));
|
||||||
@ -33,8 +40,6 @@ public abstract class BitOrNode extends Node {
|
|||||||
|
|
||||||
@Fallback
|
@Fallback
|
||||||
Object doOther(Object self, Object that) {
|
Object doOther(Object self, Object that) {
|
||||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this);
|
||||||
var integer = builtins.number().getInteger();
|
|
||||||
throw new PanicException(builtins.error().makeTypeError(integer, that, "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.Fallback;
|
||||||
import com.oracle.truffle.api.dsl.ImportStatic;
|
import com.oracle.truffle.api.dsl.ImportStatic;
|
||||||
import com.oracle.truffle.api.dsl.NeverDefault;
|
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.BigIntegerOps;
|
||||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
||||||
import org.enso.interpreter.runtime.EnsoContext;
|
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.DataflowError;
|
||||||
import org.enso.interpreter.runtime.error.PanicException;
|
|
||||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||||
|
|
||||||
@ImportStatic(BigIntegerOps.class)
|
@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 {
|
public abstract class BitShiftNode extends Node {
|
||||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||||
private final CountingConditionProfile canShiftLeftInLongProfile =
|
private final CountingConditionProfile canShiftLeftInLongProfile =
|
||||||
@ -26,7 +26,7 @@ public abstract class BitShiftNode extends Node {
|
|||||||
private final CountingConditionProfile rightShiftExceedsLongWidth =
|
private final CountingConditionProfile rightShiftExceedsLongWidth =
|
||||||
CountingConditionProfile.create();
|
CountingConditionProfile.create();
|
||||||
|
|
||||||
abstract Object execute(long self, Object that);
|
abstract Object execute(Object self, Object that);
|
||||||
|
|
||||||
@NeverDefault
|
@NeverDefault
|
||||||
static BitShiftNode build() {
|
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
|
@Fallback
|
||||||
Object doOther(long self, Object that) {
|
Object doOther(Object self, Object that) {
|
||||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this);
|
||||||
var integer = builtins.number().getInteger();
|
|
||||||
throw new PanicException(builtins.error().makeTypeError(integer, that, "that"), this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean hasFreeBitsLeftShift(long number, long shift) {
|
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;
|
||||||
import com.oracle.truffle.api.dsl.Cached.Shared;
|
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 com.oracle.truffle.api.nodes.Node;
|
||||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
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.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;
|
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 {
|
public abstract class BitShiftRightNode extends Node {
|
||||||
abstract Object execute(EnsoBigInteger self, Object that);
|
abstract Object execute(Object self, Object that);
|
||||||
|
|
||||||
static BitShiftRightNode build() {
|
static BitShiftRightNode build() {
|
||||||
return BitShiftRightNodeGen.create();
|
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
|
@Specialization
|
||||||
Object doBigInteger(
|
Object doBigInteger(
|
||||||
EnsoBigInteger self,
|
EnsoBigInteger self,
|
||||||
@ -37,9 +48,7 @@ public abstract class BitShiftRightNode extends Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Fallback
|
@Fallback
|
||||||
Object doOther(EnsoBigInteger self, Object that) {
|
Object doOther(Object self, Object that) {
|
||||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this);
|
||||||
var integer = builtins.number().getInteger();
|
|
||||||
throw new PanicException(builtins.error().makeTypeError(integer, that, "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.Fallback;
|
||||||
import com.oracle.truffle.api.dsl.Specialization;
|
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.dsl.BuiltinMethod;
|
||||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
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;
|
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 {
|
public abstract class BitXorNode extends Node {
|
||||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||||
|
|
||||||
abstract Object execute(EnsoBigInteger self, Object that);
|
abstract Object execute(Object self, Object that);
|
||||||
|
|
||||||
static BitXorNode build() {
|
static BitXorNode build() {
|
||||||
return BitXorNodeGen.create();
|
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
|
@Specialization
|
||||||
Object doLong(EnsoBigInteger self, long that) {
|
Object doLong(EnsoBigInteger self, long that) {
|
||||||
return toEnsoNumberNode.execute(BigIntegerOps.bitXor(self.getValue(), that));
|
return toEnsoNumberNode.execute(BigIntegerOps.bitXor(self.getValue(), that));
|
||||||
@ -32,9 +39,7 @@ public abstract class BitXorNode extends Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Fallback
|
@Fallback
|
||||||
Object doOther(EnsoBigInteger self, Object that) {
|
Object doOther(Object self, Object that) {
|
||||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this);
|
||||||
var integer = builtins.number().getInteger();
|
|
||||||
throw new PanicException(builtins.error().makeTypeError(integer, that, "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.Fallback;
|
||||||
import com.oracle.truffle.api.dsl.Specialization;
|
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.BigIntegerOps;
|
||||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
||||||
import org.enso.interpreter.runtime.EnsoContext;
|
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.DataflowError;
|
||||||
import org.enso.interpreter.runtime.error.PanicException;
|
|
||||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
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 {
|
public abstract class DivNode extends Node {
|
||||||
|
|
||||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||||
|
|
||||||
abstract Object execute(EnsoBigInteger self, Object that);
|
abstract Object execute(Object self, Object that);
|
||||||
|
|
||||||
static DivNode build() {
|
static DivNode build() {
|
||||||
return DivNodeGen.create();
|
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
|
@Specialization
|
||||||
Object doLong(EnsoBigInteger self, long that) {
|
Object doLong(EnsoBigInteger self, long that) {
|
||||||
try {
|
try {
|
||||||
@ -39,9 +54,7 @@ public abstract class DivNode extends Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Fallback
|
@Fallback
|
||||||
Object doOther(EnsoBigInteger self, Object that) {
|
Object doOther(Object self, Object that) {
|
||||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this);
|
||||||
var integer = builtins.number().getInteger();
|
|
||||||
throw new PanicException(builtins.error().makeTypeError(integer, that, "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.Fallback;
|
||||||
import com.oracle.truffle.api.dsl.Specialization;
|
import com.oracle.truffle.api.dsl.Specialization;
|
||||||
import com.oracle.truffle.api.nodes.Node;
|
import com.oracle.truffle.api.nodes.Node;
|
||||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
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.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;
|
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 {
|
public abstract class DivideNode extends Node {
|
||||||
abstract double execute(EnsoBigInteger self, Object that);
|
abstract double execute(Object self, Object that);
|
||||||
|
|
||||||
static DivideNode build() {
|
static DivideNode build() {
|
||||||
return DivideNodeGen.create();
|
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
|
@Specialization
|
||||||
double doBigInteger(EnsoBigInteger self, EnsoBigInteger that) {
|
double doBigInteger(EnsoBigInteger self, EnsoBigInteger that) {
|
||||||
return BigIntegerOps.toDouble(self.getValue()) / BigIntegerOps.toDouble(that.getValue());
|
return BigIntegerOps.toDouble(self.getValue()) / BigIntegerOps.toDouble(that.getValue());
|
||||||
@ -34,9 +46,7 @@ public abstract class DivideNode extends Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Fallback
|
@Fallback
|
||||||
double doOther(EnsoBigInteger self, Object that) {
|
double doOther(Object self, Object that) {
|
||||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this);
|
||||||
var number = builtins.number().getNumber();
|
|
||||||
throw new PanicException(builtins.error().makeTypeError(number, that, "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.Fallback;
|
||||||
import com.oracle.truffle.api.dsl.Specialization;
|
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.error.DataflowError;
|
||||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
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 {
|
public abstract class GreaterNode extends Node {
|
||||||
|
|
||||||
abstract Object execute(EnsoBigInteger self, Object that);
|
abstract Object execute(Object self, Object that);
|
||||||
|
|
||||||
static GreaterNode build() {
|
static GreaterNode build() {
|
||||||
return GreaterNodeGen.create();
|
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
|
@Specialization
|
||||||
boolean doDouble(EnsoBigInteger self, double that) {
|
boolean doDouble(EnsoBigInteger self, double that) {
|
||||||
return BigIntegerOps.toDouble(self.getValue()) > that;
|
return BigIntegerOps.toDouble(self.getValue()) > that;
|
||||||
@ -34,7 +49,7 @@ public abstract class GreaterNode extends Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Fallback
|
@Fallback
|
||||||
Object doOther(EnsoBigInteger self, Object that) {
|
Object doOther(Object self, Object that) {
|
||||||
var builtins = EnsoContext.get(this).getBuiltins();
|
var builtins = EnsoContext.get(this).getBuiltins();
|
||||||
var incomparableValsErr = builtins.error().makeIncomparableValues(self, that);
|
var incomparableValsErr = builtins.error().makeIncomparableValues(self, that);
|
||||||
return DataflowError.withoutTrace(incomparableValsErr, this);
|
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.Fallback;
|
||||||
import com.oracle.truffle.api.dsl.Specialization;
|
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.error.DataflowError;
|
||||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
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 {
|
public abstract class GreaterOrEqualNode extends Node {
|
||||||
|
|
||||||
abstract Object execute(EnsoBigInteger self, Object that);
|
abstract Object execute(Object self, Object that);
|
||||||
|
|
||||||
static GreaterOrEqualNode build() {
|
static GreaterOrEqualNode build() {
|
||||||
return GreaterOrEqualNodeGen.create();
|
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
|
@Specialization
|
||||||
boolean doDouble(EnsoBigInteger self, double that) {
|
boolean doDouble(EnsoBigInteger self, double that) {
|
||||||
return BigIntegerOps.toDouble(self.getValue()) >= that;
|
return BigIntegerOps.toDouble(self.getValue()) >= that;
|
||||||
@ -34,7 +49,7 @@ public abstract class GreaterOrEqualNode extends Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Fallback
|
@Fallback
|
||||||
Object doOther(EnsoBigInteger self, Object that) {
|
Object doOther(Object self, Object that) {
|
||||||
var builtins = EnsoContext.get(this).getBuiltins();
|
var builtins = EnsoContext.get(this).getBuiltins();
|
||||||
var incomparableValsErr = builtins.error().makeIncomparableValues(self, that);
|
var incomparableValsErr = builtins.error().makeIncomparableValues(self, that);
|
||||||
return DataflowError.withoutTrace(incomparableValsErr, this);
|
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.Fallback;
|
||||||
import com.oracle.truffle.api.dsl.Specialization;
|
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.error.DataflowError;
|
||||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
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 {
|
public abstract class LessNode extends Node {
|
||||||
|
|
||||||
abstract Object execute(EnsoBigInteger self, Object that);
|
abstract Object execute(Object self, Object that);
|
||||||
|
|
||||||
static LessNode build() {
|
static LessNode build() {
|
||||||
return LessNodeGen.create();
|
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
|
@Specialization
|
||||||
boolean doDouble(EnsoBigInteger self, double that) {
|
boolean doDouble(EnsoBigInteger self, double that) {
|
||||||
return BigIntegerOps.toDouble(self.getValue()) < that;
|
return BigIntegerOps.toDouble(self.getValue()) < that;
|
||||||
@ -34,7 +49,7 @@ public abstract class LessNode extends Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Fallback
|
@Fallback
|
||||||
Object doOther(EnsoBigInteger self, Object that) {
|
Object doOther(Object self, Object that) {
|
||||||
var builtins = EnsoContext.get(this).getBuiltins();
|
var builtins = EnsoContext.get(this).getBuiltins();
|
||||||
var incomparableValsErr = builtins.error().makeIncomparableValues(self, that);
|
var incomparableValsErr = builtins.error().makeIncomparableValues(self, that);
|
||||||
return DataflowError.withoutTrace(incomparableValsErr, this);
|
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.Fallback;
|
||||||
import com.oracle.truffle.api.dsl.Specialization;
|
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.error.DataflowError;
|
||||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
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 {
|
public abstract class LessOrEqualNode extends Node {
|
||||||
|
|
||||||
abstract Object execute(EnsoBigInteger self, Object that);
|
abstract Object execute(Object self, Object that);
|
||||||
|
|
||||||
static LessOrEqualNode build() {
|
static LessOrEqualNode build() {
|
||||||
return LessOrEqualNodeGen.create();
|
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
|
@Specialization
|
||||||
boolean doDouble(EnsoBigInteger self, double that) {
|
boolean doDouble(EnsoBigInteger self, double that) {
|
||||||
return BigIntegerOps.toDouble(self.getValue()) <= that;
|
return BigIntegerOps.toDouble(self.getValue()) <= that;
|
||||||
@ -34,7 +49,7 @@ public abstract class LessOrEqualNode extends Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Fallback
|
@Fallback
|
||||||
Object doOther(EnsoBigInteger self, Object that) {
|
Object doOther(Object self, Object that) {
|
||||||
var builtins = EnsoContext.get(this).getBuiltins();
|
var builtins = EnsoContext.get(this).getBuiltins();
|
||||||
var incomparableValsErr = builtins.error().makeIncomparableValues(self, that);
|
var incomparableValsErr = builtins.error().makeIncomparableValues(self, that);
|
||||||
return DataflowError.withoutTrace(incomparableValsErr, this);
|
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.Fallback;
|
||||||
import com.oracle.truffle.api.dsl.Specialization;
|
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.dsl.BuiltinMethod;
|
||||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
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;
|
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 {
|
public abstract class MultiplyNode extends Node {
|
||||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||||
|
|
||||||
abstract Object execute(long self, Object that);
|
abstract Object execute(Object self, Object that);
|
||||||
|
|
||||||
static MultiplyNode build() {
|
static MultiplyNode build() {
|
||||||
return MultiplyNodeGen.create();
|
return MultiplyNodeGen.create();
|
||||||
@ -41,10 +38,23 @@ public abstract class MultiplyNode extends Node {
|
|||||||
return toEnsoNumberNode.execute(BigIntegerOps.multiply(that.getValue(), self));
|
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
|
@Fallback
|
||||||
Object doOther(long self, Object that) {
|
Object doOther(Object self, Object that) {
|
||||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this);
|
||||||
var number = builtins.number().getNumber();
|
|
||||||
throw new PanicException(builtins.error().makeTypeError(number, that, "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.dsl.Specialization;
|
||||||
import com.oracle.truffle.api.nodes.Node;
|
import com.oracle.truffle.api.nodes.Node;
|
||||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
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.BigIntegerOps;
|
||||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
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 {
|
public abstract class NegateNode extends Node {
|
||||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||||
|
|
||||||
@ -14,15 +16,25 @@ public abstract class NegateNode extends Node {
|
|||||||
return NegateNodeGen.create();
|
return NegateNodeGen.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract Object execute(long self);
|
abstract Object execute(Object self);
|
||||||
|
|
||||||
@Specialization(rewriteOn = ArithmeticException.class)
|
@Specialization(rewriteOn = ArithmeticException.class)
|
||||||
long doNormal(long self) {
|
long doNormal(long self) {
|
||||||
return Math.negateExact(self);
|
return Math.negateExact(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
Object doBigInt(EnsoBigInteger self) {
|
||||||
|
return toEnsoNumberNode.execute(BigIntegerOps.negate(self.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
@Specialization
|
@Specialization
|
||||||
Object doOverflow(long self) {
|
Object doOverflow(long self) {
|
||||||
return toEnsoNumberNode.execute(BigIntegerOps.negate(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.Fallback;
|
||||||
import com.oracle.truffle.api.dsl.Specialization;
|
import com.oracle.truffle.api.dsl.Specialization;
|
||||||
import com.oracle.truffle.api.nodes.Node;
|
import com.oracle.truffle.api.nodes.Node;
|
||||||
|
import java.math.BigInteger;
|
||||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
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.BigIntegerOps;
|
||||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
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;
|
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 {
|
public abstract class PowNode extends Node {
|
||||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
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();
|
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
|
@Specialization
|
||||||
Object doLong(EnsoBigInteger self, long that) {
|
Object doLong(EnsoBigInteger self, long that) {
|
||||||
if (that == 0) {
|
if (that == 0) {
|
||||||
@ -49,10 +81,13 @@ public abstract class PowNode extends Node {
|
|||||||
return Math.pow(BigIntegerOps.toDouble(self.getValue()), that);
|
return Math.pow(BigIntegerOps.toDouble(self.getValue()), that);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@CompilerDirectives.TruffleBoundary
|
||||||
|
private static EnsoBigInteger toBigInteger(long self) {
|
||||||
|
return new EnsoBigInteger(BigInteger.valueOf(self));
|
||||||
|
}
|
||||||
|
|
||||||
@Fallback
|
@Fallback
|
||||||
Object doOther(EnsoBigInteger self, Object that) {
|
Object doOther(Object self, Object that) {
|
||||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this);
|
||||||
var number = builtins.number().getNumber();
|
|
||||||
throw new PanicException(builtins.error().makeTypeError(number, that, "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.nodes.Node;
|
||||||
import com.oracle.truffle.api.profiles.BranchProfile;
|
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.Fallback;
|
||||||
import com.oracle.truffle.api.dsl.Specialization;
|
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.dsl.BuiltinMethod;
|
||||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
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;
|
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 {
|
public abstract class SubtractNode extends Node {
|
||||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
|
||||||
|
|
||||||
abstract Object execute(long self, Object that);
|
abstract Object execute(Object self, Object that);
|
||||||
|
|
||||||
static SubtractNode build() {
|
static SubtractNode build() {
|
||||||
return SubtractNodeGen.create();
|
return SubtractNodeGen.create();
|
||||||
@ -41,10 +38,23 @@ public abstract class SubtractNode extends Node {
|
|||||||
return toEnsoNumberNode.execute(BigIntegerOps.subtract(self, that.getValue()));
|
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
|
@Fallback
|
||||||
Object doOther(long self, Object that) {
|
Object doOther(Object self, Object that) {
|
||||||
Builtins builtins = EnsoContext.get(this).getBuiltins();
|
throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this);
|
||||||
var number = builtins.number().getNumber();
|
|
||||||
throw new PanicException(builtins.error().makeTypeError(number, that, "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;
|
package org.enso.interpreter.runtime.builtin;
|
||||||
|
|
||||||
import org.enso.interpreter.node.expression.builtin.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.Decimal;
|
||||||
import org.enso.interpreter.node.expression.builtin.number.Integer;
|
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;
|
import org.enso.interpreter.runtime.data.Type;
|
||||||
|
|
||||||
/** A container for all number-related builtins. */
|
/** A container for all number-related builtins. */
|
||||||
public class Number {
|
public class Number {
|
||||||
private final Builtin smallInteger;
|
|
||||||
private final Builtin bigInteger;
|
|
||||||
private final Builtin integer;
|
private final Builtin integer;
|
||||||
private final Builtin number;
|
private final Builtin number;
|
||||||
private final Builtin decimal;
|
private final Builtin decimal;
|
||||||
|
|
||||||
/** Creates builders for number Atom Constructors. */
|
/** Creates builders for number Atom Constructors. */
|
||||||
public Number(Builtins builtins) {
|
public Number(Builtins builtins) {
|
||||||
smallInteger = builtins.getBuiltinType(SmallInteger.class);
|
|
||||||
bigInteger = builtins.getBuiltinType(BigInteger.class);
|
|
||||||
integer = builtins.getBuiltinType(Integer.class);
|
integer = builtins.getBuiltinType(Integer.class);
|
||||||
number =
|
number =
|
||||||
builtins.getBuiltinType(org.enso.interpreter.node.expression.builtin.number.Number.class);
|
builtins.getBuiltinType(org.enso.interpreter.node.expression.builtin.number.Number.class);
|
||||||
decimal = builtins.getBuiltinType(Decimal.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 */
|
/** @return the Integer atom constructor */
|
||||||
public Type getInteger() {
|
public Type getInteger() {
|
||||||
return integer.getType();
|
return integer.getType();
|
||||||
|
@ -17,6 +17,6 @@ public class DefaultLongExports {
|
|||||||
@ExportMessage
|
@ExportMessage
|
||||||
static Type getType(
|
static Type getType(
|
||||||
Long receiver, @CachedLibrary("receiver") TypesLibrary thisLib, @Cached("1") int ignore) {
|
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
|
@ExportMessage
|
||||||
Type getMetaObject(@CachedLibrary("this") InteropLibrary thisLib) {
|
Type getMetaObject(@CachedLibrary("this") InteropLibrary thisLib) {
|
||||||
return EnsoContext.get(thisLib).getBuiltins().number().getBigInteger();
|
return EnsoContext.get(thisLib).getBuiltins().number().getInteger();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExportMessage
|
@ExportMessage
|
||||||
@ -146,7 +146,7 @@ public final class EnsoBigInteger implements EnsoObject {
|
|||||||
|
|
||||||
@ExportMessage
|
@ExportMessage
|
||||||
Type getType(@CachedLibrary("this") TypesLibrary thisLib, @Cached("1") int ignore) {
|
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
|
@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 :(.",
|
"Compile error: error :(.",
|
||||||
"Inexhaustive pattern match: no branch matches 32.",
|
"Inexhaustive pattern match: no branch matches 32.",
|
||||||
"Arithmetic error: cannot frobnicate quaternions.",
|
"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.",
|
"Type error: expected a function, but got 7.",
|
||||||
"Wrong number of arguments. Expected 10, but got 20."
|
"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 "-101021010" 2 . should_fail_with Number_Parse_Error
|
||||||
Integer.parse "123" 128 . 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.group "Decimals" <|
|
||||||
|
|
||||||
Test.specify "should exist and expose basic arithmetic operations" <|
|
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
|
||||||
-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" <|
|
Test.specify "should support less than operator" <|
|
||||||
(1 < 2).should_be_true
|
(1 < 2).should_be_true
|
||||||
(1 < 1).should_be_false
|
(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']
|
methods.sort . should_equal ['Value', 'create', 'factory', 'first_method', 'my_method', 'other_method', 'second_method']
|
||||||
|
|
||||||
Test.specify "methods of Integer" <|
|
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" <|
|
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" <|
|
Test.specify "methods of Any" <|
|
||||||
Meta.meta Any . methods . should_contain "to_text"
|
Meta.meta Any . methods . should_contain "to_text"
|
||||||
|
Loading…
Reference in New Issue
Block a user