Skip to content

Commit

Permalink
Making integer AddNode work with foreign numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
JaroslavTulach committed Sep 13, 2023
1 parent 340d76d commit dad0fb1
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
package org.enso.interpreter.node.expression.builtin.number.integer;

import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.ImportStatic;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.CachedLibrary;
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.")
@ImportStatic(IntegerUtils.class)
public abstract class AddNode extends Node {
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();

Expand Down Expand Up @@ -55,6 +62,25 @@ Object doBigIntegerLong(EnsoBigInteger self, long that) {
return self.asDouble() + that;
}

@Specialization(guards = "isForeignNumber(iop, that)")
Object doInterop(
Object self,
TruffleObject that,
@CachedLibrary(limit = "3") InteropLibrary iop,
@Cached AddNode delegate) {
try {
if (iop.fitsInLong(that)) {
return delegate.execute(self, iop.asLong(that));
} else if (iop.fitsInDouble(that)) {
return delegate.execute(self, iop.asDouble(that));
} else if (iop.fitsInBigInteger(that)) {
return delegate.execute(self, new EnsoBigInteger(iop.asBigInteger(that)));
}
} catch (UnsupportedMessageException ex) {
}
return doOther(self, that);
}

@Fallback
Object doOther(Object self, Object that) {
throw IntegerUtils.throwTypeErrorIfNotInt(self, that, this);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package org.enso.interpreter.node.expression.builtin.number.integer;

import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.TruffleObject;
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;
import org.enso.interpreter.runtime.number.EnsoBigInteger;

public final class IntegerUtils {
private IntegerUtils() {}
Expand All @@ -27,4 +30,11 @@ static PanicException throwTypeErrorIfNotInt(Object self, Node node) {
var intType = builtins.number().getInteger();
return new PanicException(builtins.error().makeTypeError(intType, self, "self"), node);
}

static boolean isForeignNumber(InteropLibrary iop, TruffleObject obj) {
if (obj instanceof EnsoBigInteger) {
return false;
}
return iop.isNumber(obj);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.ExportLibrary;
import com.oracle.truffle.api.library.ExportMessage;

import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalTime;
Expand All @@ -16,9 +17,11 @@
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import org.enso.interpreter.node.expression.builtin.interop.syntax.HostValueToEnsoNode;
import org.enso.interpreter.node.expression.builtin.meta.EqualsNode;
import org.enso.interpreter.node.expression.builtin.meta.EqualsNodeGen;
import org.enso.polyglot.MethodNames;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Value;
import org.junit.AfterClass;
Expand Down Expand Up @@ -117,9 +120,6 @@ public void equalsNodeCachedIsConsistentWithUncached(Object firstVal, Object sec
() -> {
Object uncachedRes = EqualsNodeGen.getUncached().execute(firstVal, secondVal);
Object cachedRes = equalsNode.execute(firstVal, secondVal);
if (uncachedRes != cachedRes) {
Thread.dumpStack();
}
assertEquals(
"Result from uncached EqualsNode should be the same as result from its cached variant",
uncachedRes,
Expand Down Expand Up @@ -393,4 +393,20 @@ public void testTruffleString() {
return null;
});
}

@Test
public void testTruffleNumberPlus() {
var plus100 = context.eval("enso", """
plus100 x = 100+x
""").invokeMember(MethodNames.Module.EVAL_EXPRESSION, "plus100");
assertTrue("plus100 can be executed", plus100.canExecute());
var foreignNumber = context.asValue(new WrappedPrimitive(42));
var hundred42 = unwrapValue(context, plus100.execute(foreignNumber));
executeInContext(context,
() -> {
assertTrue(equalsNode.execute(142L, hundred42));
assertTrue(equalsNode.execute(hundred42, 142L));
return null;
});
}
}
1 change: 1 addition & 0 deletions test/Tests/src/Semantic/Conversion_Spec.enso
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ spec =
100+(x:Integer) . should_equal 142
(x:Integer)+100 . should_equal 142
x+100 . should_equal 142
100+x . should_equal 142
x.to_text . should_equal "{FOOL 42}"
(x:Fool).to_text . should_equal "{FOOL 42}"
(x:Integer).to_text . should_equal "42"
Expand Down

0 comments on commit dad0fb1

Please sign in to comment.