Skip to content

Commit

Permalink
Support foreign number argument in double arithmetic nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
JaroslavTulach committed Sep 14, 2023
1 parent 3d5b014 commit 634b25c
Show file tree
Hide file tree
Showing 13 changed files with 212 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package org.enso.interpreter.node.expression.builtin.number.decimal;

import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Fallback;
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.library.CachedLibrary;
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.node.expression.builtin.number.utils.ToEnsoNumberNode;
import org.enso.interpreter.runtime.number.EnsoBigInteger;

@BuiltinMethod(type = "Decimal", name = "+", description = "Addition of numbers.")
Expand All @@ -32,10 +34,18 @@ static AddNode build() {
return self + BigIntegerOps.toDouble(that.getValue());
}

@Specialization(guards = "isForeignNumber(iop, that)")
double doInterop(
double self,
TruffleObject that,
@CachedLibrary(limit = INTEROP_LIMIT) InteropLibrary iop,
@Cached ToEnsoNumberNode toEnsoNumberNode,
@Cached AddNode delegate) {
return delegate.execute(self, handleInterop(false, self, that, iop, toEnsoNumberNode));
}

@Fallback
double doOther(double self, Object that) {
Builtins builtins = EnsoContext.get(this).getBuiltins();
var number = builtins.number().getNumber();
throw new PanicException(builtins.error().makeTypeError(number, that, "that"), this);
throw panicOtherwise(self, that);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package org.enso.interpreter.node.expression.builtin.number.decimal;

import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Fallback;
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.library.CachedLibrary;
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 = "Decimal", name = "/", description = "Division of numbers.")
Expand All @@ -29,8 +34,18 @@ static DivideNode build() {
return self / BigIntegerOps.toDouble(that.getValue());
}

@Specialization(guards = "isForeignNumber(iop, that)")
double doInterop(
double self,
TruffleObject that,
@CachedLibrary(limit = INTEROP_LIMIT) InteropLibrary iop,
@Cached ToEnsoNumberNode toEnsoNumberNode,
@Cached DivideNode delegate) {
return delegate.execute(self, handleInterop(false, self, that, iop, toEnsoNumberNode));
}

@Fallback
double doOther(double self, Object that) {
return handleOther(self, that);
throw panicOtherwise(self, that);
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,45 @@
package org.enso.interpreter.node.expression.builtin.number.decimal;

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.nodes.Node;
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.error.PanicException;
import org.enso.interpreter.runtime.number.EnsoBigInteger;

abstract class FloatNode extends Node {
final double handleOther(double self, Object that) {
static final String INTEROP_LIMIT = "3";

final boolean isForeignNumber(InteropLibrary iop, TruffleObject obj) {
if (obj instanceof EnsoBigInteger) {
return false;
}
return iop.isNumber(obj);
}

final Object handleInterop(
boolean incomparableError,
double self,
TruffleObject that,
InteropLibrary iop,
ToEnsoNumberNode toEnsoNumberNode) {
try {
if (iop.fitsInLong(that)) {
return iop.asLong(that);
} else if (iop.fitsInDouble(that)) {
return iop.asDouble(that);
} else if (iop.fitsInBigInteger(that)) {
return toEnsoNumberNode.execute(iop.asBigInteger(that));
}
} catch (UnsupportedMessageException ex) {
}
return incomparableError ? incomparableError(self, that) : panicOtherwise(self, that);
}

final PanicException panicOtherwise(double self, Object that) {
var builtins = EnsoContext.get(this).getBuiltins();
var number = builtins.number().getNumber();
throw new PanicException(builtins.error().makeTypeError(number, that, "that"), this);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package org.enso.interpreter.node.expression.builtin.number.decimal;

import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Fallback;
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.library.CachedLibrary;
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 = "Decimal", name = ">", description = "Comparison of numbers.")
Expand Down Expand Up @@ -42,6 +47,16 @@ Object doBigInteger(double self, EnsoBigInteger that) {
}
}

@Specialization(guards = "isForeignNumber(iop, that)")
Object doInterop(
double self,
TruffleObject that,
@CachedLibrary(limit = INTEROP_LIMIT) InteropLibrary iop,
@Cached ToEnsoNumberNode toEnsoNumberNode,
@Cached GreaterNode delegate) {
return delegate.execute(self, handleInterop(true, self, that, iop, toEnsoNumberNode));
}

@Fallback
Object doOther(double self, Object that) {
return incomparableError(self, that);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package org.enso.interpreter.node.expression.builtin.number.decimal;

import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Fallback;
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.library.CachedLibrary;
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 = "Decimal", name = ">=", description = "Comparison of numbers.")
Expand Down Expand Up @@ -42,6 +47,16 @@ Object doBigInteger(double self, EnsoBigInteger that) {
}
}

@Specialization(guards = "isForeignNumber(iop, that)")
Object doInterop(
double self,
TruffleObject that,
@CachedLibrary(limit = INTEROP_LIMIT) InteropLibrary iop,
@Cached ToEnsoNumberNode toEnsoNumberNode,
@Cached GreaterOrEqualNode delegate) {
return delegate.execute(self, handleInterop(true, self, that, iop, toEnsoNumberNode));
}

@Fallback
Object doOther(double self, Object that) {
return incomparableError(self, that);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package org.enso.interpreter.node.expression.builtin.number.decimal;

import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Fallback;
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.library.CachedLibrary;
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 = "Decimal", name = "<", description = "Comparison of numbers.")
Expand Down Expand Up @@ -42,6 +47,16 @@ Object doBigInteger(double self, EnsoBigInteger that) {
}
}

@Specialization(guards = "isForeignNumber(iop, that)")
Object doInterop(
double self,
TruffleObject that,
@CachedLibrary(limit = INTEROP_LIMIT) InteropLibrary iop,
@Cached ToEnsoNumberNode toEnsoNumberNode,
@Cached LessNode delegate) {
return delegate.execute(self, handleInterop(true, self, that, iop, toEnsoNumberNode));
}

@Fallback
Object doOther(double self, Object that) {
return incomparableError(self, that);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package org.enso.interpreter.node.expression.builtin.number.decimal;

import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Fallback;
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.library.CachedLibrary;
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 = "Decimal", name = "<=", description = "Comparison of numbers.")
Expand Down Expand Up @@ -42,6 +47,16 @@ Object doBigInteger(double self, EnsoBigInteger that) {
}
}

@Specialization(guards = "isForeignNumber(iop, that)")
Object doInterop(
double self,
TruffleObject that,
@CachedLibrary(limit = INTEROP_LIMIT) InteropLibrary iop,
@Cached ToEnsoNumberNode toEnsoNumberNode,
@Cached LessOrEqualNode delegate) {
return delegate.execute(self, handleInterop(true, self, that, iop, toEnsoNumberNode));
}

@Fallback
Object doOther(double self, Object that) {
return incomparableError(self, that);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package org.enso.interpreter.node.expression.builtin.number.decimal;

import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Fallback;
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.library.CachedLibrary;
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 = "Decimal", name = "%", description = "Modulo division of numbers.")
Expand All @@ -29,8 +34,18 @@ static ModNode build() {
return self % BigIntegerOps.toDouble(that.getValue());
}

@Specialization(guards = "isForeignNumber(iop, that)")
double doInterop(
double self,
TruffleObject that,
@CachedLibrary(limit = INTEROP_LIMIT) InteropLibrary iop,
@Cached ToEnsoNumberNode toEnsoNumberNode,
@Cached ModNode delegate) {
return delegate.execute(self, handleInterop(false, self, that, iop, toEnsoNumberNode));
}

@Fallback
double doOther(double self, Object that) {
return handleOther(self, that);
throw panicOtherwise(self, that);
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package org.enso.interpreter.node.expression.builtin.number.decimal;

import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Fallback;
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.library.CachedLibrary;
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.node.expression.builtin.number.utils.ToEnsoNumberNode;
import org.enso.interpreter.runtime.number.EnsoBigInteger;

@BuiltinMethod(type = "Decimal", name = "*", description = "Multiplication of numbers.")
Expand All @@ -32,10 +34,18 @@ static MultiplyNode build() {
return self * BigIntegerOps.toDouble(that.getValue());
}

@Specialization(guards = "isForeignNumber(iop, that)")
double doInterop(
double self,
TruffleObject that,
@CachedLibrary(limit = INTEROP_LIMIT) InteropLibrary iop,
@Cached ToEnsoNumberNode toEnsoNumberNode,
@Cached MultiplyNode delegate) {
return delegate.execute(self, handleInterop(false, self, that, iop, toEnsoNumberNode));
}

@Fallback
double doOther(double self, Object that) {
Builtins builtins = EnsoContext.get(this).getBuiltins();
var number = builtins.number().getNumber();
throw new PanicException(builtins.error().makeTypeError(number, that, "that"), this);
throw panicOtherwise(self, that);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package org.enso.interpreter.node.expression.builtin.number.decimal;

import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Fallback;
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.library.CachedLibrary;
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 = "Decimal", name = "^", description = "Exponentiation of numbers.")
Expand All @@ -29,8 +34,18 @@ static PowNode build() {
return Math.pow(self, BigIntegerOps.toDouble(that.getValue()));
}

@Specialization(guards = "isForeignNumber(iop, that)")
double doInterop(
double self,
TruffleObject that,
@CachedLibrary(limit = INTEROP_LIMIT) InteropLibrary iop,
@Cached ToEnsoNumberNode toEnsoNumberNode,
@Cached PowNode delegate) {
return delegate.execute(self, handleInterop(false, self, that, iop, toEnsoNumberNode));
}

@Fallback
double doOther(double self, Object that) {
return handleOther(self, that);
throw panicOtherwise(self, that);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package org.enso.interpreter.node.expression.builtin.number.decimal;

import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Fallback;
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.library.CachedLibrary;
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 = "Decimal", name = "-", description = "Subtraction of numbers.")
Expand All @@ -29,8 +34,18 @@ static SubtractNode build() {
return self - BigIntegerOps.toDouble(that.getValue());
}

@Specialization(guards = "isForeignNumber(iop, that)")
double doInterop(
double self,
TruffleObject that,
@CachedLibrary(limit = INTEROP_LIMIT) InteropLibrary iop,
@Cached ToEnsoNumberNode toEnsoNumberNode,
@Cached SubtractNode delegate) {
return delegate.execute(self, handleInterop(false, self, that, iop, toEnsoNumberNode));
}

@Fallback
double doOther(double self, Object that) {
return handleOther(self, that);
throw panicOtherwise(self, that);
}
}
Loading

0 comments on commit 634b25c

Please sign in to comment.