From e0ee8fdda7adba28edfc24764918b723e3fba568 Mon Sep 17 00:00:00 2001 From: Pavel Marek Date: Fri, 8 Sep 2023 16:04:39 +0200 Subject: [PATCH] Merge Small_Integer and Big_Integer types (#7636) Merge Small_Integer and Big_Integer types into a single Integer type --- CHANGELOG.md | 2 + .../test/instrument/RuntimeServerTest.scala | 2 +- .../RuntimeVisualizationsTest.scala | 48 ++++++++++- .../builtin/meta/IsValueOfTypeNode.java | 4 +- .../expression/builtin/number/BigInteger.java | 12 --- .../builtin/number/SmallInteger.java | 12 --- .../builtin/number/bigInteger/AbsNode.java | 16 ---- .../builtin/number/bigInteger/AddNode.java | 45 ---------- .../builtin/number/bigInteger/BitNotNode.java | 33 ------- .../number/bigInteger/BitShiftNode.java | 80 ----------------- .../builtin/number/bigInteger/CeilNode.java | 12 --- .../builtin/number/bigInteger/FloorNode.java | 12 --- .../builtin/number/bigInteger/ModNode.java | 54 ------------ .../number/bigInteger/MultiplyNode.java | 45 ---------- .../builtin/number/bigInteger/NegateNode.java | 16 ---- .../number/bigInteger/SubtractNode.java | 45 ---------- .../number/bigInteger/ToDecimalNode.java | 16 ---- .../{smallInteger => integer}/AbsNode.java | 26 ++++-- .../builtin/number/integer/AddNode.java | 62 ++++++++++++++ .../{bigInteger => integer}/BitAndNode.java | 29 ++++--- .../builtin/number/integer/BitNotNode.java | 33 +++++++ .../{bigInteger => integer}/BitOrNode.java | 21 +++-- .../BitShiftNode.java | 61 +++++++++++-- .../BitShiftRightNode.java | 29 ++++--- .../{bigInteger => integer}/BitXorNode.java | 25 +++--- .../builtin/number/integer/CeilNode.java | 31 +++++++ .../{bigInteger => integer}/DivNode.java | 31 +++++-- .../{bigInteger => integer}/DivideNode.java | 30 ++++--- .../builtin/number/integer/FloorNode.java | 32 +++++++ .../{bigInteger => integer}/GreaterNode.java | 23 ++++- .../GreaterOrEqualNode.java | 23 ++++- .../builtin/number/integer/IntegerUtils.java | 30 +++++++ .../{bigInteger => integer}/LessNode.java | 23 ++++- .../LessOrEqualNode.java | 23 ++++- .../builtin/number/integer/ModNode.java | 85 +++++++++++++++++++ .../MultiplyNode.java | 30 ++++--- .../{smallInteger => integer}/NegateNode.java | 18 +++- .../{bigInteger => integer}/PowNode.java | 57 ++++++++++--- .../{smallInteger => integer}/RoundNode.java | 2 +- .../SubtractNode.java | 30 ++++--- .../builtin/number/integer/ToDecimalNode.java | 35 ++++++++ .../builtin/number/smallInteger/AddNode.java | 50 ----------- .../number/smallInteger/BitAndNode.java | 40 --------- .../number/smallInteger/BitNotNode.java | 30 ------- .../number/smallInteger/BitOrNode.java | 40 --------- .../smallInteger/BitShiftRightNode.java | 43 ---------- .../number/smallInteger/BitXorNode.java | 40 --------- .../builtin/number/smallInteger/CeilNode.java | 11 --- .../builtin/number/smallInteger/DivNode.java | 43 ---------- .../number/smallInteger/DivideNode.java | 42 --------- .../number/smallInteger/FloorNode.java | 11 --- .../number/smallInteger/GreaterNode.java | 41 --------- .../smallInteger/GreaterOrEqualNode.java | 41 --------- .../builtin/number/smallInteger/LessNode.java | 41 --------- .../number/smallInteger/LessOrEqualNode.java | 41 --------- .../builtin/number/smallInteger/ModNode.java | 50 ----------- .../builtin/number/smallInteger/PowNode.java | 85 ------------------- .../number/smallInteger/ToDecimalNode.java | 14 --- .../interpreter/runtime/builtin/Number.java | 16 ---- .../library/dispatch/DefaultLongExports.java | 2 +- .../runtime/number/EnsoBigInteger.java | 4 +- .../enso/interpreter/test/IntegerTest.java | 71 ++++++++++++++++ .../interpreter/test/semantic/TextTest.scala | 2 +- test/Tests/src/Data/Numbers_Spec.enso | 11 +++ test/Tests/src/Semantic/Meta_Spec.enso | 4 +- 65 files changed, 801 insertions(+), 1215 deletions(-) delete mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/BigInteger.java delete mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/SmallInteger.java delete mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/AbsNode.java delete mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/AddNode.java delete mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/BitNotNode.java delete mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/BitShiftNode.java delete mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/CeilNode.java delete mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/FloorNode.java delete mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/ModNode.java delete mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/MultiplyNode.java delete mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/NegateNode.java delete mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/SubtractNode.java delete mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/ToDecimalNode.java rename engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/{smallInteger => integer}/AbsNode.java (51%) create mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/AddNode.java rename engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/{bigInteger => integer}/BitAndNode.java (54%) create mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitNotNode.java rename engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/{bigInteger => integer}/BitOrNode.java (67%) rename engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/{smallInteger => integer}/BitShiftNode.java (60%) rename engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/{bigInteger => integer}/BitShiftRightNode.java (57%) rename engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/{bigInteger => integer}/BitXorNode.java (59%) create mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/CeilNode.java rename engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/{bigInteger => integer}/DivNode.java (63%) rename engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/{bigInteger => integer}/DivideNode.java (57%) create mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/FloorNode.java rename engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/{bigInteger => integer}/GreaterNode.java (67%) rename engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/{bigInteger => integer}/GreaterOrEqualNode.java (68%) create mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/IntegerUtils.java rename engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/{bigInteger => integer}/LessNode.java (67%) rename engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/{bigInteger => integer}/LessOrEqualNode.java (68%) create mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/ModNode.java rename engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/{smallInteger => integer}/MultiplyNode.java (59%) rename engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/{smallInteger => integer}/NegateNode.java (57%) rename engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/{bigInteger => integer}/PowNode.java (50%) rename engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/{smallInteger => integer}/RoundNode.java (96%) rename engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/{smallInteger => integer}/SubtractNode.java (59%) create mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/ToDecimalNode.java delete mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/AddNode.java delete mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/BitAndNode.java delete mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/BitNotNode.java delete mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/BitOrNode.java delete mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/BitShiftRightNode.java delete mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/BitXorNode.java delete mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/CeilNode.java delete mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/DivNode.java delete mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/DivideNode.java delete mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/FloorNode.java delete mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/GreaterNode.java delete mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/GreaterOrEqualNode.java delete mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/LessNode.java delete mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/LessOrEqualNode.java delete mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/ModNode.java delete mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/PowNode.java delete mode 100644 engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/ToDecimalNode.java create mode 100644 engine/runtime/src/test/java/org/enso/interpreter/test/IntegerTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 3893208c9f..3544fcd6d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -945,6 +945,7 @@ - [Use `numpy` & co. from Enso!][7678] - [Changed layout of local libraries directory, making it easier to reference projects next to each other][7634] +- [Merge `Small_Integer` and `Big_Integer` types][7636] [3227]: https://github.com/enso-org/enso/pull/3227 [3248]: https://github.com/enso-org/enso/pull/3248 @@ -1082,6 +1083,7 @@ [7613]: https://github.com/enso-org/enso/pull/7613 [7678]: https://github.com/enso-org/enso/pull/7678 [7634]: https://github.com/enso-org/enso/pull/7634 +[7636]: https://github.com/enso-org/enso/pull/7636 # Enso 2.0.0-alpha.18 (2021-10-12) diff --git a/engine/runtime-with-instruments/src/test/scala/org/enso/interpreter/test/instrument/RuntimeServerTest.scala b/engine/runtime-with-instruments/src/test/scala/org/enso/interpreter/test/instrument/RuntimeServerTest.scala index 344dca947d..a264dba531 100644 --- a/engine/runtime-with-instruments/src/test/scala/org/enso/interpreter/test/instrument/RuntimeServerTest.scala +++ b/engine/runtime-with-instruments/src/test/scala/org/enso/interpreter/test/instrument/RuntimeServerTest.scala @@ -5092,7 +5092,7 @@ class RuntimeServerTest Api.ExecutionFailed( contextId, Api.ExecutionResult.Diagnostic.error( - "Type error: expected `that` to be Number, but got Function.", + "Type error: expected `that` to be Integer, but got Function.", Some(mainFile), Some(model.Range(model.Position(11, 8), model.Position(11, 17))), None, diff --git a/engine/runtime-with-polyglot/src/test/scala/org/enso/interpreter/test/instrument/RuntimeVisualizationsTest.scala b/engine/runtime-with-polyglot/src/test/scala/org/enso/interpreter/test/instrument/RuntimeVisualizationsTest.scala index b5ad2fa9a2..5d9bb9b115 100644 --- a/engine/runtime-with-polyglot/src/test/scala/org/enso/interpreter/test/instrument/RuntimeVisualizationsTest.scala +++ b/engine/runtime-with-polyglot/src/test/scala/org/enso/interpreter/test/instrument/RuntimeVisualizationsTest.scala @@ -187,7 +187,15 @@ class RuntimeVisualizationsTest Api.ExpressionUpdate( Main.idMainZ, Some(ConstantsGen.INTEGER), - None, + Some( + Api.MethodCall( + Api.MethodPointer( + "Standard.Base.Data.Numbers", + "Standard.Base.Data.Numbers.Integer", + "+" + ) + ) + ), Vector(Api.ProfilingInfo.ExecutionTime(0)), fromCache, typeChanged, @@ -209,7 +217,15 @@ class RuntimeVisualizationsTest Api.ExpressionUpdate( Main.idFooY, Some(ConstantsGen.INTEGER), - None, + Some( + Api.MethodCall( + Api.MethodPointer( + "Standard.Base.Data.Numbers", + "Standard.Base.Data.Numbers.Integer", + "+" + ) + ) + ), Vector(Api.ProfilingInfo.ExecutionTime(0)), fromCache, typeChanged, @@ -231,7 +247,15 @@ class RuntimeVisualizationsTest Api.ExpressionUpdate( Main.idFooZ, Some(ConstantsGen.INTEGER), - None, + Some( + Api.MethodCall( + Api.MethodPointer( + "Standard.Base.Data.Numbers", + "Standard.Base.Data.Numbers.Integer", + "*" + ) + ) + ), Vector(Api.ProfilingInfo.ExecutionTime(0)), fromCache, typeChanged, @@ -973,12 +997,30 @@ class RuntimeVisualizationsTest contextId, context.Main.idFooY, ConstantsGen.INTEGER, + methodCall = Some( + Api.MethodCall( + Api.MethodPointer( + "Standard.Base.Data.Numbers", + "Standard.Base.Data.Numbers.Integer", + "+" + ) + ) + ), typeChanged = false ), TestMessages.update( contextId, context.Main.idFooZ, ConstantsGen.INTEGER, + methodCall = Some( + Api.MethodCall( + Api.MethodPointer( + "Standard.Base.Data.Numbers", + "Standard.Base.Data.Numbers.Integer", + "*" + ) + ) + ), typeChanged = false ), context.executionComplete(contextId) diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/meta/IsValueOfTypeNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/meta/IsValueOfTypeNode.java index 197c2e58a8..49b2284175 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/meta/IsValueOfTypeNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/meta/IsValueOfTypeNode.java @@ -85,7 +85,7 @@ public abstract class IsValueOfTypeNode extends Node { @Specialization boolean doLongCheck(Type expectedType, long payload) { var numbers = EnsoContext.get(this).getBuiltins().number(); - return checkParentTypes(numbers.getSmallInteger(), expectedType); + return checkParentTypes(numbers.getInteger(), expectedType); } @Specialization @@ -97,7 +97,7 @@ public abstract class IsValueOfTypeNode extends Node { @Specialization boolean doBigIntegerCheck(Type expectedType, EnsoBigInteger value) { var numbers = EnsoContext.get(this).getBuiltins().number(); - return checkParentTypes(numbers.getBigInteger(), expectedType); + return checkParentTypes(numbers.getInteger(), expectedType); } @Specialization diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/BigInteger.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/BigInteger.java deleted file mode 100644 index ef68428998..0000000000 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/BigInteger.java +++ /dev/null @@ -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 getSuperType() { - return Integer.class; - } -} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/SmallInteger.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/SmallInteger.java deleted file mode 100644 index 78b7201aa8..0000000000 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/SmallInteger.java +++ /dev/null @@ -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 getSuperType() { - return Integer.class; - } -} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/AbsNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/AbsNode.java deleted file mode 100644 index addd4af00c..0000000000 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/AbsNode.java +++ /dev/null @@ -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())); - } -} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/AddNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/AddNode.java deleted file mode 100644 index c521090de7..0000000000 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/AddNode.java +++ /dev/null @@ -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); - } -} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/BitNotNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/BitNotNode.java deleted file mode 100644 index a8fd83c8bb..0000000000 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/BitNotNode.java +++ /dev/null @@ -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); - } -} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/BitShiftNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/BitShiftNode.java deleted file mode 100644 index 0610fb7690..0000000000 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/BitShiftNode.java +++ /dev/null @@ -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); - } -} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/CeilNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/CeilNode.java deleted file mode 100644 index 23b9ebea6d..0000000000 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/CeilNode.java +++ /dev/null @@ -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; - } -} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/FloorNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/FloorNode.java deleted file mode 100644 index 7bca13f03b..0000000000 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/FloorNode.java +++ /dev/null @@ -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; - } -} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/ModNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/ModNode.java deleted file mode 100644 index 6248e00c14..0000000000 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/ModNode.java +++ /dev/null @@ -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); - } -} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/MultiplyNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/MultiplyNode.java deleted file mode 100644 index 46df97d1ca..0000000000 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/MultiplyNode.java +++ /dev/null @@ -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); - } -} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/NegateNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/NegateNode.java deleted file mode 100644 index 5764150916..0000000000 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/NegateNode.java +++ /dev/null @@ -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())); - } -} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/SubtractNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/SubtractNode.java deleted file mode 100644 index 96e04475df..0000000000 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/SubtractNode.java +++ /dev/null @@ -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); - } -} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/ToDecimalNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/ToDecimalNode.java deleted file mode 100644 index cb52779f47..0000000000 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/ToDecimalNode.java +++ /dev/null @@ -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()); - } -} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/AbsNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/AbsNode.java similarity index 51% rename from engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/AbsNode.java rename to engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/AbsNode.java index 44dc13fbe7..ec401fe535 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/AbsNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/AbsNode.java @@ -1,23 +1,25 @@ -package org.enso.interpreter.node.expression.builtin.number.smallInteger; +package org.enso.interpreter.node.expression.builtin.number.integer; +import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.nodes.Node; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode; +import org.enso.interpreter.runtime.number.EnsoBigInteger; -@BuiltinMethod(type = "Small_Integer", name = "abs", description = "Absolute value of a number") +@BuiltinMethod(type = "Integer", name = "abs", description = "Absolute value of a number") public abstract class AbsNode extends Node { private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create(); - static AbsNode build() { + public static AbsNode build() { return AbsNodeGen.create(); } - abstract Object execute(long self); + public abstract Object execute(Object self); @Specialization(rewriteOn = ArithmeticException.class) - long doNormal(long self) { + long doLong(long self) { if (self < 0) { return Math.negateExact(self); } else { @@ -25,8 +27,18 @@ public abstract class AbsNode extends Node { } } - @Specialization - Object doOverflow(long self) { + @Specialization(replaces = "doLong") + Object doLongOverflow(long self) { return toEnsoNumberNode.execute(BigIntegerOps.abs(self)); } + + @Specialization + Object doBigInt(EnsoBigInteger self) { + return toEnsoNumberNode.execute(BigIntegerOps.abs(self.getValue())); + } + + @Fallback + Object doOther(Object self) { + throw IntegerUtils.throwTypeErrorIfNotInt(self, this); + } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/AddNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/AddNode.java new file mode 100644 index 0000000000..cfc2216e48 --- /dev/null +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/AddNode.java @@ -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); + } +} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/BitAndNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitAndNode.java similarity index 54% rename from engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/BitAndNode.java rename to engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitAndNode.java index 46e96df183..37ac2f3d3b 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/BitAndNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitAndNode.java @@ -1,4 +1,4 @@ -package org.enso.interpreter.node.expression.builtin.number.bigInteger; +package org.enso.interpreter.node.expression.builtin.number.integer; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; @@ -6,35 +6,40 @@ import com.oracle.truffle.api.nodes.Node; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode; -import org.enso.interpreter.runtime.EnsoContext; -import org.enso.interpreter.runtime.builtin.Builtins; -import org.enso.interpreter.runtime.error.PanicException; import org.enso.interpreter.runtime.number.EnsoBigInteger; -@BuiltinMethod(type = "Big_Integer", name = "bit_and", description = "Bitwise and.") +@BuiltinMethod(type = "Integer", name = "bit_and", description = "Bitwise and.") public abstract class BitAndNode extends Node { private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create(); - abstract Object execute(Object self, Object that); + public abstract Object execute(Object self, Object that); - static BitAndNode build() { + public static BitAndNode build() { return BitAndNodeGen.create(); } @Specialization - Object doLong(EnsoBigInteger self, long that) { + long doLongLong(long self, long that) { + return self & that; + } + + @Specialization + Object doLongBigInt(long self, EnsoBigInteger that) { + return toEnsoNumberNode.execute(BigIntegerOps.bitAnd(self, that.getValue())); + } + + @Specialization + Object doBigIntLong(EnsoBigInteger self, long that) { return toEnsoNumberNode.execute(BigIntegerOps.bitAnd(self.getValue(), that)); } @Specialization - Object doBigInteger(EnsoBigInteger self, EnsoBigInteger that) { + Object doBigIntBigInt(EnsoBigInteger self, EnsoBigInteger that) { return toEnsoNumberNode.execute(BigIntegerOps.bitAnd(self.getValue(), that.getValue())); } @Fallback Object doOther(Object self, Object that) { - Builtins builtins = EnsoContext.get(this).getBuiltins(); - var integer = builtins.number().getInteger(); - throw new PanicException(builtins.error().makeTypeError(integer, that, "that"), this); + throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitNotNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitNotNode.java new file mode 100644 index 0000000000..258dc36bb2 --- /dev/null +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitNotNode.java @@ -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); + } +} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/BitOrNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitOrNode.java similarity index 67% rename from engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/BitOrNode.java rename to engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitOrNode.java index f06e018db3..7c999b7599 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/BitOrNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitOrNode.java @@ -1,4 +1,4 @@ -package org.enso.interpreter.node.expression.builtin.number.bigInteger; +package org.enso.interpreter.node.expression.builtin.number.integer; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; @@ -6,12 +6,9 @@ import com.oracle.truffle.api.nodes.Node; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode; -import org.enso.interpreter.runtime.EnsoContext; -import org.enso.interpreter.runtime.builtin.Builtins; -import org.enso.interpreter.runtime.error.PanicException; import org.enso.interpreter.runtime.number.EnsoBigInteger; -@BuiltinMethod(type = "Big_Integer", name = "bit_or", description = "Bitwise or.") +@BuiltinMethod(type = "Integer", name = "bit_or", description = "Bitwise or.") public abstract class BitOrNode extends Node { private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create(); @@ -21,6 +18,16 @@ public abstract class BitOrNode extends Node { return BitOrNodeGen.create(); } + @Specialization + long doLong(long self, long that) { + return self | that; + } + + @Specialization + Object doBigInteger(long self, EnsoBigInteger that) { + return toEnsoNumberNode.execute(BigIntegerOps.bitOr(self, that.getValue())); + } + @Specialization Object doLong(EnsoBigInteger self, long that) { return toEnsoNumberNode.execute(BigIntegerOps.bitOr(self.getValue(), that)); @@ -33,8 +40,6 @@ public abstract class BitOrNode extends Node { @Fallback Object doOther(Object self, Object that) { - Builtins builtins = EnsoContext.get(this).getBuiltins(); - var integer = builtins.number().getInteger(); - throw new PanicException(builtins.error().makeTypeError(integer, that, "that"), this); + throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/BitShiftNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitShiftNode.java similarity index 60% rename from engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/BitShiftNode.java rename to engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitShiftNode.java index 49ec251c44..73cc0ef31b 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/BitShiftNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitShiftNode.java @@ -1,5 +1,7 @@ -package org.enso.interpreter.node.expression.builtin.number.smallInteger; +package org.enso.interpreter.node.expression.builtin.number.integer; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Cached.Exclusive; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.NeverDefault; @@ -10,13 +12,11 @@ import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode; import org.enso.interpreter.runtime.EnsoContext; -import org.enso.interpreter.runtime.builtin.Builtins; import org.enso.interpreter.runtime.error.DataflowError; -import org.enso.interpreter.runtime.error.PanicException; import org.enso.interpreter.runtime.number.EnsoBigInteger; @ImportStatic(BigIntegerOps.class) -@BuiltinMethod(type = "Small_Integer", name = "bit_shift", description = "Bitwise shift.") +@BuiltinMethod(type = "Integer", name = "bit_shift", description = "Bitwise shift.") public abstract class BitShiftNode extends Node { private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create(); private final CountingConditionProfile canShiftLeftInLongProfile = @@ -26,7 +26,7 @@ public abstract class BitShiftNode extends Node { private final CountingConditionProfile rightShiftExceedsLongWidth = CountingConditionProfile.create(); - abstract Object execute(long self, Object that); + abstract Object execute(Object self, Object that); @NeverDefault static BitShiftNode build() { @@ -79,11 +79,54 @@ public abstract class BitShiftNode extends Node { } } + @Specialization(guards = {"that >= 0", "fitsInInt(that)"}) + EnsoBigInteger doBigIntShiftLeft(EnsoBigInteger self, long that) { + return new EnsoBigInteger(BigIntegerOps.bitShiftLeft(self.getValue(), (int) that)); + } + + @Specialization(guards = "that >= 0", replaces = "doBigIntShiftLeft") + Object doBigIntShiftLeftExplicit( + EnsoBigInteger self, + long that, + @Exclusive @Cached CountingConditionProfile fitsInIntProfileLeftShift) { + if (fitsInIntProfileLeftShift.profile(BigIntegerOps.fitsInInt(that))) { + return doBigIntShiftLeft(self, that); + } else { + return DataflowError.withoutTrace( + EnsoContext.get(this).getBuiltins().error().getShiftAmountTooLargeError(), this); + } + } + + @Specialization(guards = {"that < 0", "fitsInInt(that)"}) + Object doBigIntShiftRight(EnsoBigInteger self, long that) { + return toEnsoNumberNode.execute(BigIntegerOps.bitShiftRight(self.getValue(), (int) -that)); + } + + @Specialization(guards = "that < 0", replaces = "doBigIntShiftRight") + Object doBigIntShiftRightExplicit( + EnsoBigInteger self, + long that, + @Exclusive @Cached CountingConditionProfile fitsInIntProfileRightShift) { + if (fitsInIntProfileRightShift.profile(BigIntegerOps.fitsInInt(that))) { + return doBigIntShiftRight(self, -that); + } else { + return BigIntegerOps.nonNegative(self.getValue()) ? 0L : -1L; + } + } + + @Specialization + Object doBigIntThat(EnsoBigInteger self, EnsoBigInteger that) { + if (!BigIntegerOps.nonNegative(that.getValue())) { + return BigIntegerOps.nonNegative(self.getValue()) ? 0L : -1L; + } else { + return DataflowError.withoutTrace( + EnsoContext.get(this).getBuiltins().error().getShiftAmountTooLargeError(), this); + } + } + @Fallback - Object doOther(long self, Object that) { - Builtins builtins = EnsoContext.get(this).getBuiltins(); - var integer = builtins.number().getInteger(); - throw new PanicException(builtins.error().makeTypeError(integer, that, "that"), this); + Object doOther(Object self, Object that) { + throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this); } boolean hasFreeBitsLeftShift(long number, long shift) { diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/BitShiftRightNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitShiftRightNode.java similarity index 57% rename from engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/BitShiftRightNode.java rename to engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitShiftRightNode.java index 638a7ae1d6..45f0af05ba 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/BitShiftRightNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitShiftRightNode.java @@ -1,4 +1,4 @@ -package org.enso.interpreter.node.expression.builtin.number.bigInteger; +package org.enso.interpreter.node.expression.builtin.number.integer; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Shared; @@ -7,19 +7,30 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.nodes.Node; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; -import org.enso.interpreter.runtime.EnsoContext; -import org.enso.interpreter.runtime.builtin.Builtins; -import org.enso.interpreter.runtime.error.PanicException; import org.enso.interpreter.runtime.number.EnsoBigInteger; -@BuiltinMethod(type = "Big_Integer", name = "bit_shift_r", description = "Bitwise right-shift.") +@BuiltinMethod(type = "Integer", name = "bit_shift_r", description = "Bitwise right-shift.") public abstract class BitShiftRightNode extends Node { - abstract Object execute(EnsoBigInteger self, Object that); + abstract Object execute(Object self, Object that); static BitShiftRightNode build() { return BitShiftRightNodeGen.create(); } + @Specialization + Object doBigInteger( + long self, long that, @Shared("bitShiftNode") @Cached("build()") BitShiftNode bitShiftNode) { + return bitShiftNode.execute(self, -1L * that); + } + + @Specialization + Object doBigInteger( + long self, + EnsoBigInteger that, + @Shared("bitShiftNode") @Cached("build()") BitShiftNode bitShiftNode) { + return bitShiftNode.execute(self, new EnsoBigInteger(BigIntegerOps.negate(that.getValue()))); + } + @Specialization Object doBigInteger( EnsoBigInteger self, @@ -37,9 +48,7 @@ public abstract class BitShiftRightNode extends Node { } @Fallback - Object doOther(EnsoBigInteger self, Object that) { - Builtins builtins = EnsoContext.get(this).getBuiltins(); - var integer = builtins.number().getInteger(); - throw new PanicException(builtins.error().makeTypeError(integer, that, "that"), this); + Object doOther(Object self, Object that) { + throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/BitXorNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitXorNode.java similarity index 59% rename from engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/BitXorNode.java rename to engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitXorNode.java index 2467ece867..ac250da2a7 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/BitXorNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitXorNode.java @@ -1,4 +1,4 @@ -package org.enso.interpreter.node.expression.builtin.number.bigInteger; +package org.enso.interpreter.node.expression.builtin.number.integer; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; @@ -6,21 +6,28 @@ import com.oracle.truffle.api.nodes.Node; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode; -import org.enso.interpreter.runtime.EnsoContext; -import org.enso.interpreter.runtime.builtin.Builtins; -import org.enso.interpreter.runtime.error.PanicException; import org.enso.interpreter.runtime.number.EnsoBigInteger; -@BuiltinMethod(type = "Big_Integer", name = "bit_xor", description = "Bitwise exclusive or.") +@BuiltinMethod(type = "Integer", name = "bit_xor", description = "Bitwise exclusive or.") public abstract class BitXorNode extends Node { private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create(); - abstract Object execute(EnsoBigInteger self, Object that); + abstract Object execute(Object self, Object that); static BitXorNode build() { return BitXorNodeGen.create(); } + @Specialization + long doLong(long self, long that) { + return self ^ that; + } + + @Specialization + Object doBigInteger(long self, EnsoBigInteger that) { + return toEnsoNumberNode.execute(BigIntegerOps.bitXor(self, that.getValue())); + } + @Specialization Object doLong(EnsoBigInteger self, long that) { return toEnsoNumberNode.execute(BigIntegerOps.bitXor(self.getValue(), that)); @@ -32,9 +39,7 @@ public abstract class BitXorNode extends Node { } @Fallback - Object doOther(EnsoBigInteger self, Object that) { - Builtins builtins = EnsoContext.get(this).getBuiltins(); - var integer = builtins.number().getInteger(); - throw new PanicException(builtins.error().makeTypeError(integer, that, "that"), this); + Object doOther(Object self, Object that) { + throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/CeilNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/CeilNode.java new file mode 100644 index 0000000000..9c08abf178 --- /dev/null +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/CeilNode.java @@ -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); + } +} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/DivNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/DivNode.java similarity index 63% rename from engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/DivNode.java rename to engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/DivNode.java index 24ea9d5472..4bc02366fe 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/DivNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/DivNode.java @@ -1,4 +1,4 @@ -package org.enso.interpreter.node.expression.builtin.number.bigInteger; +package org.enso.interpreter.node.expression.builtin.number.integer; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; @@ -7,21 +7,36 @@ import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode; import org.enso.interpreter.runtime.EnsoContext; -import org.enso.interpreter.runtime.builtin.Builtins; import org.enso.interpreter.runtime.error.DataflowError; -import org.enso.interpreter.runtime.error.PanicException; import org.enso.interpreter.runtime.number.EnsoBigInteger; -@BuiltinMethod(type = "Big_Integer", name = "div", description = "Big integer integral division.") +@BuiltinMethod(type = "Integer", name = "div", description = "Division of numbers.") public abstract class DivNode extends Node { + private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create(); - abstract Object execute(EnsoBigInteger self, Object that); + abstract Object execute(Object self, Object that); static DivNode build() { return DivNodeGen.create(); } + @Specialization + Object doLong(long self, long that) { + try { + return self / that; + } catch (ArithmeticException e) { + return DataflowError.withoutTrace( + EnsoContext.get(this).getBuiltins().error().getDivideByZeroError(), this); + } + } + + @Specialization + Object doBigInteger(long self, EnsoBigInteger that) { + // No need to trap, as 0 is never represented as an EnsoBigInteger. + return 0L; + } + @Specialization Object doLong(EnsoBigInteger self, long that) { try { @@ -39,9 +54,7 @@ public abstract class DivNode extends Node { } @Fallback - Object doOther(EnsoBigInteger self, Object that) { - Builtins builtins = EnsoContext.get(this).getBuiltins(); - var integer = builtins.number().getInteger(); - throw new PanicException(builtins.error().makeTypeError(integer, that, "that"), this); + Object doOther(Object self, Object that) { + throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/DivideNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/DivideNode.java similarity index 57% rename from engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/DivideNode.java rename to engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/DivideNode.java index 730ceea762..7642754775 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/DivideNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/DivideNode.java @@ -1,23 +1,35 @@ -package org.enso.interpreter.node.expression.builtin.number.bigInteger; +package org.enso.interpreter.node.expression.builtin.number.integer; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.nodes.Node; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; -import org.enso.interpreter.runtime.EnsoContext; -import org.enso.interpreter.runtime.builtin.Builtins; -import org.enso.interpreter.runtime.error.PanicException; import org.enso.interpreter.runtime.number.EnsoBigInteger; -@BuiltinMethod(type = "Big_Integer", name = "/", description = "Big integer division.") +@BuiltinMethod(type = "Integer", name = "/", description = "Division of numbers.") public abstract class DivideNode extends Node { - abstract double execute(EnsoBigInteger self, Object that); + abstract double execute(Object self, Object that); static DivideNode build() { return DivideNodeGen.create(); } + @Specialization + double doLong(long self, long that) { + return ((double) self) / ((double) that); + } + + @Specialization + double doDouble(long self, double that) { + return self / that; + } + + @Specialization + double doBigInteger(long self, EnsoBigInteger that) { + return ((double) self) / BigIntegerOps.toDouble(that.getValue()); + } + @Specialization double doBigInteger(EnsoBigInteger self, EnsoBigInteger that) { return BigIntegerOps.toDouble(self.getValue()) / BigIntegerOps.toDouble(that.getValue()); @@ -34,9 +46,7 @@ public abstract class DivideNode extends Node { } @Fallback - double doOther(EnsoBigInteger self, Object that) { - Builtins builtins = EnsoContext.get(this).getBuiltins(); - var number = builtins.number().getNumber(); - throw new PanicException(builtins.error().makeTypeError(number, that, "that"), this); + double doOther(Object self, Object that) { + throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/FloorNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/FloorNode.java new file mode 100644 index 0000000000..7e7578b826 --- /dev/null +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/FloorNode.java @@ -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); + } +} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/GreaterNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/GreaterNode.java similarity index 67% rename from engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/GreaterNode.java rename to engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/GreaterNode.java index ea3bb9ab40..d07eb62eb6 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/GreaterNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/GreaterNode.java @@ -1,4 +1,4 @@ -package org.enso.interpreter.node.expression.builtin.number.bigInteger; +package org.enso.interpreter.node.expression.builtin.number.integer; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; @@ -9,15 +9,30 @@ import org.enso.interpreter.runtime.EnsoContext; import org.enso.interpreter.runtime.error.DataflowError; import org.enso.interpreter.runtime.number.EnsoBigInteger; -@BuiltinMethod(type = "Big_Integer", name = ">", description = "Comparison of numbers.") +@BuiltinMethod(type = "Integer", name = ">", description = "Comparison of numbers.") public abstract class GreaterNode extends Node { - abstract Object execute(EnsoBigInteger self, Object that); + abstract Object execute(Object self, Object that); static GreaterNode build() { return GreaterNodeGen.create(); } + @Specialization + boolean doLong(long self, long that) { + return self > that; + } + + @Specialization + boolean doDouble(long self, double that) { + return (double) self > that; + } + + @Specialization + boolean doBigInteger(long self, EnsoBigInteger that) { + return that.getValue().signum() < 0; + } + @Specialization boolean doDouble(EnsoBigInteger self, double that) { return BigIntegerOps.toDouble(self.getValue()) > that; @@ -34,7 +49,7 @@ public abstract class GreaterNode extends Node { } @Fallback - Object doOther(EnsoBigInteger self, Object that) { + Object doOther(Object self, Object that) { var builtins = EnsoContext.get(this).getBuiltins(); var incomparableValsErr = builtins.error().makeIncomparableValues(self, that); return DataflowError.withoutTrace(incomparableValsErr, this); diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/GreaterOrEqualNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/GreaterOrEqualNode.java similarity index 68% rename from engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/GreaterOrEqualNode.java rename to engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/GreaterOrEqualNode.java index 2e7ec44d23..89f086a9d1 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/GreaterOrEqualNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/GreaterOrEqualNode.java @@ -1,4 +1,4 @@ -package org.enso.interpreter.node.expression.builtin.number.bigInteger; +package org.enso.interpreter.node.expression.builtin.number.integer; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; @@ -9,15 +9,30 @@ import org.enso.interpreter.runtime.EnsoContext; import org.enso.interpreter.runtime.error.DataflowError; import org.enso.interpreter.runtime.number.EnsoBigInteger; -@BuiltinMethod(type = "Big_Integer", name = ">=", description = "Comparison of numbers.") +@BuiltinMethod(type = "Integer", name = ">=", description = "Comparison of numbers.") public abstract class GreaterOrEqualNode extends Node { - abstract Object execute(EnsoBigInteger self, Object that); + abstract Object execute(Object self, Object that); static GreaterOrEqualNode build() { return GreaterOrEqualNodeGen.create(); } + @Specialization + boolean doLong(long self, long that) { + return self >= that; + } + + @Specialization + boolean doDouble(long self, double that) { + return (double) self >= that; + } + + @Specialization + boolean doBigInteger(long self, EnsoBigInteger that) { + return that.getValue().signum() < 0; + } + @Specialization boolean doDouble(EnsoBigInteger self, double that) { return BigIntegerOps.toDouble(self.getValue()) >= that; @@ -34,7 +49,7 @@ public abstract class GreaterOrEqualNode extends Node { } @Fallback - Object doOther(EnsoBigInteger self, Object that) { + Object doOther(Object self, Object that) { var builtins = EnsoContext.get(this).getBuiltins(); var incomparableValsErr = builtins.error().makeIncomparableValues(self, that); return DataflowError.withoutTrace(incomparableValsErr, this); diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/IntegerUtils.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/IntegerUtils.java new file mode 100644 index 0000000000..5f62263a2f --- /dev/null +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/IntegerUtils.java @@ -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); + } +} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/LessNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/LessNode.java similarity index 67% rename from engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/LessNode.java rename to engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/LessNode.java index 1e145ba5b4..9947cb931c 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/LessNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/LessNode.java @@ -1,4 +1,4 @@ -package org.enso.interpreter.node.expression.builtin.number.bigInteger; +package org.enso.interpreter.node.expression.builtin.number.integer; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; @@ -9,15 +9,30 @@ import org.enso.interpreter.runtime.EnsoContext; import org.enso.interpreter.runtime.error.DataflowError; import org.enso.interpreter.runtime.number.EnsoBigInteger; -@BuiltinMethod(type = "Big_Integer", name = "<", description = "Comparison of numbers.") +@BuiltinMethod(type = "Integer", name = "<", description = "Comparison of numbers.") public abstract class LessNode extends Node { - abstract Object execute(EnsoBigInteger self, Object that); + abstract Object execute(Object self, Object that); static LessNode build() { return LessNodeGen.create(); } + @Specialization + boolean doLong(long self, long that) { + return self < that; + } + + @Specialization + boolean doDouble(long self, double that) { + return (double) self < that; + } + + @Specialization + boolean doBigInteger(long self, EnsoBigInteger that) { + return that.getValue().signum() > 0; + } + @Specialization boolean doDouble(EnsoBigInteger self, double that) { return BigIntegerOps.toDouble(self.getValue()) < that; @@ -34,7 +49,7 @@ public abstract class LessNode extends Node { } @Fallback - Object doOther(EnsoBigInteger self, Object that) { + Object doOther(Object self, Object that) { var builtins = EnsoContext.get(this).getBuiltins(); var incomparableValsErr = builtins.error().makeIncomparableValues(self, that); return DataflowError.withoutTrace(incomparableValsErr, this); diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/LessOrEqualNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/LessOrEqualNode.java similarity index 68% rename from engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/LessOrEqualNode.java rename to engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/LessOrEqualNode.java index c1c71ec8b3..f4c225c1c8 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/LessOrEqualNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/LessOrEqualNode.java @@ -1,4 +1,4 @@ -package org.enso.interpreter.node.expression.builtin.number.bigInteger; +package org.enso.interpreter.node.expression.builtin.number.integer; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; @@ -9,15 +9,30 @@ import org.enso.interpreter.runtime.EnsoContext; import org.enso.interpreter.runtime.error.DataflowError; import org.enso.interpreter.runtime.number.EnsoBigInteger; -@BuiltinMethod(type = "Big_Integer", name = "<=", description = "Comparison of numbers.") +@BuiltinMethod(type = "Integer", name = "<=", description = "Comparison of numbers.") public abstract class LessOrEqualNode extends Node { - abstract Object execute(EnsoBigInteger self, Object that); + abstract Object execute(Object self, Object that); static LessOrEqualNode build() { return LessOrEqualNodeGen.create(); } + @Specialization + boolean doLong(long self, long that) { + return self <= that; + } + + @Specialization + boolean doDouble(long self, double that) { + return (double) self <= that; + } + + @Specialization + boolean doBigInteger(long self, EnsoBigInteger that) { + return that.getValue().signum() > 0; + } + @Specialization boolean doDouble(EnsoBigInteger self, double that) { return BigIntegerOps.toDouble(self.getValue()) <= that; @@ -34,7 +49,7 @@ public abstract class LessOrEqualNode extends Node { } @Fallback - Object doOther(EnsoBigInteger self, Object that) { + Object doOther(Object self, Object that) { var builtins = EnsoContext.get(this).getBuiltins(); var incomparableValsErr = builtins.error().makeIncomparableValues(self, that); return DataflowError.withoutTrace(incomparableValsErr, this); diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/ModNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/ModNode.java new file mode 100644 index 0000000000..7f4442520a --- /dev/null +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/ModNode.java @@ -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); + } +} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/MultiplyNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/MultiplyNode.java similarity index 59% rename from engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/MultiplyNode.java rename to engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/MultiplyNode.java index 72657c6b1b..3a9b1bb247 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/MultiplyNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/MultiplyNode.java @@ -1,4 +1,4 @@ -package org.enso.interpreter.node.expression.builtin.number.smallInteger; +package org.enso.interpreter.node.expression.builtin.number.integer; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; @@ -6,16 +6,13 @@ import com.oracle.truffle.api.nodes.Node; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode; -import org.enso.interpreter.runtime.EnsoContext; -import org.enso.interpreter.runtime.builtin.Builtins; -import org.enso.interpreter.runtime.error.PanicException; import org.enso.interpreter.runtime.number.EnsoBigInteger; -@BuiltinMethod(type = "Small_Integer", name = "*", description = "Multiplication of numbers.") +@BuiltinMethod(type = "Integer", name = "*", description = "Multiplication of numbers.") public abstract class MultiplyNode extends Node { private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create(); - abstract Object execute(long self, Object that); + abstract Object execute(Object self, Object that); static MultiplyNode build() { return MultiplyNodeGen.create(); @@ -41,10 +38,23 @@ public abstract class MultiplyNode extends Node { return toEnsoNumberNode.execute(BigIntegerOps.multiply(that.getValue(), self)); } + @Specialization + Object doLong(EnsoBigInteger self, long that) { + return toEnsoNumberNode.execute(BigIntegerOps.multiply(self.getValue(), that)); + } + + @Specialization + Object doBigInteger(EnsoBigInteger self, EnsoBigInteger that) { + return toEnsoNumberNode.execute(BigIntegerOps.multiply(self.getValue(), that.getValue())); + } + + @Specialization + double doDouble(EnsoBigInteger self, double that) { + return BigIntegerOps.toDouble(self.getValue()) * that; + } + @Fallback - Object doOther(long self, Object that) { - Builtins builtins = EnsoContext.get(this).getBuiltins(); - var number = builtins.number().getNumber(); - throw new PanicException(builtins.error().makeTypeError(number, that, "that"), this); + Object doOther(Object self, Object that) { + throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/NegateNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/NegateNode.java similarity index 57% rename from engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/NegateNode.java rename to engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/NegateNode.java index 7a166de20c..bad75b2e7a 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/NegateNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/NegateNode.java @@ -1,12 +1,14 @@ -package org.enso.interpreter.node.expression.builtin.number.smallInteger; +package org.enso.interpreter.node.expression.builtin.number.integer; +import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.nodes.Node; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode; +import org.enso.interpreter.runtime.number.EnsoBigInteger; -@BuiltinMethod(type = "Small_Integer", name = "negate", description = "Negation for numbers.") +@BuiltinMethod(type = "Integer", name = "negate", description = "Negation for numbers.") public abstract class NegateNode extends Node { private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create(); @@ -14,15 +16,25 @@ public abstract class NegateNode extends Node { return NegateNodeGen.create(); } - abstract Object execute(long self); + abstract Object execute(Object self); @Specialization(rewriteOn = ArithmeticException.class) long doNormal(long self) { return Math.negateExact(self); } + @Specialization + Object doBigInt(EnsoBigInteger self) { + return toEnsoNumberNode.execute(BigIntegerOps.negate(self.getValue())); + } + @Specialization Object doOverflow(long self) { return toEnsoNumberNode.execute(BigIntegerOps.negate(self)); } + + @Fallback + Object doOther(Object self) { + throw IntegerUtils.throwTypeErrorIfNotInt(self, this); + } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/PowNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/PowNode.java similarity index 50% rename from engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/PowNode.java rename to engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/PowNode.java index bc2acb0f4a..ece5406ba9 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/bigInteger/PowNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/PowNode.java @@ -1,26 +1,58 @@ -package org.enso.interpreter.node.expression.builtin.number.bigInteger; +package org.enso.interpreter.node.expression.builtin.number.integer; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.nodes.Node; +import java.math.BigInteger; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode; -import org.enso.interpreter.runtime.EnsoContext; -import org.enso.interpreter.runtime.builtin.Builtins; -import org.enso.interpreter.runtime.error.PanicException; import org.enso.interpreter.runtime.number.EnsoBigInteger; -@BuiltinMethod(type = "Big_Integer", name = "^", description = "Big integer exponentiation.") +@BuiltinMethod(type = "Integer", name = "^", description = "Exponentiation of numbers.") public abstract class PowNode extends Node { private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create(); + private @Child MultiplyNode multiplyNode = MultiplyNode.build(); - public abstract Object execute(EnsoBigInteger self, Object that); + abstract Object execute(Object self, Object that); - public static PowNode build() { + static PowNode build() { return PowNodeGen.create(); } + @Specialization + Object doLong(long self, long that) { + if (that < 0) { + return Math.pow(self, that); + } else if (that == 0) { + return 1L; + } else { + Object res = 1L; + Object base = self; + while (that > 0) { + if (that % 2 == 0) { + base = multiplyNode.execute(base, base); + that /= 2; + } else { + res = multiplyNode.execute(res, base); + that--; + } + } + return res; + } + } + + @Specialization + double doDouble(long self, double that) { + return Math.pow(self, that); + } + + @Specialization + Object doBigInteger(long self, EnsoBigInteger that) { + return doBigInteger(toBigInteger(self), that); + } + @Specialization Object doLong(EnsoBigInteger self, long that) { if (that == 0) { @@ -49,10 +81,13 @@ public abstract class PowNode extends Node { return Math.pow(BigIntegerOps.toDouble(self.getValue()), that); } + @CompilerDirectives.TruffleBoundary + private static EnsoBigInteger toBigInteger(long self) { + return new EnsoBigInteger(BigInteger.valueOf(self)); + } + @Fallback - Object doOther(EnsoBigInteger self, Object that) { - Builtins builtins = EnsoContext.get(this).getBuiltins(); - var number = builtins.number().getNumber(); - throw new PanicException(builtins.error().makeTypeError(number, that, "that"), this); + Object doOther(Object self, Object that) { + throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/RoundNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/RoundNode.java similarity index 96% rename from engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/RoundNode.java rename to engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/RoundNode.java index 83aeee35e0..01e8d80fb3 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/RoundNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/RoundNode.java @@ -1,4 +1,4 @@ -package org.enso.interpreter.node.expression.builtin.number.smallInteger; +package org.enso.interpreter.node.expression.builtin.number.integer; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.BranchProfile; diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/SubtractNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/SubtractNode.java similarity index 59% rename from engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/SubtractNode.java rename to engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/SubtractNode.java index 046174a110..635abb2a6f 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/SubtractNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/SubtractNode.java @@ -1,4 +1,4 @@ -package org.enso.interpreter.node.expression.builtin.number.smallInteger; +package org.enso.interpreter.node.expression.builtin.number.integer; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; @@ -6,16 +6,13 @@ import com.oracle.truffle.api.nodes.Node; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode; -import org.enso.interpreter.runtime.EnsoContext; -import org.enso.interpreter.runtime.builtin.Builtins; -import org.enso.interpreter.runtime.error.PanicException; import org.enso.interpreter.runtime.number.EnsoBigInteger; -@BuiltinMethod(type = "Small_Integer", name = "-", description = "Subtraction of numbers.") +@BuiltinMethod(type = "Integer", name = "-", description = "Subtraction of numbers.") public abstract class SubtractNode extends Node { private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create(); - abstract Object execute(long self, Object that); + abstract Object execute(Object self, Object that); static SubtractNode build() { return SubtractNodeGen.create(); @@ -41,10 +38,23 @@ public abstract class SubtractNode extends Node { return toEnsoNumberNode.execute(BigIntegerOps.subtract(self, that.getValue())); } + @Specialization + Object doLong(EnsoBigInteger self, long that) { + return toEnsoNumberNode.execute(BigIntegerOps.subtract(self.getValue(), that)); + } + + @Specialization + Object doBigInteger(EnsoBigInteger self, EnsoBigInteger that) { + return toEnsoNumberNode.execute(BigIntegerOps.subtract(self.getValue(), that.getValue())); + } + + @Specialization + double doDouble(EnsoBigInteger self, double that) { + return BigIntegerOps.toDouble(self.getValue()) - that; + } + @Fallback - Object doOther(long self, Object that) { - Builtins builtins = EnsoContext.get(this).getBuiltins(); - var number = builtins.number().getNumber(); - throw new PanicException(builtins.error().makeTypeError(number, that, "that"), this); + Object doOther(Object self, Object that) { + throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/ToDecimalNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/ToDecimalNode.java new file mode 100644 index 0000000000..5035aafe08 --- /dev/null +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/ToDecimalNode.java @@ -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); + } +} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/AddNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/AddNode.java deleted file mode 100644 index 59df47fe4e..0000000000 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/AddNode.java +++ /dev/null @@ -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); - } -} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/BitAndNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/BitAndNode.java deleted file mode 100644 index 33330ff0b4..0000000000 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/BitAndNode.java +++ /dev/null @@ -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); - } -} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/BitNotNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/BitNotNode.java deleted file mode 100644 index 0bd8646b30..0000000000 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/BitNotNode.java +++ /dev/null @@ -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); - } -} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/BitOrNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/BitOrNode.java deleted file mode 100644 index 431cf16f02..0000000000 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/BitOrNode.java +++ /dev/null @@ -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); - } -} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/BitShiftRightNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/BitShiftRightNode.java deleted file mode 100644 index a8752966e8..0000000000 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/BitShiftRightNode.java +++ /dev/null @@ -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); - } -} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/BitXorNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/BitXorNode.java deleted file mode 100644 index 9cd3c2af6c..0000000000 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/BitXorNode.java +++ /dev/null @@ -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); - } -} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/CeilNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/CeilNode.java deleted file mode 100644 index 9dfaf40665..0000000000 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/CeilNode.java +++ /dev/null @@ -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; - } -} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/DivNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/DivNode.java deleted file mode 100644 index 6af5da0547..0000000000 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/DivNode.java +++ /dev/null @@ -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); - } -} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/DivideNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/DivideNode.java deleted file mode 100644 index 9d3a6de7f1..0000000000 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/DivideNode.java +++ /dev/null @@ -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); - } -} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/FloorNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/FloorNode.java deleted file mode 100644 index c7f147025a..0000000000 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/FloorNode.java +++ /dev/null @@ -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; - } -} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/GreaterNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/GreaterNode.java deleted file mode 100644 index 690d7bfc3c..0000000000 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/GreaterNode.java +++ /dev/null @@ -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); - } -} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/GreaterOrEqualNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/GreaterOrEqualNode.java deleted file mode 100644 index 0e54883b47..0000000000 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/GreaterOrEqualNode.java +++ /dev/null @@ -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); - } -} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/LessNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/LessNode.java deleted file mode 100644 index 598251aaa2..0000000000 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/LessNode.java +++ /dev/null @@ -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); - } -} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/LessOrEqualNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/LessOrEqualNode.java deleted file mode 100644 index 089d31fc0f..0000000000 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/LessOrEqualNode.java +++ /dev/null @@ -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); - } -} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/ModNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/ModNode.java deleted file mode 100644 index 9c6a6e34f1..0000000000 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/ModNode.java +++ /dev/null @@ -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); - } -} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/PowNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/PowNode.java deleted file mode 100644 index b069786886..0000000000 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/PowNode.java +++ /dev/null @@ -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); - } -} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/ToDecimalNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/ToDecimalNode.java deleted file mode 100644 index 771414cc22..0000000000 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/smallInteger/ToDecimalNode.java +++ /dev/null @@ -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; - } -} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/builtin/Number.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/builtin/Number.java index 1430e131cc..92d0ad21b4 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/builtin/Number.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/builtin/Number.java @@ -1,40 +1,24 @@ package org.enso.interpreter.runtime.builtin; import org.enso.interpreter.node.expression.builtin.Builtin; -import org.enso.interpreter.node.expression.builtin.number.BigInteger; import org.enso.interpreter.node.expression.builtin.number.Decimal; import org.enso.interpreter.node.expression.builtin.number.Integer; -import org.enso.interpreter.node.expression.builtin.number.SmallInteger; import org.enso.interpreter.runtime.data.Type; /** A container for all number-related builtins. */ public class Number { - private final Builtin smallInteger; - private final Builtin bigInteger; private final Builtin integer; private final Builtin number; private final Builtin decimal; /** Creates builders for number Atom Constructors. */ public Number(Builtins builtins) { - smallInteger = builtins.getBuiltinType(SmallInteger.class); - bigInteger = builtins.getBuiltinType(BigInteger.class); integer = builtins.getBuiltinType(Integer.class); number = builtins.getBuiltinType(org.enso.interpreter.node.expression.builtin.number.Number.class); decimal = builtins.getBuiltinType(Decimal.class); } - /** @return the Int64 atom constructor. */ - public Type getSmallInteger() { - return smallInteger.getType(); - } - - /** @return the Big_Integer atom constructor. */ - public Type getBigInteger() { - return bigInteger.getType(); - } - /** @return the Integer atom constructor */ public Type getInteger() { return integer.getType(); diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/library/dispatch/DefaultLongExports.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/library/dispatch/DefaultLongExports.java index 1b9888014e..b0a9d49a43 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/library/dispatch/DefaultLongExports.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/library/dispatch/DefaultLongExports.java @@ -17,6 +17,6 @@ public class DefaultLongExports { @ExportMessage static Type getType( Long receiver, @CachedLibrary("receiver") TypesLibrary thisLib, @Cached("1") int ignore) { - return EnsoContext.get(thisLib).getBuiltins().number().getSmallInteger(); + return EnsoContext.get(thisLib).getBuiltins().number().getInteger(); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/number/EnsoBigInteger.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/number/EnsoBigInteger.java index cb74cbf54d..931390e592 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/number/EnsoBigInteger.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/number/EnsoBigInteger.java @@ -131,7 +131,7 @@ public final class EnsoBigInteger implements EnsoObject { @ExportMessage Type getMetaObject(@CachedLibrary("this") InteropLibrary thisLib) { - return EnsoContext.get(thisLib).getBuiltins().number().getBigInteger(); + return EnsoContext.get(thisLib).getBuiltins().number().getInteger(); } @ExportMessage @@ -146,7 +146,7 @@ public final class EnsoBigInteger implements EnsoObject { @ExportMessage Type getType(@CachedLibrary("this") TypesLibrary thisLib, @Cached("1") int ignore) { - return EnsoContext.get(thisLib).getBuiltins().number().getBigInteger(); + return EnsoContext.get(thisLib).getBuiltins().number().getInteger(); } @Override diff --git a/engine/runtime/src/test/java/org/enso/interpreter/test/IntegerTest.java b/engine/runtime/src/test/java/org/enso/interpreter/test/IntegerTest.java new file mode 100644 index 0000000000..95de017ce4 --- /dev/null +++ b/engine/runtime/src/test/java/org/enso/interpreter/test/IntegerTest.java @@ -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; + }); + } +} diff --git a/engine/runtime/src/test/scala/org/enso/interpreter/test/semantic/TextTest.scala b/engine/runtime/src/test/scala/org/enso/interpreter/test/semantic/TextTest.scala index 8b313a0a98..b18dc73ce1 100644 --- a/engine/runtime/src/test/scala/org/enso/interpreter/test/semantic/TextTest.scala +++ b/engine/runtime/src/test/scala/org/enso/interpreter/test/semantic/TextTest.scala @@ -133,7 +133,7 @@ class TextTest extends InterpreterTest { "Compile error: error :(.", "Inexhaustive pattern match: no branch matches 32.", "Arithmetic error: cannot frobnicate quaternions.", - "Type error: expected `that` to be Number, but got Text.", + "Type error: expected `that` to be Integer, but got Text.", "Type error: expected a function, but got 7.", "Wrong number of arguments. Expected 10, but got 20." ) diff --git a/test/Tests/src/Data/Numbers_Spec.enso b/test/Tests/src/Data/Numbers_Spec.enso index 14d12ed804..27b0be1b73 100644 --- a/test/Tests/src/Data/Numbers_Spec.enso +++ b/test/Tests/src/Data/Numbers_Spec.enso @@ -225,6 +225,13 @@ spec = Integer.parse "-101021010" 2 . should_fail_with Number_Parse_Error Integer.parse "123" 128 . should_fail_with Number_Parse_Error + Test.specify "should be able to invoke methods on Integer via static method call" <| + Integer.+ 1 2 . should_equal 3 + Integer.+ 1 2.5 . should_equal 3.5 + Test.expect_panic_with (Integer.+ 1.5 1) Type_Error + Test.expect_panic_with (Integer.+ 1.5 2.5) Type_Error + Test.expect_panic_with (Integer.+ 1 "hello") Type_Error + Test.group "Decimals" <| Test.specify "should exist and expose basic arithmetic operations" <| @@ -297,6 +304,10 @@ spec = 1/0 . is_infinite . should_be_true -1/0 . is_infinite . should_be_true + hundred_factorial%0 . should_fail_with Arithmetic_Error + hundred_factorial%hundred_factorial . should_equal 0 + 10%hundred_factorial . should_equal 10 + Test.specify "should support less than operator" <| (1 < 2).should_be_true (1 < 1).should_be_false diff --git a/test/Tests/src/Semantic/Meta_Spec.enso b/test/Tests/src/Semantic/Meta_Spec.enso index 1634e97df3..5c7c7acb6b 100644 --- a/test/Tests/src/Semantic/Meta_Spec.enso +++ b/test/Tests/src/Semantic/Meta_Spec.enso @@ -258,10 +258,10 @@ spec = methods.sort . should_equal ['Value', 'create', 'factory', 'first_method', 'my_method', 'other_method', 'second_method'] Test.specify "methods of Integer" <| - Meta.meta Integer . methods . sort . should_equal ['bit_shift_l', 'round', 'truncate'] + Meta.meta Integer . methods . sort . should_equal ['%', '*', '+', '-', '/', '<', '<=', '>', '>=', '^', 'abs', 'bit_and', 'bit_not', 'bit_or', 'bit_shift', 'bit_shift_l', 'bit_shift_r', 'bit_xor', 'ceil', 'div', 'floor', 'negate', 'round', 'to_decimal', 'truncate'] Test.specify "static methods of Integer" <| - Meta.meta (Meta.type_of Integer) . methods . sort . should_equal ['bit_shift_l', 'parse', 'parse_builtin', 'round', 'round_integer_builtin', 'truncate'] + Meta.meta (Meta.type_of Integer) . methods . sort . should_equal ['%', '*', '+', '-', '/', '<', '<=', '>', '>=', '^', 'abs', 'bit_and', 'bit_not', 'bit_or', 'bit_shift', 'bit_shift_l', 'bit_shift_r', 'bit_xor', 'ceil', 'div', 'floor', 'negate', 'parse', 'parse_builtin', 'round', 'round_integer_builtin', 'to_decimal', 'truncate'] Test.specify "methods of Any" <| Meta.meta Any . methods . should_contain "to_text"