mirror of
https://github.com/enso-org/enso.git
synced 2024-09-11 13:15:52 +03:00
Decimal Numbers (#1146)
This commit is contained in:
parent
9666d9065e
commit
e38d1ab521
@ -26,11 +26,6 @@ Number.times = act ->
|
|||||||
res = here.reverse_list (go Nil this)
|
res = here.reverse_list (go Nil this)
|
||||||
res
|
res
|
||||||
|
|
||||||
zeropad number =
|
|
||||||
txt = number.to_text
|
|
||||||
if number % 10 == number then "00" + txt else
|
|
||||||
if number % 100 == number then "0" + txt else txt
|
|
||||||
|
|
||||||
measure = ~act -> label -> iter_size -> num_iters ->
|
measure = ~act -> label -> iter_size -> num_iters ->
|
||||||
single_call = _ ->
|
single_call = _ ->
|
||||||
x1 = System.nano_time
|
x1 = System.nano_time
|
||||||
@ -41,6 +36,6 @@ measure = ~act -> label -> iter_size -> num_iters ->
|
|||||||
act_it_num = num_iters - it_num
|
act_it_num = num_iters - it_num
|
||||||
res = iter_size.times single_call
|
res = iter_size.times single_call
|
||||||
avg = here.avg_list res
|
avg = here.avg_list res
|
||||||
fmt = (avg / 1000000).to_text + "." + here.zeropad ((avg / 1000) % 1000)
|
fmt = (avg / 1000000).format "%.2f"
|
||||||
IO.println (label + "/iteration:" + act_it_num.to_text + ": " + fmt + "ms")
|
IO.println (label + "/iteration:" + act_it_num.to_text + ": " + fmt + "ms")
|
||||||
num_iters.times iteration
|
num_iters.times iteration
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
import Base.List
|
import Base.List
|
||||||
import Base.Vector
|
import Base.Vector
|
||||||
from Builtins import Number, Unit
|
import Base.Number.Extensions
|
||||||
|
from Builtins import Unit, Number, Integer
|
||||||
|
|
||||||
from Builtins export all
|
from Builtins export all
|
||||||
|
|
||||||
from Base.List export Nil, Cons
|
from Base.List export Nil, Cons
|
||||||
from Base.Vector export Vector
|
from Base.Vector export Vector
|
||||||
|
from Base.Number.Extensions export all hiding Math
|
||||||
|
|
||||||
## Represents a right-exclusive range of integer values.
|
## Represents a right-exclusive range of integer values.
|
||||||
type Range
|
type Range
|
||||||
@ -42,5 +44,9 @@ type Range
|
|||||||
res = it initial this.start this.end
|
res = it initial this.start this.end
|
||||||
res
|
res
|
||||||
|
|
||||||
## Creates a new right-exclusive range of integers from `this` to `n`.
|
type Math
|
||||||
Number.upto n = Range this n
|
|
||||||
|
## The mathematical constant pi, equal to the ratio of a circle circumference
|
||||||
|
to its diameter.
|
||||||
|
Math.pi : Decimal
|
||||||
|
Math.pi = 3.141592653589793
|
||||||
|
85
distribution/std-lib/Base/src/Number/Extensions.enso
Normal file
85
distribution/std-lib/Base/src/Number/Extensions.enso
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
from Base import all
|
||||||
|
polyglot java import java.lang.Math
|
||||||
|
polyglot java import java.lang.String
|
||||||
|
|
||||||
|
## Computes the inverse of the sine function
|
||||||
|
|
||||||
|
Selects a value in the -pi/2 through pi/2 range.
|
||||||
|
Number.asin : Decimal
|
||||||
|
Number.asin = Math.asin [this.to_decimal]
|
||||||
|
|
||||||
|
## Computes the inverse of the cosine function.
|
||||||
|
|
||||||
|
Selects a value in the -pi/2 through pi/2 range.
|
||||||
|
Number.acos : Decimal
|
||||||
|
Number.acos = Math.acos [this.to_decimal]
|
||||||
|
|
||||||
|
## Computes the inverse of the tangent function.
|
||||||
|
|
||||||
|
Selects a value in the -pi/2 through pi/2 range.
|
||||||
|
Number.atan : Decimal
|
||||||
|
Number.atan = Math.atan [this.to_decimal]
|
||||||
|
|
||||||
|
## Computes the argument (angle) in the conversion from cartesian
|
||||||
|
to polar coordinates.
|
||||||
|
|
||||||
|
The returned angle is in the -pi through pi range.
|
||||||
|
Number.atan_2 : Number -> Decimal
|
||||||
|
Number.atan_2 y = Math.atan2 [this.to_decimal, y.to_decimal]
|
||||||
|
|
||||||
|
## Computes the sine function.
|
||||||
|
Number.sin : Decimal
|
||||||
|
Number.sin = Math.sin [this.to_decimal]
|
||||||
|
|
||||||
|
## Computes the cosine function.
|
||||||
|
Number.cos : Decimal
|
||||||
|
Number.cos = Math.cos [this.to_decimal]
|
||||||
|
|
||||||
|
## Computes the tangent function.
|
||||||
|
Number.tan : Decimal
|
||||||
|
Number.tan = Math.tan [this.to_decimal]
|
||||||
|
|
||||||
|
## Computes the hyperbolic sine function.
|
||||||
|
Number.sinh : Decimal
|
||||||
|
Number.sinh = Math.sinh [this.to_decimal]
|
||||||
|
|
||||||
|
## Computes the hyperbolic cosine function.
|
||||||
|
Number.cosh : Decimal
|
||||||
|
Number.cosh = Math.cosh [this.to_decimal]
|
||||||
|
|
||||||
|
## Computes the hyperbolic tangent function.
|
||||||
|
Number.tanh : Decimal
|
||||||
|
Number.tanh = Math.tanh [this.to_decimal]
|
||||||
|
|
||||||
|
## Computes the exponential function.
|
||||||
|
Number.exp : Decimal
|
||||||
|
Number.exp = Math.exp [this.to_decimal]
|
||||||
|
|
||||||
|
## Computes the natural logarithm function.
|
||||||
|
Number.ln : Decimal
|
||||||
|
Number.ln = Math.log [this.to_decimal]
|
||||||
|
|
||||||
|
## Computes the square root of `this`.
|
||||||
|
Number.sqrt : Decimal
|
||||||
|
Number.sqrt = Math.sqrt [this.to_decimal]
|
||||||
|
|
||||||
|
## Computes the `base`-log of `this`.
|
||||||
|
Number.log : Number -> Decimal
|
||||||
|
Number.log base = this.ln / base.ln
|
||||||
|
|
||||||
|
## Converts a decimal value to a string, using the Java string formatting
|
||||||
|
syntax.
|
||||||
|
|
||||||
|
TODO this should expose a more-user friendly API in the future.
|
||||||
|
Decimal.format : Text -> Text
|
||||||
|
Decimal.format fmt = String.format [fmt, this]
|
||||||
|
|
||||||
|
## Creates a new right-exclusive range of integers from `this` to `n`.
|
||||||
|
Integer.upto : Integer -> Range
|
||||||
|
Integer.upto n = Range this n
|
||||||
|
|
||||||
|
## Checks equality of numbers, using an `epsilon` value.
|
||||||
|
|
||||||
|
Returns `True` when `this` and `that` are at most `epsilon` apart.
|
||||||
|
Number.equals : Number -> Number -> Boolean
|
||||||
|
Number.equals that epsilon = (this - that).abs <= epsilon
|
@ -1,5 +1,4 @@
|
|||||||
import Base.List
|
from Base import all
|
||||||
from Builtins import all
|
|
||||||
|
|
||||||
## The top-level entry point for a test suite.
|
## The top-level entry point for a test suite.
|
||||||
type Suite specs
|
type Suite specs
|
||||||
@ -38,6 +37,13 @@ Any.should_equal that = case this == that of
|
|||||||
msg = this.to_text + " did not equal " + that.to_text + "."
|
msg = this.to_text + " did not equal " + that.to_text + "."
|
||||||
Panic.throw (Failure msg)
|
Panic.throw (Failure msg)
|
||||||
|
|
||||||
|
## Asserts that `this` is within `epsilon` from `that`.
|
||||||
|
Decimal.should_equal that (epsilon = 0) = case this.equals that epsilon of
|
||||||
|
True -> Success
|
||||||
|
False ->
|
||||||
|
msg = this.to_text + " did not equal " + that.to_text + "."
|
||||||
|
Panic.throw (Failure msg)
|
||||||
|
|
||||||
## Asserts that the given `Boolean` is `True`
|
## Asserts that the given `Boolean` is `True`
|
||||||
Boolean.should_be_true = case this of
|
Boolean.should_be_true = case this of
|
||||||
True -> Success
|
True -> Success
|
||||||
|
66
docs/semantics/numbers.md
Normal file
66
docs/semantics/numbers.md
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
---
|
||||||
|
layout: developer-doc
|
||||||
|
title: Numbers
|
||||||
|
category: semantics
|
||||||
|
tags: [semantics, runtime, number]
|
||||||
|
order: 8
|
||||||
|
---
|
||||||
|
|
||||||
|
# Numbers
|
||||||
|
|
||||||
|
In order to enhance the user experience, Enso provides a number hierarchy,
|
||||||
|
encompassing both integers of unbound size and floating-point decimals.
|
||||||
|
|
||||||
|
<!-- MarkdownTOC levels="2,3" autolink="true" -->
|
||||||
|
|
||||||
|
- [Number Types](#number-types)
|
||||||
|
- [Internal Representation](#internal-representation)
|
||||||
|
- [Type Conversions](#type-conversions)
|
||||||
|
|
||||||
|
<!-- /MarkdownTOC -->
|
||||||
|
|
||||||
|
## Number Types
|
||||||
|
|
||||||
|
The base number type in Enso is `Number`. It includes both integers and
|
||||||
|
floating-point numbers and is the basic type that should be used whenever
|
||||||
|
numerical computations are performed. Any method defined on the type `Number` is
|
||||||
|
automatically available on all types of numeric values.
|
||||||
|
|
||||||
|
The hierarchy is further split into the `Integer` and `Decimal` types. `Integer`
|
||||||
|
is capable of representing values of unbound length. `Decimal` is capable of
|
||||||
|
representing IEEE 64-bit (double precision) floating numbers.
|
||||||
|
|
||||||
|
Any method defined on `Integer` is available for all integers, while any method
|
||||||
|
defined on `Decimal` is available on all floating-point numbers. Methods defined
|
||||||
|
on `Integer` or `Decimal` take precedence over methods defined on `Number`, when
|
||||||
|
name resolution is performed.
|
||||||
|
|
||||||
|
## Internal Representation
|
||||||
|
|
||||||
|
Integers that can be represented in a 64-bit integer type are represented as
|
||||||
|
such. When a 64-bit representation would overflow (either by the result of
|
||||||
|
creating a large number literal or an arithmetic operation), it is represented
|
||||||
|
in a Java `BigInteger` type, thus becoming significantly slower than the 64-bit
|
||||||
|
representation.
|
||||||
|
|
||||||
|
Decimals are represented using the Java `double` type.
|
||||||
|
|
||||||
|
## Type Conversions
|
||||||
|
|
||||||
|
Number literals that do not contain a decimal point, are treated as integers.
|
||||||
|
Other literals are interpreted as decimals (even if the fractional part is 0).
|
||||||
|
|
||||||
|
Any arithmetic operation where at least one of the operands is a decimal will
|
||||||
|
result in a decimal result.
|
||||||
|
|
||||||
|
Moreover, the default division operator `/` is implemented as floating-point
|
||||||
|
division and always returns a decimal. If the desired behavior is integral
|
||||||
|
division instead, the `Integer.div` method implements it.
|
||||||
|
|
||||||
|
Another operator worth noting is the exponentiation operator (`^`). It will
|
||||||
|
always result in a decimal whenever either operand is decimal or the exponent is
|
||||||
|
negative. It will also return a float result when the exponent is outside the
|
||||||
|
64-bit integer range.
|
||||||
|
|
||||||
|
There is a `Number.to_decimal` method, that allows converting any number to a
|
||||||
|
decimal. This is useful in certain high-performance and polyglot applications.
|
@ -97,6 +97,16 @@ public abstract class MethodResolverNode extends Node {
|
|||||||
return function;
|
return function;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Specialization(guards = "cachedSymbol == symbol")
|
||||||
|
Function resolveDouble(
|
||||||
|
UnresolvedSymbol symbol,
|
||||||
|
double self,
|
||||||
|
@Cached(value = "symbol", allowUncached = true) UnresolvedSymbol cachedSymbol,
|
||||||
|
@Cached(value = "resolveMethodOnDouble(cachedSymbol)", allowUncached = true)
|
||||||
|
Function function) {
|
||||||
|
return function;
|
||||||
|
}
|
||||||
|
|
||||||
@Specialization(guards = {"cachedSymbol == symbol", "function != null"})
|
@Specialization(guards = {"cachedSymbol == symbol", "function != null"})
|
||||||
Function resolveBoolean(
|
Function resolveBoolean(
|
||||||
UnresolvedSymbol symbol,
|
UnresolvedSymbol symbol,
|
||||||
@ -220,6 +230,14 @@ public abstract class MethodResolverNode extends Node {
|
|||||||
symbol);
|
symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Function resolveMethodOnDouble(UnresolvedSymbol symbol) {
|
||||||
|
Number number = getBuiltins().number();
|
||||||
|
return ensureMethodExists(
|
||||||
|
symbol.resolveFor(number.getDecimal(), number.getNumber(), getBuiltins().any()),
|
||||||
|
"Decimal",
|
||||||
|
symbol);
|
||||||
|
}
|
||||||
|
|
||||||
@CompilerDirectives.TruffleBoundary
|
@CompilerDirectives.TruffleBoundary
|
||||||
Function resolveMethodOnPrimBoolean(UnresolvedSymbol symbol, Context context) {
|
Function resolveMethodOnPrimBoolean(UnresolvedSymbol symbol, Context context) {
|
||||||
Bool bool = context.getBuiltins().bool();
|
Bool bool = context.getBuiltins().bool();
|
||||||
|
@ -0,0 +1,55 @@
|
|||||||
|
package org.enso.interpreter.node.expression.builtin.interop.syntax;
|
||||||
|
|
||||||
|
import com.oracle.truffle.api.dsl.Fallback;
|
||||||
|
import com.oracle.truffle.api.dsl.ReportPolymorphism;
|
||||||
|
import com.oracle.truffle.api.dsl.Specialization;
|
||||||
|
import com.oracle.truffle.api.nodes.Node;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a value returned by a polyglot call back to a value that can be further used within Enso
|
||||||
|
* programs.
|
||||||
|
*/
|
||||||
|
@ReportPolymorphism
|
||||||
|
public abstract class HostValueToEnsoNode extends Node {
|
||||||
|
public static HostValueToEnsoNode build() {
|
||||||
|
return HostValueToEnsoNodeGen.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts an arbitrary value to a value usable within Enso code.
|
||||||
|
*
|
||||||
|
* @param o the value to convert.
|
||||||
|
* @return the Enso counterpart of the value.
|
||||||
|
*/
|
||||||
|
public abstract Object execute(Object o);
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
double doFloat(float f) {
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
long doInt(int i) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
long doShort(short i) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
long doByte(byte i) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
long doChar(char i) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Fallback
|
||||||
|
Object doOther(Object o) {
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,6 @@
|
|||||||
package org.enso.interpreter.node.expression.builtin.interop.syntax;
|
package org.enso.interpreter.node.expression.builtin.interop.syntax;
|
||||||
|
|
||||||
import com.oracle.truffle.api.dsl.Cached;
|
import com.oracle.truffle.api.dsl.*;
|
||||||
import com.oracle.truffle.api.dsl.Bind;
|
|
||||||
import com.oracle.truffle.api.dsl.ReportPolymorphism;
|
|
||||||
import com.oracle.truffle.api.dsl.Specialization;
|
|
||||||
import com.oracle.truffle.api.frame.VirtualFrame;
|
import com.oracle.truffle.api.frame.VirtualFrame;
|
||||||
import com.oracle.truffle.api.interop.*;
|
import com.oracle.truffle.api.interop.*;
|
||||||
import com.oracle.truffle.api.nodes.NodeInfo;
|
import com.oracle.truffle.api.nodes.NodeInfo;
|
||||||
@ -17,6 +14,7 @@ import org.enso.interpreter.runtime.callable.UnresolvedSymbol;
|
|||||||
import org.enso.interpreter.runtime.callable.argument.CallArgumentInfo;
|
import org.enso.interpreter.runtime.callable.argument.CallArgumentInfo;
|
||||||
import org.enso.interpreter.runtime.callable.function.Function;
|
import org.enso.interpreter.runtime.callable.function.Function;
|
||||||
import org.enso.interpreter.runtime.error.PanicException;
|
import org.enso.interpreter.runtime.error.PanicException;
|
||||||
|
import org.enso.interpreter.runtime.scope.ModuleScope;
|
||||||
import org.enso.interpreter.runtime.state.Stateful;
|
import org.enso.interpreter.runtime.state.Stateful;
|
||||||
import org.enso.interpreter.runtime.type.TypesGen;
|
import org.enso.interpreter.runtime.type.TypesGen;
|
||||||
|
|
||||||
@ -29,6 +27,7 @@ public abstract class MethodDispatchNode extends BuiltinRootNode {
|
|||||||
|
|
||||||
private @Child InteropLibrary library =
|
private @Child InteropLibrary library =
|
||||||
InteropLibrary.getFactory().createDispatched(Constants.CacheSizes.BUILTIN_INTEROP_DISPATCH);
|
InteropLibrary.getFactory().createDispatched(Constants.CacheSizes.BUILTIN_INTEROP_DISPATCH);
|
||||||
|
private @Child HostValueToEnsoNode hostValueToEnsoNode = HostValueToEnsoNode.build();
|
||||||
private final BranchProfile err = BranchProfile.create();
|
private final BranchProfile err = BranchProfile.create();
|
||||||
|
|
||||||
private @Child InvokeCallableNode invokeCallableNode =
|
private @Child InvokeCallableNode invokeCallableNode =
|
||||||
@ -53,12 +52,12 @@ public abstract class MethodDispatchNode extends BuiltinRootNode {
|
|||||||
* @param frame current execution frame.
|
* @param frame current execution frame.
|
||||||
* @return the result of converting input into a string.
|
* @return the result of converting input into a string.
|
||||||
*/
|
*/
|
||||||
@Specialization(guards = "symbol == cachedSymbol")
|
@Specialization(guards = "symbol.getScope() == cachedScope")
|
||||||
public Stateful run(
|
public Stateful run(
|
||||||
VirtualFrame frame,
|
VirtualFrame frame,
|
||||||
@Bind("getSymbol(frame)") UnresolvedSymbol symbol,
|
@Bind("getSymbol(frame)") UnresolvedSymbol symbol,
|
||||||
@Cached("symbol") UnresolvedSymbol cachedSymbol,
|
@Cached("symbol.getScope()") ModuleScope cachedScope,
|
||||||
@Cached("buildToArray(cachedSymbol)") UnresolvedSymbol toArray) {
|
@Cached("buildToArray(cachedScope)") UnresolvedSymbol toArray) {
|
||||||
Object[] args = Function.ArgumentsHelper.getPositionalArguments(frame.getArguments());
|
Object[] args = Function.ArgumentsHelper.getPositionalArguments(frame.getArguments());
|
||||||
Object callable = args[0];
|
Object callable = args[0];
|
||||||
Object state = Function.ArgumentsHelper.getState(frame.getArguments());
|
Object state = Function.ArgumentsHelper.getState(frame.getArguments());
|
||||||
@ -66,7 +65,8 @@ public abstract class MethodDispatchNode extends BuiltinRootNode {
|
|||||||
Stateful casted = invokeCallableNode.execute(toArray, frame, state, new Object[] {arguments});
|
Stateful casted = invokeCallableNode.execute(toArray, frame, state, new Object[] {arguments});
|
||||||
try {
|
try {
|
||||||
Object[] castedArgs = TypesGen.expectArray(casted.getValue()).getItems();
|
Object[] castedArgs = TypesGen.expectArray(casted.getValue()).getItems();
|
||||||
Object res = library.invokeMember(callable, symbol.getName(), castedArgs);
|
Object res =
|
||||||
|
hostValueToEnsoNode.execute(library.invokeMember(callable, symbol.getName(), castedArgs));
|
||||||
return new Stateful(casted.getState(), res);
|
return new Stateful(casted.getState(), res);
|
||||||
} catch (UnsupportedMessageException
|
} catch (UnsupportedMessageException
|
||||||
| ArityException
|
| ArityException
|
||||||
@ -78,8 +78,14 @@ public abstract class MethodDispatchNode extends BuiltinRootNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UnresolvedSymbol buildToArray(UnresolvedSymbol originalSymbol) {
|
@Specialization
|
||||||
return UnresolvedSymbol.build("to_array", originalSymbol.getScope());
|
public Stateful runUncached(VirtualFrame frame) {
|
||||||
|
UnresolvedSymbol sym = getSymbol(frame);
|
||||||
|
return run(frame, sym, sym.getScope(), buildToArray(sym.getScope()));
|
||||||
|
}
|
||||||
|
|
||||||
|
UnresolvedSymbol buildToArray(ModuleScope scope) {
|
||||||
|
return UnresolvedSymbol.build("to_array", scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
UnresolvedSymbol getSymbol(VirtualFrame frame) {
|
UnresolvedSymbol getSymbol(VirtualFrame frame) {
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
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.build();
|
||||||
|
|
||||||
|
Object execute(EnsoBigInteger _this) {
|
||||||
|
return toEnsoNumberNode.execute(BigIntegerOps.abs(_this.getValue()));
|
||||||
|
}
|
||||||
|
}
|
@ -29,6 +29,11 @@ public abstract class AddNode extends Node {
|
|||||||
return toEnsoNumberNode.execute(BigIntegerOps.add(_this.getValue(), that.getValue()));
|
return toEnsoNumberNode.execute(BigIntegerOps.add(_this.getValue(), that.getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
double doDouble(EnsoBigInteger _this, double that) {
|
||||||
|
return BigIntegerOps.toDouble(_this.getValue()) + that;
|
||||||
|
}
|
||||||
|
|
||||||
@Fallback
|
@Fallback
|
||||||
Object doOther(EnsoBigInteger _this, Object that) {
|
Object doOther(EnsoBigInteger _this, Object that) {
|
||||||
throw new TypeError("Unexpected type provided for argument `that` in Integer.+", this);
|
throw new TypeError("Unexpected type provided for argument `that` in Integer.+", this);
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
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.error.TypeError;
|
||||||
|
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||||
|
|
||||||
|
@BuiltinMethod(type = "Big_Integer", name = "div", description = "Big integer integral division.")
|
||||||
|
public abstract class DivNode extends Node {
|
||||||
|
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.build();
|
||||||
|
|
||||||
|
abstract Object execute(EnsoBigInteger _this, Object that);
|
||||||
|
|
||||||
|
static DivNode build() {
|
||||||
|
return DivNodeGen.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
Object doLong(EnsoBigInteger _this, long that) {
|
||||||
|
return toEnsoNumberNode.execute(BigIntegerOps.divide(_this.getValue(), that));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
Object doBigInteger(EnsoBigInteger _this, EnsoBigInteger that) {
|
||||||
|
return toEnsoNumberNode.execute(BigIntegerOps.divide(_this.getValue(), that.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Fallback
|
||||||
|
Object doOther(EnsoBigInteger _this, Object that) {
|
||||||
|
throw new TypeError("Unexpected type provided for argument `that` in Integer.div", this);
|
||||||
|
}
|
||||||
|
}
|
@ -5,32 +5,34 @@ import com.oracle.truffle.api.dsl.Specialization;
|
|||||||
import com.oracle.truffle.api.nodes.Node;
|
import com.oracle.truffle.api.nodes.Node;
|
||||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
|
||||||
import org.enso.interpreter.runtime.error.TypeError;
|
import org.enso.interpreter.runtime.error.TypeError;
|
||||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||||
|
|
||||||
@BuiltinMethod(type = "Big_Integer", name = "/", description = "Big integer division.")
|
@BuiltinMethod(type = "Big_Integer", name = "/", description = "Big integer division.")
|
||||||
public abstract class DivideNode extends Node {
|
public abstract class DivideNode extends Node {
|
||||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.build();
|
abstract double execute(EnsoBigInteger _this, Object that);
|
||||||
|
|
||||||
abstract Object execute(EnsoBigInteger _this, Object that);
|
|
||||||
|
|
||||||
static DivideNode build() {
|
static DivideNode build() {
|
||||||
return DivideNodeGen.create();
|
return DivideNodeGen.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Specialization
|
@Specialization
|
||||||
Object doLong(EnsoBigInteger _this, long that) {
|
double doBigInteger(EnsoBigInteger _this, EnsoBigInteger that) {
|
||||||
return toEnsoNumberNode.execute(BigIntegerOps.divide(_this.getValue(), that));
|
return BigIntegerOps.toDouble(_this.getValue()) / BigIntegerOps.toDouble(that.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Specialization
|
@Specialization
|
||||||
Object doBigInteger(EnsoBigInteger _this, EnsoBigInteger that) {
|
double doLong(EnsoBigInteger _this, long that) {
|
||||||
return toEnsoNumberNode.execute(BigIntegerOps.divide(_this.getValue(), that.getValue()));
|
return BigIntegerOps.toDouble(_this.getValue()) / that;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
double doDouble(EnsoBigInteger _this, double that) {
|
||||||
|
return BigIntegerOps.toDouble(_this.getValue()) / that;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Fallback
|
@Fallback
|
||||||
Object doOther(EnsoBigInteger _this, Object that) {
|
double doOther(EnsoBigInteger _this, Object that) {
|
||||||
throw new TypeError("Unexpected type provided for argument `that` in Integer./", this);
|
throw new TypeError("Unexpected type provided for argument `that` in Integer./", this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,11 @@ public abstract class EqualsNode extends Node {
|
|||||||
return BigIntegerOps.equals(_this.getValue(), that.getValue());
|
return BigIntegerOps.equals(_this.getValue(), that.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doDouble(EnsoBigInteger _this, double that) {
|
||||||
|
return BigIntegerOps.toDouble(_this.getValue()) == that;
|
||||||
|
}
|
||||||
|
|
||||||
@Fallback
|
@Fallback
|
||||||
boolean doOther(EnsoBigInteger _this, Object that) {
|
boolean doOther(EnsoBigInteger _this, Object that) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
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.runtime.error.TypeError;
|
||||||
|
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||||
|
|
||||||
|
@BuiltinMethod(type = "Big_Integer", name = ">", description = "Comparison of numbers.")
|
||||||
|
public abstract class GreaterNode extends Node {
|
||||||
|
|
||||||
|
abstract boolean execute(EnsoBigInteger _this, Object that);
|
||||||
|
|
||||||
|
static GreaterNode build() {
|
||||||
|
return GreaterNodeGen.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doDouble(EnsoBigInteger _this, double that) {
|
||||||
|
return BigIntegerOps.toDouble(_this.getValue()) > that;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doLong(EnsoBigInteger _this, long that) {
|
||||||
|
return _this.getValue().signum() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doBigInteger(EnsoBigInteger _this, EnsoBigInteger that) {
|
||||||
|
return BigIntegerOps.compare(_this.getValue(), that.getValue()) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Fallback
|
||||||
|
boolean doOther(EnsoBigInteger _this, Object that) {
|
||||||
|
throw new TypeError("Unexpected type provided for argument `that` in Integer.>", this);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
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.runtime.error.TypeError;
|
||||||
|
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||||
|
|
||||||
|
@BuiltinMethod(type = "Big_Integer", name = ">=", description = "Comparison of numbers.")
|
||||||
|
public abstract class GreaterOrEqualNode extends Node {
|
||||||
|
|
||||||
|
abstract boolean execute(EnsoBigInteger _this, Object that);
|
||||||
|
|
||||||
|
static GreaterOrEqualNode build() {
|
||||||
|
return GreaterOrEqualNodeGen.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doDouble(EnsoBigInteger _this, double that) {
|
||||||
|
return BigIntegerOps.toDouble(_this.getValue()) >= that;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doLong(EnsoBigInteger _this, long that) {
|
||||||
|
return _this.getValue().signum() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doBigInteger(EnsoBigInteger _this, EnsoBigInteger that) {
|
||||||
|
return BigIntegerOps.compare(_this.getValue(), that.getValue()) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Fallback
|
||||||
|
boolean doOther(EnsoBigInteger _this, Object that) {
|
||||||
|
throw new TypeError("Unexpected type provided for argument `that` in Integer.>=", this);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
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.runtime.error.TypeError;
|
||||||
|
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||||
|
|
||||||
|
@BuiltinMethod(type = "Big_Integer", name = "<", description = "Comparison of numbers.")
|
||||||
|
public abstract class LessNode extends Node {
|
||||||
|
|
||||||
|
abstract boolean execute(EnsoBigInteger _this, Object that);
|
||||||
|
|
||||||
|
static LessNode build() {
|
||||||
|
return LessNodeGen.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doDouble(EnsoBigInteger _this, double that) {
|
||||||
|
return BigIntegerOps.toDouble(_this.getValue()) < that;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doLong(EnsoBigInteger _this, long that) {
|
||||||
|
return _this.getValue().signum() < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doBigInteger(EnsoBigInteger _this, EnsoBigInteger that) {
|
||||||
|
return BigIntegerOps.compare(_this.getValue(), that.getValue()) < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Fallback
|
||||||
|
boolean doOther(EnsoBigInteger _this, Object that) {
|
||||||
|
throw new TypeError("Unexpected type provided for argument `that` in Integer.<", this);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
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.runtime.error.TypeError;
|
||||||
|
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||||
|
|
||||||
|
@BuiltinMethod(type = "Big_Integer", name = "<=", description = "Comparison of numbers.")
|
||||||
|
public abstract class LessOrEqualNode extends Node {
|
||||||
|
|
||||||
|
abstract boolean execute(EnsoBigInteger _this, Object that);
|
||||||
|
|
||||||
|
static LessOrEqualNode build() {
|
||||||
|
return LessOrEqualNodeGen.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doDouble(EnsoBigInteger _this, double that) {
|
||||||
|
return BigIntegerOps.toDouble(_this.getValue()) <= that;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doLong(EnsoBigInteger _this, long that) {
|
||||||
|
return _this.getValue().signum() < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doBigInteger(EnsoBigInteger _this, EnsoBigInteger that) {
|
||||||
|
return BigIntegerOps.compare(_this.getValue(), that.getValue()) <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Fallback
|
||||||
|
boolean doOther(EnsoBigInteger _this, Object that) {
|
||||||
|
throw new TypeError("Unexpected type provided for argument `that` in Integer.<=", this);
|
||||||
|
}
|
||||||
|
}
|
@ -13,9 +13,9 @@ import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
|||||||
public abstract class MultiplyNode extends Node {
|
public abstract class MultiplyNode extends Node {
|
||||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.build();
|
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.build();
|
||||||
|
|
||||||
abstract Object execute(EnsoBigInteger _this, Object that);
|
public abstract Object execute(EnsoBigInteger _this, Object that);
|
||||||
|
|
||||||
static MultiplyNode build() {
|
public static MultiplyNode build() {
|
||||||
return MultiplyNodeGen.create();
|
return MultiplyNodeGen.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,6 +29,11 @@ public abstract class MultiplyNode extends Node {
|
|||||||
return toEnsoNumberNode.execute(BigIntegerOps.multiply(_this.getValue(), that.getValue()));
|
return toEnsoNumberNode.execute(BigIntegerOps.multiply(_this.getValue(), that.getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
double doDouble(EnsoBigInteger _this, double that) {
|
||||||
|
return BigIntegerOps.toDouble(_this.getValue()) * that;
|
||||||
|
}
|
||||||
|
|
||||||
@Fallback
|
@Fallback
|
||||||
Object doOther(EnsoBigInteger _this, Object that) {
|
Object doOther(EnsoBigInteger _this, Object that) {
|
||||||
throw new TypeError("Unexpected type provided for argument `that` in Integer.*", this);
|
throw new TypeError("Unexpected type provided for argument `that` in Integer.*", this);
|
||||||
|
@ -0,0 +1,54 @@
|
|||||||
|
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.error.TypeError;
|
||||||
|
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||||
|
|
||||||
|
@BuiltinMethod(type = "Big_Integer", name = "^", description = "Big integer exponentiation.")
|
||||||
|
public abstract class PowNode extends Node {
|
||||||
|
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.build();
|
||||||
|
|
||||||
|
public abstract Object execute(EnsoBigInteger _this, Object that);
|
||||||
|
|
||||||
|
public static PowNode build() {
|
||||||
|
return PowNodeGen.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
Object doLong(EnsoBigInteger _this, long that) {
|
||||||
|
if (that == 0) {
|
||||||
|
return 1L;
|
||||||
|
} else if (that > 0) {
|
||||||
|
return toEnsoNumberNode.execute(BigIntegerOps.pow(_this.getValue(), that));
|
||||||
|
} else {
|
||||||
|
return Math.pow(BigIntegerOps.toDouble(_this.getValue()), that);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
Object doBigInteger(EnsoBigInteger _this, EnsoBigInteger that) {
|
||||||
|
if (that.getValue().signum() > 0) {
|
||||||
|
return Math.pow(
|
||||||
|
BigIntegerOps.toDouble(_this.getValue()), BigIntegerOps.toDouble(that.getValue()));
|
||||||
|
} else if (that.getValue().signum() == 0) {
|
||||||
|
return 1.0D;
|
||||||
|
} else {
|
||||||
|
return 0.0D;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
double doDouble(EnsoBigInteger _this, double that) {
|
||||||
|
return Math.pow(BigIntegerOps.toDouble(_this.getValue()), that);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Fallback
|
||||||
|
Object doOther(EnsoBigInteger _this, Object that) {
|
||||||
|
throw new TypeError("Unexpected type provided for argument `that` in Integer.^", this);
|
||||||
|
}
|
||||||
|
}
|
@ -29,6 +29,11 @@ public abstract class SubtractNode extends Node {
|
|||||||
return toEnsoNumberNode.execute(BigIntegerOps.subtract(_this.getValue(), that.getValue()));
|
return toEnsoNumberNode.execute(BigIntegerOps.subtract(_this.getValue(), that.getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
double doDouble(EnsoBigInteger _this, double that) {
|
||||||
|
return BigIntegerOps.toDouble(_this.getValue()) - that;
|
||||||
|
}
|
||||||
|
|
||||||
@Fallback
|
@Fallback
|
||||||
Object doOther(EnsoBigInteger _this, Object that) {
|
Object doOther(EnsoBigInteger _this, Object that) {
|
||||||
throw new TypeError("Unexpected type provided for argument `that` in Integer.-", this);
|
throw new TypeError("Unexpected type provided for argument `that` in Integer.-", this);
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
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 _this) {
|
||||||
|
return BigIntegerOps.toDouble(_this.getValue());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package org.enso.interpreter.node.expression.builtin.number.decimal;
|
||||||
|
|
||||||
|
import com.oracle.truffle.api.nodes.Node;
|
||||||
|
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||||
|
|
||||||
|
@BuiltinMethod(type = "Decimal", name = "abs", description = "Absolute value of a number.")
|
||||||
|
public class AbsNode extends Node {
|
||||||
|
double execute(double _this) {
|
||||||
|
return Math.abs(_this);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package org.enso.interpreter.node.expression.builtin.number.decimal;
|
||||||
|
|
||||||
|
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.error.TypeError;
|
||||||
|
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||||
|
|
||||||
|
@BuiltinMethod(type = "Decimal", name = "+", description = "Addition of numbers.")
|
||||||
|
public abstract class AddNode extends Node {
|
||||||
|
abstract double execute(double _this, Object that);
|
||||||
|
|
||||||
|
static AddNode build() {
|
||||||
|
return AddNodeGen.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
double doDouble(double _this, double that) {
|
||||||
|
return _this + that;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
double doLong(double _this, long that) {
|
||||||
|
return _this + that;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
double doBigInteger(double _this, EnsoBigInteger that) {
|
||||||
|
return _this + BigIntegerOps.toDouble(that.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Fallback
|
||||||
|
double doOther(double _this, Object that) {
|
||||||
|
throw new TypeError("Unexpected type provided for argument `that` in Decimal.+", this);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package org.enso.interpreter.node.expression.builtin.number.decimal;
|
||||||
|
|
||||||
|
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.error.TypeError;
|
||||||
|
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||||
|
|
||||||
|
@BuiltinMethod(type = "Decimal", name = "/", description = "Division of numbers.")
|
||||||
|
public abstract class DivideNode extends Node {
|
||||||
|
abstract double execute(double _this, Object that);
|
||||||
|
|
||||||
|
static DivideNode build() {
|
||||||
|
return DivideNodeGen.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
double doDouble(double _this, double that) {
|
||||||
|
return _this / that;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
double doLong(double _this, long that) {
|
||||||
|
return _this / that;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
double doBigInteger(double _this, EnsoBigInteger that) {
|
||||||
|
return _this / BigIntegerOps.toDouble(that.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Fallback
|
||||||
|
double doOther(double _this, Object that) {
|
||||||
|
throw new TypeError("Unexpected type provided for argument `that` in Decimal./", this);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package org.enso.interpreter.node.expression.builtin.number.decimal;
|
||||||
|
|
||||||
|
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 = "Decimal", name = "==", description = "Equality on numbers.")
|
||||||
|
public abstract class EqualsNode extends Node {
|
||||||
|
|
||||||
|
abstract boolean execute(double _this, Object that);
|
||||||
|
|
||||||
|
static EqualsNode build() {
|
||||||
|
return EqualsNodeGen.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doDouble(double _this, double that) {
|
||||||
|
return _this == that;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doLong(double _this, long that) {
|
||||||
|
return _this == (double) that;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doBigInteger(double _this, EnsoBigInteger that) {
|
||||||
|
return _this == BigIntegerOps.toDouble(that.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Fallback
|
||||||
|
boolean doOther(double _this, Object that) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package org.enso.interpreter.node.expression.builtin.number.decimal;
|
||||||
|
|
||||||
|
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.error.TypeError;
|
||||||
|
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||||
|
|
||||||
|
@BuiltinMethod(type = "Decimal", name = ">", description = "Comparison of numbers.")
|
||||||
|
public abstract class GreaterNode extends Node {
|
||||||
|
|
||||||
|
abstract boolean execute(double _this, Object that);
|
||||||
|
|
||||||
|
static GreaterNode build() {
|
||||||
|
return GreaterNodeGen.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doDouble(double _this, double that) {
|
||||||
|
return _this > that;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doLong(double _this, long that) {
|
||||||
|
return _this > (double) that;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doBigInteger(double _this, EnsoBigInteger that) {
|
||||||
|
return _this > BigIntegerOps.toDouble(that.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Fallback
|
||||||
|
boolean doOther(double _this, Object that) {
|
||||||
|
throw new TypeError("Unexpected type provided for argument `that` in Decimal.>", this);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package org.enso.interpreter.node.expression.builtin.number.decimal;
|
||||||
|
|
||||||
|
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.error.TypeError;
|
||||||
|
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||||
|
|
||||||
|
@BuiltinMethod(type = "Decimal", name = ">=", description = "Comparison of numbers.")
|
||||||
|
public abstract class GreaterOrEqualNode extends Node {
|
||||||
|
|
||||||
|
abstract boolean execute(double _this, Object that);
|
||||||
|
|
||||||
|
static GreaterOrEqualNode build() {
|
||||||
|
return GreaterOrEqualNodeGen.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doDouble(double _this, double that) {
|
||||||
|
return _this >= that;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doLong(double _this, long that) {
|
||||||
|
return _this >= (double) that;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doBigInteger(double _this, EnsoBigInteger that) {
|
||||||
|
return _this >= BigIntegerOps.toDouble(that.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Fallback
|
||||||
|
boolean doOther(double _this, Object that) {
|
||||||
|
throw new TypeError("Unexpected type provided for argument `that` in Decimal.>=", this);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package org.enso.interpreter.node.expression.builtin.number.decimal;
|
||||||
|
|
||||||
|
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.error.TypeError;
|
||||||
|
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||||
|
|
||||||
|
@BuiltinMethod(type = "Decimal", name = "<", description = "Comparison of numbers.")
|
||||||
|
public abstract class LessNode extends Node {
|
||||||
|
|
||||||
|
abstract boolean execute(double _this, Object that);
|
||||||
|
|
||||||
|
static LessNode build() {
|
||||||
|
return LessNodeGen.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doDouble(double _this, double that) {
|
||||||
|
return _this < that;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doLong(double _this, long that) {
|
||||||
|
return _this < (double) that;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doBigInteger(double _this, EnsoBigInteger that) {
|
||||||
|
return _this < BigIntegerOps.toDouble(that.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Fallback
|
||||||
|
boolean doOther(double _this, Object that) {
|
||||||
|
throw new TypeError("Unexpected type provided for argument `that` in Decimal.<", this);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package org.enso.interpreter.node.expression.builtin.number.decimal;
|
||||||
|
|
||||||
|
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.error.TypeError;
|
||||||
|
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||||
|
|
||||||
|
@BuiltinMethod(type = "Decimal", name = "<=", description = "Comparison of numbers.")
|
||||||
|
public abstract class LessOrEqualNode extends Node {
|
||||||
|
|
||||||
|
abstract boolean execute(double _this, Object that);
|
||||||
|
|
||||||
|
static LessOrEqualNode build() {
|
||||||
|
return LessOrEqualNodeGen.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doDouble(double _this, double that) {
|
||||||
|
return _this <= that;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doLong(double _this, long that) {
|
||||||
|
return _this <= (double) that;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doBigInteger(double _this, EnsoBigInteger that) {
|
||||||
|
return _this <= BigIntegerOps.toDouble(that.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Fallback
|
||||||
|
boolean doOther(double _this, Object that) {
|
||||||
|
throw new TypeError("Unexpected type provided for argument `that` in Decimal.<=", this);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package org.enso.interpreter.node.expression.builtin.number.decimal;
|
||||||
|
|
||||||
|
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.error.TypeError;
|
||||||
|
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||||
|
|
||||||
|
@BuiltinMethod(type = "Decimal", name = "*", description = "Multiplication of numbers.")
|
||||||
|
public abstract class MultiplyNode extends Node {
|
||||||
|
abstract double execute(double _this, Object that);
|
||||||
|
|
||||||
|
static MultiplyNode build() {
|
||||||
|
return MultiplyNodeGen.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
double doDouble(double _this, double that) { return _this * that;}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
double doLong(double _this, long that) {
|
||||||
|
return _this * that;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
double doBigInteger(double _this, EnsoBigInteger that) {
|
||||||
|
return _this * BigIntegerOps.toDouble(that.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Fallback
|
||||||
|
double doOther(double _this, Object that) {
|
||||||
|
throw new TypeError("Unexpected type provided for argument `that` in Decimal.*", this);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package org.enso.interpreter.node.expression.builtin.number.decimal;
|
||||||
|
|
||||||
|
import com.oracle.truffle.api.nodes.Node;
|
||||||
|
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||||
|
|
||||||
|
@BuiltinMethod(type = "Decimal", name = "negate", description = "Negation for numbers.")
|
||||||
|
public class NegateNode extends Node {
|
||||||
|
double execute(double _this) {
|
||||||
|
return -_this;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package org.enso.interpreter.node.expression.builtin.number.decimal;
|
||||||
|
|
||||||
|
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.error.TypeError;
|
||||||
|
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||||
|
|
||||||
|
@BuiltinMethod(type = "Decimal", name = "^", description = "Exponentiation of numbers.")
|
||||||
|
public abstract class PowNode extends Node {
|
||||||
|
abstract double execute(double _this, Object that);
|
||||||
|
|
||||||
|
static PowNode build() {
|
||||||
|
return PowNodeGen.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
double doDouble(double _this, double that) {
|
||||||
|
return Math.pow(_this, that);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
double doLong(double _this, long that) {
|
||||||
|
return Math.pow(_this, that);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
double doBigInteger(double _this, EnsoBigInteger that) {
|
||||||
|
return Math.pow(_this, BigIntegerOps.toDouble(that.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Fallback
|
||||||
|
double doOther(double _this, Object that) {
|
||||||
|
throw new TypeError("Unexpected type provided for argument `that` in Decimal.^", this);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package org.enso.interpreter.node.expression.builtin.number.decimal;
|
||||||
|
|
||||||
|
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.error.TypeError;
|
||||||
|
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||||
|
|
||||||
|
@BuiltinMethod(type = "Decimal", name = "-", description = "Subtraction of numbers.")
|
||||||
|
public abstract class SubtractNode extends Node {
|
||||||
|
abstract double execute(double _this, Object that);
|
||||||
|
|
||||||
|
static SubtractNode build() {
|
||||||
|
return SubtractNodeGen.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
double doDouble(double _this, double that) {
|
||||||
|
return _this - that;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
double doLong(double _this, long that) {
|
||||||
|
return _this - that;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
double doBigInteger(double _this, EnsoBigInteger that) {
|
||||||
|
return _this - BigIntegerOps.toDouble(that.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Fallback
|
||||||
|
double doOther(double _this, Object that) {
|
||||||
|
throw new TypeError("Unexpected type provided for argument `that` in Decimal.-", this);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package org.enso.interpreter.node.expression.builtin.number.decimal;
|
||||||
|
|
||||||
|
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 = "Decimal",
|
||||||
|
name = "to_decimal",
|
||||||
|
description = "Identity on decimals")
|
||||||
|
public class ToDecimalNode extends Node {
|
||||||
|
double execute(double _this) {
|
||||||
|
return _this;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package org.enso.interpreter.node.expression.builtin.number.int64;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
@BuiltinMethod(type = "Small_Integer", name = "negate", description = "Negation for numbers.")
|
||||||
|
public abstract class AbsNode extends Node {
|
||||||
|
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.build();
|
||||||
|
|
||||||
|
static AbsNode build() {
|
||||||
|
return AbsNodeGen.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract Object execute(long _this);
|
||||||
|
|
||||||
|
@Specialization(rewriteOn = ArithmeticException.class)
|
||||||
|
long doNormal(long _this) {
|
||||||
|
if (_this < 0) {
|
||||||
|
return Math.negateExact(_this);
|
||||||
|
} else {
|
||||||
|
return _this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
Object doOverflow(long _this) {
|
||||||
|
return toEnsoNumberNode.execute(BigIntegerOps.abs(_this));
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,7 @@ import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNod
|
|||||||
import org.enso.interpreter.runtime.error.TypeError;
|
import org.enso.interpreter.runtime.error.TypeError;
|
||||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||||
|
|
||||||
@BuiltinMethod(type = "Int_64", name = "+", description = "Addition of numbers.")
|
@BuiltinMethod(type = "Small_Integer", name = "+", description = "Addition of numbers.")
|
||||||
public abstract class AddNode extends Node {
|
public abstract class AddNode extends Node {
|
||||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.build();
|
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.build();
|
||||||
|
|
||||||
@ -29,6 +29,11 @@ public abstract class AddNode extends Node {
|
|||||||
return toEnsoNumberNode.execute(BigIntegerOps.add(_this, that));
|
return toEnsoNumberNode.execute(BigIntegerOps.add(_this, that));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
double doDouble(long _this, double that) {
|
||||||
|
return _this + that;
|
||||||
|
}
|
||||||
|
|
||||||
@Specialization
|
@Specialization
|
||||||
Object doBigInteger(long _this, EnsoBigInteger that) {
|
Object doBigInteger(long _this, EnsoBigInteger that) {
|
||||||
return toEnsoNumberNode.execute(BigIntegerOps.add(that.getValue(), _this));
|
return toEnsoNumberNode.execute(BigIntegerOps.add(that.getValue(), _this));
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
package org.enso.interpreter.node.expression.builtin.number.int64;
|
||||||
|
|
||||||
|
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.error.TypeError;
|
||||||
|
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 _this, Object that);
|
||||||
|
|
||||||
|
static DivNode build() {
|
||||||
|
return DivNodeGen.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
long doLong(long _this, long that) {
|
||||||
|
return _this / that;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
long doBigInteger(long _this, EnsoBigInteger that) {
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Fallback
|
||||||
|
Object doOther(long _this, Object that) {
|
||||||
|
throw new TypeError("Unexpected type provided for argument `that` in Integer.div", this);
|
||||||
|
}
|
||||||
|
}
|
@ -4,29 +4,35 @@ import com.oracle.truffle.api.dsl.Fallback;
|
|||||||
import com.oracle.truffle.api.dsl.Specialization;
|
import com.oracle.truffle.api.dsl.Specialization;
|
||||||
import com.oracle.truffle.api.nodes.Node;
|
import com.oracle.truffle.api.nodes.Node;
|
||||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||||
|
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||||
import org.enso.interpreter.runtime.error.TypeError;
|
import org.enso.interpreter.runtime.error.TypeError;
|
||||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||||
|
|
||||||
@BuiltinMethod(type = "Int_64", name = "/", description = "Division of numbers.")
|
@BuiltinMethod(type = "Small_Integer", name = "/", description = "Division of numbers.")
|
||||||
public abstract class DivideNode extends Node {
|
public abstract class DivideNode extends Node {
|
||||||
abstract Object execute(long _this, Object that);
|
abstract double execute(long _this, Object that);
|
||||||
|
|
||||||
static DivideNode build() {
|
static DivideNode build() {
|
||||||
return DivideNodeGen.create();
|
return DivideNodeGen.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Specialization
|
@Specialization
|
||||||
long doLong(long _this, long that) {
|
double doLong(long _this, long that) {
|
||||||
|
return ((double) _this) / ((double) that);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
double doDouble(long _this, double that) {
|
||||||
return _this / that;
|
return _this / that;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Specialization
|
@Specialization
|
||||||
long doBigInteger(long _this, EnsoBigInteger that) {
|
double doBigInteger(long _this, EnsoBigInteger that) {
|
||||||
return 0L;
|
return ((double) _this) / BigIntegerOps.toDouble(that.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Fallback
|
@Fallback
|
||||||
Object doOther(long _this, Object that) {
|
double doOther(long _this, Object that) {
|
||||||
throw new TypeError("Unexpected type provided for argument `that` in Integer./", this);
|
throw new TypeError("Unexpected type provided for argument `that` in Integer./", this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import com.oracle.truffle.api.dsl.Specialization;
|
|||||||
import com.oracle.truffle.api.nodes.Node;
|
import com.oracle.truffle.api.nodes.Node;
|
||||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||||
|
|
||||||
@BuiltinMethod(type = "Int_64", name = "==", description = "Equality on numbers.")
|
@BuiltinMethod(type = "Small_Integer", name = "==", description = "Equality on numbers.")
|
||||||
public abstract class EqualsNode extends Node {
|
public abstract class EqualsNode extends Node {
|
||||||
|
|
||||||
abstract boolean execute(long _this, Object that);
|
abstract boolean execute(long _this, Object that);
|
||||||
@ -19,6 +19,11 @@ public abstract class EqualsNode extends Node {
|
|||||||
return _this == that;
|
return _this == that;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doDouble(long _this, double that) {
|
||||||
|
return (double) _this == that;
|
||||||
|
}
|
||||||
|
|
||||||
@Fallback
|
@Fallback
|
||||||
boolean doOther(long _this, Object that) {
|
boolean doOther(long _this, Object that) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
package org.enso.interpreter.node.expression.builtin.number.int64;
|
||||||
|
|
||||||
|
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.error.TypeError;
|
||||||
|
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||||
|
|
||||||
|
@BuiltinMethod(type = "Small_Integer", name = ">", description = "Comparison of numbers.")
|
||||||
|
public abstract class GreaterNode extends Node {
|
||||||
|
|
||||||
|
abstract boolean execute(long _this, Object that);
|
||||||
|
|
||||||
|
static GreaterNode build() {
|
||||||
|
return GreaterNodeGen.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doLong(long _this, long that) {
|
||||||
|
return _this > that;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doDouble(long _this, double that) {
|
||||||
|
return (double) _this > that;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doBigInteger(long _this, EnsoBigInteger that) {
|
||||||
|
return that.getValue().signum() < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Fallback
|
||||||
|
boolean doOther(long _this, Object that) {
|
||||||
|
throw new TypeError("Unexpected type provided for argument `that` in Integer.>", this);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package org.enso.interpreter.node.expression.builtin.number.int64;
|
||||||
|
|
||||||
|
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.error.TypeError;
|
||||||
|
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||||
|
|
||||||
|
@BuiltinMethod(type = "Small_Integer", name = ">=", description = "Comparison of numbers.")
|
||||||
|
public abstract class GreaterOrEqualNode extends Node {
|
||||||
|
|
||||||
|
abstract boolean execute(long _this, Object that);
|
||||||
|
|
||||||
|
static GreaterOrEqualNode build() {
|
||||||
|
return GreaterOrEqualNodeGen.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doLong(long _this, long that) {
|
||||||
|
return _this >= that;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doDouble(long _this, double that) {
|
||||||
|
return (double) _this >= that;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doBigInteger(long _this, EnsoBigInteger that) {
|
||||||
|
return that.getValue().signum() < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Fallback
|
||||||
|
boolean doOther(long _this, Object that) {
|
||||||
|
throw new TypeError("Unexpected type provided for argument `that` in Integer.>=", this);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package org.enso.interpreter.node.expression.builtin.number.int64;
|
||||||
|
|
||||||
|
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.error.TypeError;
|
||||||
|
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||||
|
|
||||||
|
@BuiltinMethod(type = "Small_Integer", name = "<", description = "Comparison of numbers.")
|
||||||
|
public abstract class LessNode extends Node {
|
||||||
|
|
||||||
|
abstract boolean execute(long _this, Object that);
|
||||||
|
|
||||||
|
static LessNode build() {
|
||||||
|
return LessNodeGen.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doLong(long _this, long that) {
|
||||||
|
return _this < that;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doDouble(long _this, double that) {
|
||||||
|
return (double) _this < that;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doBigInteger(long _this, EnsoBigInteger that) {
|
||||||
|
return that.getValue().signum() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Fallback
|
||||||
|
boolean doOther(long _this, Object that) {
|
||||||
|
throw new TypeError("Unexpected type provided for argument `that` in Integer.<", this);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package org.enso.interpreter.node.expression.builtin.number.int64;
|
||||||
|
|
||||||
|
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.error.TypeError;
|
||||||
|
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||||
|
|
||||||
|
@BuiltinMethod(type = "Small_Integer", name = "<=", description = "Comparison of numbers.")
|
||||||
|
public abstract class LessOrEqualNode extends Node {
|
||||||
|
|
||||||
|
abstract boolean execute(long _this, Object that);
|
||||||
|
|
||||||
|
static LessOrEqualNode build() {
|
||||||
|
return LessOrEqualNodeGen.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doLong(long _this, long that) {
|
||||||
|
return _this <= that;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doDouble(long _this, double that) {
|
||||||
|
return (double) _this <= that;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
boolean doBigInteger(long _this, EnsoBigInteger that) {
|
||||||
|
return that.getValue().signum() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Fallback
|
||||||
|
boolean doOther(long _this, Object that) {
|
||||||
|
throw new TypeError("Unexpected type provided for argument `that` in Integer.<=", this);
|
||||||
|
}
|
||||||
|
}
|
@ -7,7 +7,7 @@ import org.enso.interpreter.dsl.BuiltinMethod;
|
|||||||
import org.enso.interpreter.runtime.error.TypeError;
|
import org.enso.interpreter.runtime.error.TypeError;
|
||||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||||
|
|
||||||
@BuiltinMethod(type = "Int_64", name = "%", description = "Modulo division of numbers.")
|
@BuiltinMethod(type = "Small_Integer", name = "%", description = "Modulo division of numbers.")
|
||||||
public abstract class ModNode extends Node {
|
public abstract class ModNode extends Node {
|
||||||
abstract Object execute(long _this, Object that);
|
abstract Object execute(long _this, Object that);
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNod
|
|||||||
import org.enso.interpreter.runtime.error.TypeError;
|
import org.enso.interpreter.runtime.error.TypeError;
|
||||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||||
|
|
||||||
@BuiltinMethod(type = "Int_64", name = "*", description = "Multiplication of numbers.")
|
@BuiltinMethod(type = "Small_Integer", name = "*", description = "Multiplication of numbers.")
|
||||||
public abstract class MultiplyNode extends Node {
|
public abstract class MultiplyNode extends Node {
|
||||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.build();
|
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.build();
|
||||||
|
|
||||||
@ -29,6 +29,11 @@ public abstract class MultiplyNode extends Node {
|
|||||||
return toEnsoNumberNode.execute(BigIntegerOps.multiply(_this, that));
|
return toEnsoNumberNode.execute(BigIntegerOps.multiply(_this, that));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
double doDouble(long _this, double that) {
|
||||||
|
return ((double) _this) * that;
|
||||||
|
}
|
||||||
|
|
||||||
@Specialization
|
@Specialization
|
||||||
Object doBigInteger(long _this, EnsoBigInteger that) {
|
Object doBigInteger(long _this, EnsoBigInteger that) {
|
||||||
return toEnsoNumberNode.execute(BigIntegerOps.multiply(that.getValue(), _this));
|
return toEnsoNumberNode.execute(BigIntegerOps.multiply(that.getValue(), _this));
|
||||||
|
@ -6,7 +6,7 @@ import org.enso.interpreter.dsl.BuiltinMethod;
|
|||||||
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps;
|
||||||
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
|
||||||
|
|
||||||
@BuiltinMethod(type = "Int_64", name = "negate", description = "Negation for numbers.")
|
@BuiltinMethod(type = "Small_Integer", name = "negate", description = "Negation for numbers.")
|
||||||
public abstract class NegateNode extends Node {
|
public abstract class NegateNode extends Node {
|
||||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.build();
|
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.build();
|
||||||
|
|
||||||
|
@ -0,0 +1,78 @@
|
|||||||
|
package org.enso.interpreter.node.expression.builtin.number.int64;
|
||||||
|
|
||||||
|
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.error.TypeError;
|
||||||
|
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||||
|
import org.enso.interpreter.runtime.type.TypesGen;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
@BuiltinMethod(type = "Small_Integer", name = "^", description = "Exponentation of numbers.")
|
||||||
|
public abstract class PowNode extends Node {
|
||||||
|
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.build();
|
||||||
|
private @Child org.enso.interpreter.node.expression.builtin.number.int64.MultiplyNode
|
||||||
|
longMultiplyNode =
|
||||||
|
org.enso.interpreter.node.expression.builtin.number.int64.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 _this, Object that);
|
||||||
|
|
||||||
|
static PowNode build() {
|
||||||
|
return PowNodeGen.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
Object doLong(long _this, long that) {
|
||||||
|
if (that < 0) {
|
||||||
|
return Math.pow(_this, that);
|
||||||
|
} else if (that == 0) {
|
||||||
|
return 1L;
|
||||||
|
} else {
|
||||||
|
Object res = 1L;
|
||||||
|
Object base = _this;
|
||||||
|
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 _this, double that) {
|
||||||
|
return Math.pow(_this, that);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
Object doBigInteger(long _this, EnsoBigInteger that) {
|
||||||
|
return bigIntPowNode.execute(new EnsoBigInteger(BigInteger.valueOf(_this)), that);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Fallback
|
||||||
|
Object doOther(long _this, Object that) {
|
||||||
|
throw new TypeError("Unexpected type provided for argument `that` in Integer.^", this);
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,7 @@ import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNod
|
|||||||
import org.enso.interpreter.runtime.error.TypeError;
|
import org.enso.interpreter.runtime.error.TypeError;
|
||||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||||
|
|
||||||
@BuiltinMethod(type = "Int_64", name = "-", description = "Subtraction of numbers.")
|
@BuiltinMethod(type = "Small_Integer", name = "-", description = "Subtraction of numbers.")
|
||||||
public abstract class SubtractNode extends Node {
|
public abstract class SubtractNode extends Node {
|
||||||
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.build();
|
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.build();
|
||||||
|
|
||||||
@ -29,6 +29,11 @@ public abstract class SubtractNode extends Node {
|
|||||||
return toEnsoNumberNode.execute(BigIntegerOps.subtract(_this, that));
|
return toEnsoNumberNode.execute(BigIntegerOps.subtract(_this, that));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Specialization
|
||||||
|
double doDouble(long _this, double that) {
|
||||||
|
return _this - that;
|
||||||
|
}
|
||||||
|
|
||||||
@Specialization
|
@Specialization
|
||||||
Object doBigInteger(long _this, EnsoBigInteger that) {
|
Object doBigInteger(long _this, EnsoBigInteger that) {
|
||||||
return toEnsoNumberNode.execute(BigIntegerOps.subtract(_this, that.getValue()));
|
return toEnsoNumberNode.execute(BigIntegerOps.subtract(_this, that.getValue()));
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
package org.enso.interpreter.node.expression.builtin.number.int64;
|
||||||
|
|
||||||
|
import com.oracle.truffle.api.nodes.Node;
|
||||||
|
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||||
|
|
||||||
|
@BuiltinMethod(
|
||||||
|
type = "Small_Int",
|
||||||
|
name = "to_decimal",
|
||||||
|
description = "Conversion of integers to decimals.")
|
||||||
|
public class ToDecimalNode extends Node {
|
||||||
|
double execute(long _this) {
|
||||||
|
return _this;
|
||||||
|
}
|
||||||
|
}
|
@ -86,8 +86,43 @@ public class BigIntegerOps {
|
|||||||
return BigInteger.valueOf(a).negate();
|
return BigInteger.valueOf(a).negate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@CompilerDirectives.TruffleBoundary
|
||||||
|
public static BigInteger abs(BigInteger a) {
|
||||||
|
return a.abs();
|
||||||
|
}
|
||||||
|
|
||||||
|
@CompilerDirectives.TruffleBoundary
|
||||||
|
public static BigInteger abs(long a) {
|
||||||
|
return BigInteger.valueOf(a).abs();
|
||||||
|
}
|
||||||
|
|
||||||
@CompilerDirectives.TruffleBoundary
|
@CompilerDirectives.TruffleBoundary
|
||||||
public static boolean equals(BigInteger a, BigInteger b) {
|
public static boolean equals(BigInteger a, BigInteger b) {
|
||||||
return a.equals(b);
|
return a.equals(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@CompilerDirectives.TruffleBoundary
|
||||||
|
public static double toDouble(BigInteger a) {
|
||||||
|
return a.doubleValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@CompilerDirectives.TruffleBoundary
|
||||||
|
public static int compare(BigInteger a, BigInteger b) {
|
||||||
|
return a.compareTo(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
@CompilerDirectives.TruffleBoundary
|
||||||
|
public static BigInteger pow(BigInteger a, long b) {
|
||||||
|
BigInteger res = BigInteger.valueOf(1);
|
||||||
|
while (b > 0) {
|
||||||
|
if (b % 2 == 0) {
|
||||||
|
a = a.pow(2);
|
||||||
|
b /= 2;
|
||||||
|
} else {
|
||||||
|
res = res.multiply(a);
|
||||||
|
b--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
package org.enso.interpreter.node.expression.literal;
|
||||||
|
|
||||||
|
import com.oracle.truffle.api.frame.VirtualFrame;
|
||||||
|
import com.oracle.truffle.api.nodes.NodeInfo;
|
||||||
|
import org.enso.interpreter.node.ExpressionNode;
|
||||||
|
|
||||||
|
/** A representation of decimal literals in Enso. */
|
||||||
|
@NodeInfo(description = "A decimal literal.")
|
||||||
|
public final class DecimalLiteralNode extends ExpressionNode {
|
||||||
|
private final double value;
|
||||||
|
|
||||||
|
private DecimalLiteralNode(double value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an instance of this node.
|
||||||
|
*
|
||||||
|
* @param value the value for the node to represent
|
||||||
|
* @return a node representing the literal given by {@code value}
|
||||||
|
*/
|
||||||
|
public static DecimalLiteralNode build(double value) {
|
||||||
|
return new DecimalLiteralNode(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the value of the literal.
|
||||||
|
*
|
||||||
|
* @param frame the stack frame for execution
|
||||||
|
* @return the value of the integer literal
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Object executeGeneric(VirtualFrame frame) {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,7 @@ public class Number {
|
|||||||
private final AtomConstructor bigInteger;
|
private final AtomConstructor bigInteger;
|
||||||
private final AtomConstructor integer;
|
private final AtomConstructor integer;
|
||||||
private final AtomConstructor number;
|
private final AtomConstructor number;
|
||||||
|
private final AtomConstructor decimal;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates and registers number builtins.
|
* Creates and registers number builtins.
|
||||||
@ -22,14 +23,17 @@ public class Number {
|
|||||||
smallInteger = new AtomConstructor("Small_Integer", scope).initializeFields();
|
smallInteger = new AtomConstructor("Small_Integer", scope).initializeFields();
|
||||||
integer = new AtomConstructor("Integer", scope).initializeFields();
|
integer = new AtomConstructor("Integer", scope).initializeFields();
|
||||||
bigInteger = new AtomConstructor("Big_Integer", scope).initializeFields();
|
bigInteger = new AtomConstructor("Big_Integer", scope).initializeFields();
|
||||||
|
decimal = new AtomConstructor("Decimal", scope).initializeFields();
|
||||||
|
|
||||||
registerInt64Methods(language, scope);
|
registerInt64Methods(language, scope);
|
||||||
registerBigIntegerMethods(language, scope);
|
registerBigIntegerMethods(language, scope);
|
||||||
|
registerDecimalMethods(language, scope);
|
||||||
|
|
||||||
scope.registerConstructor(number);
|
scope.registerConstructor(number);
|
||||||
scope.registerConstructor(smallInteger);
|
scope.registerConstructor(smallInteger);
|
||||||
scope.registerConstructor(integer);
|
scope.registerConstructor(integer);
|
||||||
scope.registerConstructor(bigInteger);
|
scope.registerConstructor(bigInteger);
|
||||||
|
scope.registerConstructor(decimal);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerInt64Methods(Language language, ModuleScope scope) {
|
private void registerInt64Methods(Language language, ModuleScope scope) {
|
||||||
@ -48,11 +52,21 @@ public class Number {
|
|||||||
"*",
|
"*",
|
||||||
org.enso.interpreter.node.expression.builtin.number.int64.MultiplyMethodGen.makeFunction(
|
org.enso.interpreter.node.expression.builtin.number.int64.MultiplyMethodGen.makeFunction(
|
||||||
language));
|
language));
|
||||||
|
scope.registerMethod(
|
||||||
|
smallInteger,
|
||||||
|
"^",
|
||||||
|
org.enso.interpreter.node.expression.builtin.number.int64.PowMethodGen.makeFunction(
|
||||||
|
language));
|
||||||
scope.registerMethod(
|
scope.registerMethod(
|
||||||
smallInteger,
|
smallInteger,
|
||||||
"/",
|
"/",
|
||||||
org.enso.interpreter.node.expression.builtin.number.int64.DivideMethodGen.makeFunction(
|
org.enso.interpreter.node.expression.builtin.number.int64.DivideMethodGen.makeFunction(
|
||||||
language));
|
language));
|
||||||
|
scope.registerMethod(
|
||||||
|
smallInteger,
|
||||||
|
"div",
|
||||||
|
org.enso.interpreter.node.expression.builtin.number.int64.DivMethodGen.makeFunction(
|
||||||
|
language));
|
||||||
scope.registerMethod(
|
scope.registerMethod(
|
||||||
smallInteger,
|
smallInteger,
|
||||||
"%",
|
"%",
|
||||||
@ -63,11 +77,41 @@ public class Number {
|
|||||||
"negate",
|
"negate",
|
||||||
org.enso.interpreter.node.expression.builtin.number.int64.NegateMethodGen.makeFunction(
|
org.enso.interpreter.node.expression.builtin.number.int64.NegateMethodGen.makeFunction(
|
||||||
language));
|
language));
|
||||||
|
scope.registerMethod(
|
||||||
|
smallInteger,
|
||||||
|
"abs",
|
||||||
|
org.enso.interpreter.node.expression.builtin.number.int64.AbsMethodGen.makeFunction(
|
||||||
|
language));
|
||||||
scope.registerMethod(
|
scope.registerMethod(
|
||||||
smallInteger,
|
smallInteger,
|
||||||
"==",
|
"==",
|
||||||
org.enso.interpreter.node.expression.builtin.number.int64.EqualsMethodGen.makeFunction(
|
org.enso.interpreter.node.expression.builtin.number.int64.EqualsMethodGen.makeFunction(
|
||||||
language));
|
language));
|
||||||
|
scope.registerMethod(
|
||||||
|
smallInteger,
|
||||||
|
">",
|
||||||
|
org.enso.interpreter.node.expression.builtin.number.int64.GreaterMethodGen.makeFunction(
|
||||||
|
language));
|
||||||
|
scope.registerMethod(
|
||||||
|
smallInteger,
|
||||||
|
">=",
|
||||||
|
org.enso.interpreter.node.expression.builtin.number.int64.GreaterOrEqualMethodGen
|
||||||
|
.makeFunction(language));
|
||||||
|
scope.registerMethod(
|
||||||
|
smallInteger,
|
||||||
|
"<",
|
||||||
|
org.enso.interpreter.node.expression.builtin.number.int64.LessMethodGen.makeFunction(
|
||||||
|
language));
|
||||||
|
scope.registerMethod(
|
||||||
|
smallInteger,
|
||||||
|
"<=",
|
||||||
|
org.enso.interpreter.node.expression.builtin.number.int64.LessOrEqualMethodGen.makeFunction(
|
||||||
|
language));
|
||||||
|
scope.registerMethod(
|
||||||
|
smallInteger,
|
||||||
|
"to_decimal",
|
||||||
|
org.enso.interpreter.node.expression.builtin.number.int64.ToDecimalMethodGen.makeFunction(
|
||||||
|
language));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerBigIntegerMethods(Language language, ModuleScope scope) {
|
private void registerBigIntegerMethods(Language language, ModuleScope scope) {
|
||||||
@ -87,11 +131,21 @@ public class Number {
|
|||||||
"*",
|
"*",
|
||||||
org.enso.interpreter.node.expression.builtin.number.bigInteger.MultiplyMethodGen
|
org.enso.interpreter.node.expression.builtin.number.bigInteger.MultiplyMethodGen
|
||||||
.makeFunction(language));
|
.makeFunction(language));
|
||||||
|
scope.registerMethod(
|
||||||
|
bigInteger,
|
||||||
|
"^",
|
||||||
|
org.enso.interpreter.node.expression.builtin.number.bigInteger.PowMethodGen.makeFunction(
|
||||||
|
language));
|
||||||
scope.registerMethod(
|
scope.registerMethod(
|
||||||
bigInteger,
|
bigInteger,
|
||||||
"/",
|
"/",
|
||||||
org.enso.interpreter.node.expression.builtin.number.bigInteger.DivideMethodGen.makeFunction(
|
org.enso.interpreter.node.expression.builtin.number.bigInteger.DivideMethodGen.makeFunction(
|
||||||
language));
|
language));
|
||||||
|
scope.registerMethod(
|
||||||
|
bigInteger,
|
||||||
|
"div",
|
||||||
|
org.enso.interpreter.node.expression.builtin.number.bigInteger.DivMethodGen.makeFunction(
|
||||||
|
language));
|
||||||
scope.registerMethod(
|
scope.registerMethod(
|
||||||
bigInteger,
|
bigInteger,
|
||||||
"%",
|
"%",
|
||||||
@ -102,11 +156,110 @@ public class Number {
|
|||||||
"negate",
|
"negate",
|
||||||
org.enso.interpreter.node.expression.builtin.number.bigInteger.NegateMethodGen.makeFunction(
|
org.enso.interpreter.node.expression.builtin.number.bigInteger.NegateMethodGen.makeFunction(
|
||||||
language));
|
language));
|
||||||
|
scope.registerMethod(
|
||||||
|
bigInteger,
|
||||||
|
"abs",
|
||||||
|
org.enso.interpreter.node.expression.builtin.number.bigInteger.AbsMethodGen.makeFunction(
|
||||||
|
language));
|
||||||
scope.registerMethod(
|
scope.registerMethod(
|
||||||
bigInteger,
|
bigInteger,
|
||||||
"==",
|
"==",
|
||||||
org.enso.interpreter.node.expression.builtin.number.bigInteger.EqualsMethodGen.makeFunction(
|
org.enso.interpreter.node.expression.builtin.number.bigInteger.EqualsMethodGen.makeFunction(
|
||||||
language));
|
language));
|
||||||
|
scope.registerMethod(
|
||||||
|
bigInteger,
|
||||||
|
">",
|
||||||
|
org.enso.interpreter.node.expression.builtin.number.bigInteger.GreaterMethodGen
|
||||||
|
.makeFunction(language));
|
||||||
|
scope.registerMethod(
|
||||||
|
bigInteger,
|
||||||
|
">=",
|
||||||
|
org.enso.interpreter.node.expression.builtin.number.bigInteger.GreaterOrEqualMethodGen
|
||||||
|
.makeFunction(language));
|
||||||
|
scope.registerMethod(
|
||||||
|
bigInteger,
|
||||||
|
"<",
|
||||||
|
org.enso.interpreter.node.expression.builtin.number.bigInteger.LessMethodGen.makeFunction(
|
||||||
|
language));
|
||||||
|
scope.registerMethod(
|
||||||
|
bigInteger,
|
||||||
|
"<=",
|
||||||
|
org.enso.interpreter.node.expression.builtin.number.bigInteger.LessOrEqualMethodGen
|
||||||
|
.makeFunction(language));
|
||||||
|
scope.registerMethod(
|
||||||
|
bigInteger,
|
||||||
|
"to_decimal",
|
||||||
|
org.enso.interpreter.node.expression.builtin.number.bigInteger.ToDecimalMethodGen
|
||||||
|
.makeFunction(language));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerDecimalMethods(Language language, ModuleScope scope) {
|
||||||
|
|
||||||
|
scope.registerMethod(
|
||||||
|
decimal,
|
||||||
|
"+",
|
||||||
|
org.enso.interpreter.node.expression.builtin.number.decimal.AddMethodGen.makeFunction(
|
||||||
|
language));
|
||||||
|
scope.registerMethod(
|
||||||
|
decimal,
|
||||||
|
"-",
|
||||||
|
org.enso.interpreter.node.expression.builtin.number.decimal.SubtractMethodGen.makeFunction(
|
||||||
|
language));
|
||||||
|
scope.registerMethod(
|
||||||
|
decimal,
|
||||||
|
"*",
|
||||||
|
org.enso.interpreter.node.expression.builtin.number.decimal.MultiplyMethodGen.makeFunction(
|
||||||
|
language));
|
||||||
|
scope.registerMethod(
|
||||||
|
decimal,
|
||||||
|
"^",
|
||||||
|
org.enso.interpreter.node.expression.builtin.number.decimal.PowMethodGen.makeFunction(
|
||||||
|
language));
|
||||||
|
scope.registerMethod(
|
||||||
|
decimal,
|
||||||
|
"/",
|
||||||
|
org.enso.interpreter.node.expression.builtin.number.decimal.DivideMethodGen.makeFunction(
|
||||||
|
language));
|
||||||
|
scope.registerMethod(
|
||||||
|
decimal,
|
||||||
|
"negate",
|
||||||
|
org.enso.interpreter.node.expression.builtin.number.decimal.NegateMethodGen.makeFunction(
|
||||||
|
language));
|
||||||
|
scope.registerMethod(
|
||||||
|
decimal,
|
||||||
|
"abs",
|
||||||
|
org.enso.interpreter.node.expression.builtin.number.decimal.AbsMethodGen.makeFunction(
|
||||||
|
language));
|
||||||
|
scope.registerMethod(
|
||||||
|
decimal,
|
||||||
|
"==",
|
||||||
|
org.enso.interpreter.node.expression.builtin.number.decimal.EqualsMethodGen.makeFunction(
|
||||||
|
language));
|
||||||
|
scope.registerMethod(
|
||||||
|
decimal,
|
||||||
|
">",
|
||||||
|
org.enso.interpreter.node.expression.builtin.number.decimal.GreaterMethodGen.makeFunction(
|
||||||
|
language));
|
||||||
|
scope.registerMethod(
|
||||||
|
decimal,
|
||||||
|
">=",
|
||||||
|
org.enso.interpreter.node.expression.builtin.number.decimal.GreaterOrEqualMethodGen
|
||||||
|
.makeFunction(language));
|
||||||
|
scope.registerMethod(
|
||||||
|
decimal,
|
||||||
|
"<",
|
||||||
|
org.enso.interpreter.node.expression.builtin.number.decimal.LessMethodGen.makeFunction(
|
||||||
|
language));
|
||||||
|
scope.registerMethod(
|
||||||
|
decimal,
|
||||||
|
"<=",
|
||||||
|
org.enso.interpreter.node.expression.builtin.number.decimal.LessOrEqualMethodGen
|
||||||
|
.makeFunction(language));
|
||||||
|
scope.registerMethod(
|
||||||
|
decimal,
|
||||||
|
"to_decimal",
|
||||||
|
org.enso.interpreter.node.expression.builtin.number.decimal.ToDecimalMethodGen.makeFunction(
|
||||||
|
language));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return the Int64 atom constructor. */
|
/** @return the Int64 atom constructor. */
|
||||||
@ -128,4 +281,9 @@ public class Number {
|
|||||||
public AtomConstructor getNumber() {
|
public AtomConstructor getNumber() {
|
||||||
return number;
|
return number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return the Decimal atom constructor */
|
||||||
|
public AtomConstructor getDecimal() {
|
||||||
|
return decimal;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package org.enso.interpreter.runtime.number;
|
package org.enso.interpreter.runtime.number;
|
||||||
|
|
||||||
|
import com.oracle.truffle.api.CompilerDirectives;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
|
||||||
/** Internal wrapper for a {@link BigInteger}. */
|
/** Internal wrapper for a {@link BigInteger}. */
|
||||||
@ -19,4 +21,10 @@ public class EnsoBigInteger {
|
|||||||
public BigInteger getValue() {
|
public BigInteger getValue() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@CompilerDirectives.TruffleBoundary
|
||||||
|
public String toString() {
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
|||||||
@TypeSystem({
|
@TypeSystem({
|
||||||
long.class,
|
long.class,
|
||||||
boolean.class,
|
boolean.class,
|
||||||
|
double.class,
|
||||||
String.class,
|
String.class,
|
||||||
Function.class,
|
Function.class,
|
||||||
Atom.class,
|
Atom.class,
|
||||||
|
@ -377,6 +377,8 @@ object AstToIr {
|
|||||||
allBranches,
|
allBranches,
|
||||||
getIdentifiedLocation(inputAst)
|
getIdentifiedLocation(inputAst)
|
||||||
)
|
)
|
||||||
|
case AstView.DecimalLiteral(intPart, fracPart) =>
|
||||||
|
translateDecimalLiteral(inputAst, intPart, fracPart)
|
||||||
case AST.App.any(inputAST) => translateApplicationLike(inputAST)
|
case AST.App.any(inputAST) => translateApplicationLike(inputAST)
|
||||||
case AST.Mixfix.any(inputAST) => translateApplicationLike(inputAST)
|
case AST.Mixfix.any(inputAST) => translateApplicationLike(inputAST)
|
||||||
case AST.Literal.any(inputAST) => translateLiteral(inputAST)
|
case AST.Literal.any(inputAST) => translateLiteral(inputAST)
|
||||||
@ -421,6 +423,26 @@ object AstToIr {
|
|||||||
* argument and cannot be performed any other way.
|
* argument and cannot be performed any other way.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
def translateDecimalLiteral(
|
||||||
|
ast: AST,
|
||||||
|
int: AST.Literal.Number,
|
||||||
|
frac: AST.Literal.Number
|
||||||
|
): Expression = {
|
||||||
|
if (int.base.isDefined && int.base.get != "10") {
|
||||||
|
Error.Syntax(
|
||||||
|
int,
|
||||||
|
Error.Syntax.UnsupportedSyntax("non-base-10 number literals")
|
||||||
|
)
|
||||||
|
} else if (frac.base.isDefined && frac.base.get != "10") {
|
||||||
|
Error.Syntax(frac, Error.Syntax.InvalidBaseInDecimalLiteral)
|
||||||
|
} else {
|
||||||
|
Literal.Number(
|
||||||
|
s"${int.shape.int}.${frac.shape.int}",
|
||||||
|
getIdentifiedLocation(ast)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Translates a program literal from its [[AST]] representation into
|
/** Translates a program literal from its [[AST]] representation into
|
||||||
* [[IR]].
|
* [[IR]].
|
||||||
*
|
*
|
||||||
|
@ -842,6 +842,19 @@ object AstView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object DecimalLiteral {
|
||||||
|
def unapply(ast: AST): Option[(AST.Literal.Number, AST.Literal.Number)] =
|
||||||
|
ast match {
|
||||||
|
case AST.App.Infix(
|
||||||
|
AST.Literal.Number.any(int),
|
||||||
|
AST.Ident.Opr("."),
|
||||||
|
AST.Literal.Number.any(frac)
|
||||||
|
) =>
|
||||||
|
Some((int, frac))
|
||||||
|
case _ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
object UnaryMinus {
|
object UnaryMinus {
|
||||||
def minusSymbol: String = "-"
|
def minusSymbol: String = "-"
|
||||||
|
|
||||||
|
@ -44,6 +44,7 @@ import org.enso.interpreter.node.expression.constant.{
|
|||||||
}
|
}
|
||||||
import org.enso.interpreter.node.expression.literal.{
|
import org.enso.interpreter.node.expression.literal.{
|
||||||
BigIntegerLiteralNode,
|
BigIntegerLiteralNode,
|
||||||
|
DecimalLiteralNode,
|
||||||
IntegerLiteralNode,
|
IntegerLiteralNode,
|
||||||
TextLiteralNode
|
TextLiteralNode
|
||||||
}
|
}
|
||||||
@ -859,10 +860,14 @@ class IrToTruffle(
|
|||||||
*/
|
*/
|
||||||
def processLiteral(literal: IR.Literal): RuntimeExpression =
|
def processLiteral(literal: IR.Literal): RuntimeExpression =
|
||||||
literal match {
|
literal match {
|
||||||
case IR.Literal.Number(value, location, _, _) =>
|
case lit @ IR.Literal.Number(value, location, _, _) =>
|
||||||
val node = value.toLongOption
|
val node = if (lit.isFractional) {
|
||||||
.map(IntegerLiteralNode.build)
|
DecimalLiteralNode.build(value.toDouble)
|
||||||
.getOrElse(BigIntegerLiteralNode.build(new BigInteger(value)))
|
} else {
|
||||||
|
value.toLongOption
|
||||||
|
.map(IntegerLiteralNode.build)
|
||||||
|
.getOrElse(BigIntegerLiteralNode.build(new BigInteger(value)))
|
||||||
|
}
|
||||||
setLocation(node, location)
|
setLocation(node, location)
|
||||||
case IR.Literal.Text(text, location, _, _) =>
|
case IR.Literal.Text(text, location, _, _) =>
|
||||||
setLocation(TextLiteralNode.build(text), location)
|
setLocation(TextLiteralNode.build(text), location)
|
||||||
|
@ -1581,6 +1581,13 @@ object IR {
|
|||||||
override def children: List[IR] = List()
|
override def children: List[IR] = List()
|
||||||
|
|
||||||
override def showCode(indent: Int): String = value
|
override def showCode(indent: Int): String = value
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the literal represents a fractional value.
|
||||||
|
*
|
||||||
|
* @return `true` if the value is fractional, `false` otherwise.
|
||||||
|
*/
|
||||||
|
def isFractional: Boolean = value.contains(".")
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A textual Enso literal.
|
/** A textual Enso literal.
|
||||||
@ -5563,6 +5570,11 @@ object IR {
|
|||||||
def explanation: String
|
def explanation: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case object InvalidBaseInDecimalLiteral extends Reason {
|
||||||
|
override def explanation: String =
|
||||||
|
"Cannot change base of the fractional part of a number literal."
|
||||||
|
}
|
||||||
|
|
||||||
case class UnsupportedSyntax(syntaxName: String) extends Reason {
|
case class UnsupportedSyntax(syntaxName: String) extends Reason {
|
||||||
override def explanation: String =
|
override def explanation: String =
|
||||||
s"Syntax is not supported yet: $syntaxName."
|
s"Syntax is not supported yet: $syntaxName."
|
||||||
|
@ -15,5 +15,7 @@ main =
|
|||||||
mil = 1000000
|
mil = 1000000
|
||||||
list = here.gen_list mil
|
list = here.gen_list mil
|
||||||
vec = Vector.new mil (ix -> ix + 1)
|
vec = Vector.new mil (ix -> ix + 1)
|
||||||
|
vec_decimal = Vector.new mil (ix -> ix + 0.0)
|
||||||
Bench_Utils.measure (vec.fold 0 (+)) "vector fold" 1000 10
|
Bench_Utils.measure (vec.fold 0 (+)) "vector fold" 1000 10
|
||||||
Bench_Utils.measure (list.fold 0 (+)) "list fold" 1000 10
|
Bench_Utils.measure (list.fold 0 (+)) "list fold" 1000 10
|
||||||
|
Bench_Utils.measure (vec_decimal.fold 0 (+)) "vector decimal fold" 1000 10
|
||||||
|
@ -12,6 +12,14 @@ sum_tco = sum_to ->
|
|||||||
res = summator 0 sum_to
|
res = summator 0 sum_to
|
||||||
res
|
res
|
||||||
|
|
||||||
|
sum_tco_decimal = sum_to ->
|
||||||
|
s = sum_to.to_decimal
|
||||||
|
summator = acc -> current ->
|
||||||
|
if current >= s then acc else summator acc+current current+1.0
|
||||||
|
res = summator 0.0 0.0
|
||||||
|
res
|
||||||
|
|
||||||
|
|
||||||
sum_tco_java = sum_to ->
|
sum_tco_java = sum_to ->
|
||||||
summator = acc -> current ->
|
summator = acc -> current ->
|
||||||
if current == 0 then acc else summator (Long.sum [acc, current]) (current - 1)
|
if current == 0 then acc else summator (Long.sum [acc, current]) (current - 1)
|
||||||
@ -40,8 +48,10 @@ sum_state = sum_to ->
|
|||||||
|
|
||||||
main =
|
main =
|
||||||
hundred_mil = 100000000
|
hundred_mil = 100000000
|
||||||
|
IO.println "Measuring Sum TCO Decimal"
|
||||||
|
Bench_Utils.measure (here.sum_tco_decimal hundred_mil) "sum_tco" 100 10
|
||||||
IO.println "Measuring SumTCO"
|
IO.println "Measuring SumTCO"
|
||||||
Bench_Utils.measure (here.sum_tco hundred_mil) "sum_tco" 500 10
|
Bench_Utils.measure (here.sum_tco hundred_mil) "sum_tco" 100 10
|
||||||
IO.println "Measuring SumTCO Java"
|
IO.println "Measuring SumTCO Java"
|
||||||
Bench_Utils.measure (here.sum_tco_java hundred_mil) "sum_tco" 100 10
|
Bench_Utils.measure (here.sum_tco_java hundred_mil) "sum_tco" 100 10
|
||||||
IO.println "Measuring State"
|
IO.println "Measuring State"
|
||||||
|
@ -2,7 +2,13 @@ from Base import all
|
|||||||
import Base.Test
|
import Base.Test
|
||||||
|
|
||||||
polyglot java import java.lang.Long
|
polyglot java import java.lang.Long
|
||||||
|
polyglot java import java.lang.Integer
|
||||||
|
polyglot java import java.lang.Float
|
||||||
|
|
||||||
spec = describe "Java FFI" <|
|
spec = describe "Java FFI" <|
|
||||||
it "should call methods imported from Java" <|
|
it "should call methods imported from Java" <|
|
||||||
Long.sum [1, 2] . should_equal 3
|
Long.sum [1, 2] . should_equal 3
|
||||||
|
it "should auto-convert numeric types across the polyglot boundary" <|
|
||||||
|
(Float.valueOf ["123.3"] + 5).should_equal 128.3 epsilon=0.0001
|
||||||
|
(Integer.sum [1, 2] + 3) . should_equal 6
|
||||||
|
|
||||||
|
@ -3,8 +3,10 @@ from Base import all
|
|||||||
import Base.Test
|
import Base.Test
|
||||||
|
|
||||||
Integer.is_even = this % 2 == 0
|
Integer.is_even = this % 2 == 0
|
||||||
|
Decimal.get_fun_factor = "Wow, " + this.to_text + " is such a fun number!"
|
||||||
|
|
||||||
spec =
|
spec =
|
||||||
|
eps = 0.000001
|
||||||
almost_max_long = 9223372036854775806
|
almost_max_long = 9223372036854775806
|
||||||
almost_max_long_times_three = 27670116110564327418
|
almost_max_long_times_three = 27670116110564327418
|
||||||
hundred_factorial = 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
|
hundred_factorial = 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
|
||||||
@ -17,7 +19,7 @@ spec =
|
|||||||
(0 - almost_max_long - almost_max_long - almost_max_long).should_equal almost_max_long_times_three.negate
|
(0 - almost_max_long - almost_max_long - almost_max_long).should_equal almost_max_long_times_three.negate
|
||||||
it "should be of unbound size when dividing" <|
|
it "should be of unbound size when dividing" <|
|
||||||
expected = 3372816184472482867110284450043137767873196479305249187406461598235841786750685581361224832688174410089430537516012695688121622150430744676
|
expected = 3372816184472482867110284450043137767873196479305249187406461598235841786750685581361224832688174410089430537516012695688121622150430744676
|
||||||
((1.upto 101 . fold 1 (*)) / 3*almost_max_long).should_equal expected
|
((1.upto 101 . fold 1 (*)).div 3*almost_max_long).should_equal expected
|
||||||
it "should be of unbound size when taking remainder" <|
|
it "should be of unbound size when taking remainder" <|
|
||||||
expected = 3191479909175673432
|
expected = 3191479909175673432
|
||||||
((1.upto 101 . fold 1 (*)) % 3*almost_max_long).should_equal expected
|
((1.upto 101 . fold 1 (*)) % 3*almost_max_long).should_equal expected
|
||||||
@ -34,4 +36,33 @@ spec =
|
|||||||
(hundred_factorial == 1).should_be_false
|
(hundred_factorial == 1).should_be_false
|
||||||
it "should properly handle going to big numbers and back" <|
|
it "should properly handle going to big numbers and back" <|
|
||||||
((almost_max_long * 3) / 3) . should_equal almost_max_long
|
((almost_max_long * 3) / 3) . should_equal almost_max_long
|
||||||
|
it "should use floating point arithmetic for division" <|
|
||||||
|
(3 / 4) . should_equal 0.75 epsilon=eps
|
||||||
|
(almost_max_long * 2 / almost_max_long_times_three) . should_equal 0.6666666 epsilon=eps
|
||||||
|
describe "Decimals" <|
|
||||||
|
it "should exist and expose basic arithmetic operations" <|
|
||||||
|
((1.5 + 1.5)*1.3 / 2 - 3) . should_equal -1.05 epsilon=eps
|
||||||
|
it "should allow defining extension methods through the Decimal type" <|
|
||||||
|
32.5.get_fun_factor.should_equal "Wow, 32.5 is such a fun number!"
|
||||||
|
describe "Numbers" <|
|
||||||
|
it "should expose comparison operators" <|
|
||||||
|
(3 < hundred_factorial).should_be_true
|
||||||
|
(hundred_factorial < 3).should_be_false
|
||||||
|
(3.0 < hundred_factorial).should_be_true
|
||||||
|
(3.0 <= 3.4).should_be_true
|
||||||
|
(3.0 >= 2).should_be_true
|
||||||
|
(-hundred_factorial > 0).should_be_false
|
||||||
|
it "should expose exponentiation operations" <|
|
||||||
|
(3.14 ^ 2.71).should_equal 22.216689546 epsilon=eps
|
||||||
|
(3.14 ^ 14).should_equal 9057640.36635 epsilon=eps
|
||||||
|
a = almost_max_long
|
||||||
|
(a ^ 4).should_equal (a * a * a * a)
|
||||||
|
(2 ^ 10).should_equal 1024
|
||||||
|
(2 ^ 0.5).should_equal 1.41421356237 epsilon=eps
|
||||||
|
(a^2)^0.5 . should_equal a epsilon=eps
|
||||||
|
it "should expose more involved mathematical functions" <|
|
||||||
|
Math.Pi.sin.should_equal 0 epsilon=eps
|
||||||
|
(Math.Pi / 4).sin.should_equal (2 ^ 0.5)/2 epsilon=eps
|
||||||
|
(Math.Pi / 6).cos.should_equal (3.sqrt / 2) epsilon=eps
|
||||||
|
(17 ^ 0.13).log base=17 . should_equal 0.13 epsilon=eps
|
||||||
|
0.exp.should_equal 1
|
||||||
|
Loading…
Reference in New Issue
Block a user