Warning for integer overflow

This commit is contained in:
Natalia Ukhorskaya
2013-11-27 10:42:36 +04:00
parent b4b7988eec
commit 9c176ddaa8
12 changed files with 630 additions and 419 deletions
@@ -465,6 +465,7 @@ public interface Errors {
// Compile-time values
DiagnosticFactory0<JetExpression> INTEGER_OVERFLOW = DiagnosticFactory0.create(WARNING);
DiagnosticFactory0<JetConstantExpression> INT_LITERAL_OUT_OF_RANGE = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<JetConstantExpression> FLOAT_LITERAL_OUT_OF_RANGE = DiagnosticFactory0.create(ERROR);
DiagnosticFactory2<JetConstantExpression, String, JetType> CONSTANT_EXPECTED_TYPE_MISMATCH = DiagnosticFactory2.create(ERROR);
@@ -297,6 +297,7 @@ public class DefaultErrorMessages {
MAP.put(TOO_MANY_ARGUMENTS, "Too many arguments for {0}", DescriptorRenderer.TEXT);
MAP.put(CONSTANT_EXPECTED_TYPE_MISMATCH, "An {0} literal does not conform to the expected type {1}", TO_STRING, RENDER_TYPE);
MAP.put(INTEGER_OVERFLOW, "This operation has led to an overflow");
MAP.put(INT_LITERAL_OUT_OF_RANGE, "The value is out of range");
MAP.put(FLOAT_LITERAL_OUT_OF_RANGE, "The value is out of range");
MAP.put(INCORRECT_CHARACTER_LITERAL, "Incorrect character literal");
@@ -34,6 +34,9 @@ import org.jetbrains.jet.lang.types.TypeUtils
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument
import org.jetbrains.jet.JetNodeTypes
import java.lang.Long.parseLong as javaParseLong
import java.math.BigInteger
import org.jetbrains.jet.lang.diagnostics.Errors
import com.intellij.psi.util.PsiTreeUtil
[suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE")]
public class ConstantExpressionEvaluator private (val trace: BindingTrace) : JetVisitor<CompileTimeConstant<*>, JetType>() {
@@ -176,9 +179,7 @@ public class ConstantExpressionEvaluator private (val trace: BindingTrace) : Jet
val argumentsEntrySet = resolvedCall.getValueArguments().entrySet()
if (argumentsEntrySet.isEmpty()) {
val function = unaryOperations[UnaryOperationKey(argumentForReceiver.ctcType, resultingDescriptorName)]
if (function == null) return null
return function(argumentForReceiver.value)
return evaluateUnaryAndCheck(argumentForReceiver, resultingDescriptorName, callExpression)
}
else if (argumentsEntrySet.size() == 1) {
val (parameter, argument) = argumentsEntrySet.first()
@@ -186,14 +187,67 @@ public class ConstantExpressionEvaluator private (val trace: BindingTrace) : Jet
val argumentForParameter = createOperationArgumentForFirstParameter(argument, parameter)
if (argumentForParameter == null) return null
val function = binaryOperations[BinaryOperationKey(argumentForReceiver.ctcType, argumentForParameter.ctcType, resultingDescriptorName)]
if (function == null) return null
return function(argumentForReceiver.value, argumentForParameter.value)
return evaluateBinaryAndCheck(argumentForReceiver, argumentForParameter, resultingDescriptorName, callExpression)
}
return null
}
private fun evaluateUnaryAndCheck(receiver: OperationArgument, name: String, callExpression: JetExpression): Any? {
val functions = unaryOperations[UnaryOperationKey(receiver.ctcType, name)]
if (functions == null) return null
val (function, check) = functions
val result = function(receiver.value)
if (check == emptyUnaryFun) {
return result
}
assert (isIntegerType(receiver.value), "Only integer constants should be checked for overflow")
assert (name == "minus", "Only negation should be checked for overflow")
if (receiver.value == result) {
trace.report(Errors.INTEGER_OVERFLOW.on(PsiTreeUtil.getParentOfType(callExpression, javaClass<JetExpression>()) ?: callExpression))
}
return result
}
private fun evaluateBinaryAndCheck(receiver: OperationArgument, parameter: OperationArgument, name: String, callExpression: JetExpression): Any? {
val functions = binaryOperations[BinaryOperationKey(receiver.ctcType, parameter.ctcType, name)]
if (functions == null) return null
if (isDividingByZero(name, parameter.value)) {
return null
}
val (function, checker) = functions
val actualResult = function(receiver.value, parameter.value)
if (checker == emptyBinaryFun) {
return actualResult
}
assert (isIntegerType(receiver.value) && isIntegerType(parameter.value)) { "Only integer constants should be checked for overflow" }
fun toBigInteger(value: Any?) = BigInteger.valueOf((value as Number).toLong())
val resultInBigIntegers = checker(toBigInteger(receiver.value), toBigInteger(parameter.value))
if (toBigInteger(actualResult) != resultInBigIntegers) {
trace.report(Errors.INTEGER_OVERFLOW.on(PsiTreeUtil.getParentOfType(callExpression, javaClass<JetExpression>()) ?: callExpression))
}
return actualResult
}
private fun isDividingByZero(name: String, parameter: Any?): Boolean {
if (name == OperatorConventions.BINARY_OPERATION_NAMES[JetTokens.DIV]!!.asString()) {
if (isIntegerType(parameter)) {
return (parameter as Number).toLong() == 0.toLong()
}
else if (parameter is Float || parameter is Double) {
return (parameter as Number).toDouble() == 0.0
}
}
return false
}
override fun visitUnaryExpression(expression: JetUnaryExpression, expectedType: JetType?): CompileTimeConstant<*>? {
val leftExpression = expression.getBaseExpression()
if (leftExpression == null) return null
@@ -406,6 +460,8 @@ public fun createCompileTimeConstant(value: Any?, expectedType: JetType?): Compi
}
}
fun isIntegerType(value: Any?) = value is Byte || value is Short || value is Int || value is Long
private fun getIntegerValue(value: Long, expectedType: JetType): CompileTimeConstant<*>? {
fun defaultIntegerValue(value: Long) = when (value) {
value.toInt().toLong() -> IntValue(value.toInt())
@@ -474,19 +530,22 @@ private val STRING = CompileTimeType<String>()
private val ANY = CompileTimeType<Any>()
[suppress("UNCHECKED_CAST")]
private fun <A, B> binaryOperationKey(
private fun <A, B> binaryOperation(
a: CompileTimeType<A>,
b: CompileTimeType<B>,
functionName: String,
f: (A, B) -> Any
) = BinaryOperationKey(a, b, functionName) to f as Function2<Any?, Any?, Any>
operation: Function2<A, B, Any>,
checker: Function2<BigInteger, BigInteger, BigInteger>
) = BinaryOperationKey(a, b, functionName) to Pair(operation, checker) as Pair<Function2<Any?, Any?, Any>, Function2<BigInteger, BigInteger, BigInteger>>
[suppress("UNCHECKED_CAST")]
private fun <A> unaryOperationKey(
private fun <A> unaryOperation(
a: CompileTimeType<A>,
functionName: String,
f: (A) -> Any
) = UnaryOperationKey(a, functionName) to f as Function1<Any?, Any>
operation: Function1<A, Any>,
checker: Function1<Long, Long>
) = UnaryOperationKey(a, functionName) to Pair(operation, checker) as Pair<Function1<Any?, Any>, Function1<Long, Long>>
private data class BinaryOperationKey<A, B>(val f: CompileTimeType<out A>, val s: CompileTimeType<out B>, val functionName: String)
private data class UnaryOperationKey<A>(val f: CompileTimeType<out A>, val functionName: String)
@@ -16,393 +16,401 @@
package org.jetbrains.jet.lang.evaluate
import java.math.BigInteger
import java.util.HashMap
/** This file is generated by org.jetbrains.jet.generators.evaluate:generate(). DO NOT MODIFY MANUALLY */
private val unaryOperations = hashMapOf<UnaryOperationKey<*>, (Any?) -> Any>(
unaryOperationKey(BOOLEAN, "not", { a -> a.not() }),
unaryOperationKey(BYTE, "toInt", { a -> a.toInt() }),
unaryOperationKey(BYTE, "minus", { a -> a.minus() }),
unaryOperationKey(BYTE, "toChar", { a -> a.toChar() }),
unaryOperationKey(BYTE, "toLong", { a -> a.toLong() }),
unaryOperationKey(BYTE, "plus", { a -> a.plus() }),
unaryOperationKey(BYTE, "toFloat", { a -> a.toFloat() }),
unaryOperationKey(BYTE, "toDouble", { a -> a.toDouble() }),
unaryOperationKey(BYTE, "toShort", { a -> a.toShort() }),
unaryOperationKey(BYTE, "toByte", { a -> a.toByte() }),
unaryOperationKey(CHAR, "toInt", { a -> a.toInt() }),
unaryOperationKey(CHAR, "minus", { a -> a.minus() }),
unaryOperationKey(CHAR, "toChar", { a -> a.toChar() }),
unaryOperationKey(CHAR, "toLong", { a -> a.toLong() }),
unaryOperationKey(CHAR, "plus", { a -> a.plus() }),
unaryOperationKey(CHAR, "toFloat", { a -> a.toFloat() }),
unaryOperationKey(CHAR, "toDouble", { a -> a.toDouble() }),
unaryOperationKey(CHAR, "toShort", { a -> a.toShort() }),
unaryOperationKey(CHAR, "toByte", { a -> a.toByte() }),
unaryOperationKey(DOUBLE, "toInt", { a -> a.toInt() }),
unaryOperationKey(DOUBLE, "minus", { a -> a.minus() }),
unaryOperationKey(DOUBLE, "toChar", { a -> a.toChar() }),
unaryOperationKey(DOUBLE, "toLong", { a -> a.toLong() }),
unaryOperationKey(DOUBLE, "plus", { a -> a.plus() }),
unaryOperationKey(DOUBLE, "toFloat", { a -> a.toFloat() }),
unaryOperationKey(DOUBLE, "toDouble", { a -> a.toDouble() }),
unaryOperationKey(DOUBLE, "toShort", { a -> a.toShort() }),
unaryOperationKey(DOUBLE, "toByte", { a -> a.toByte() }),
unaryOperationKey(FLOAT, "toInt", { a -> a.toInt() }),
unaryOperationKey(FLOAT, "minus", { a -> a.minus() }),
unaryOperationKey(FLOAT, "toChar", { a -> a.toChar() }),
unaryOperationKey(FLOAT, "toLong", { a -> a.toLong() }),
unaryOperationKey(FLOAT, "plus", { a -> a.plus() }),
unaryOperationKey(FLOAT, "toFloat", { a -> a.toFloat() }),
unaryOperationKey(FLOAT, "toDouble", { a -> a.toDouble() }),
unaryOperationKey(FLOAT, "toShort", { a -> a.toShort() }),
unaryOperationKey(FLOAT, "toByte", { a -> a.toByte() }),
unaryOperationKey(INT, "plus", { a -> a.plus() }),
unaryOperationKey(INT, "toShort", { a -> a.toShort() }),
unaryOperationKey(INT, "toByte", { a -> a.toByte() }),
unaryOperationKey(INT, "inv", { a -> a.inv() }),
unaryOperationKey(INT, "toInt", { a -> a.toInt() }),
unaryOperationKey(INT, "minus", { a -> a.minus() }),
unaryOperationKey(INT, "toChar", { a -> a.toChar() }),
unaryOperationKey(INT, "toLong", { a -> a.toLong() }),
unaryOperationKey(INT, "toDouble", { a -> a.toDouble() }),
unaryOperationKey(INT, "toFloat", { a -> a.toFloat() }),
unaryOperationKey(LONG, "plus", { a -> a.plus() }),
unaryOperationKey(LONG, "toShort", { a -> a.toShort() }),
unaryOperationKey(LONG, "toByte", { a -> a.toByte() }),
unaryOperationKey(LONG, "inv", { a -> a.inv() }),
unaryOperationKey(LONG, "toInt", { a -> a.toInt() }),
unaryOperationKey(LONG, "minus", { a -> a.minus() }),
unaryOperationKey(LONG, "toChar", { a -> a.toChar() }),
unaryOperationKey(LONG, "toLong", { a -> a.toLong() }),
unaryOperationKey(LONG, "toDouble", { a -> a.toDouble() }),
unaryOperationKey(LONG, "toFloat", { a -> a.toFloat() }),
unaryOperationKey(SHORT, "toInt", { a -> a.toInt() }),
unaryOperationKey(SHORT, "minus", { a -> a.minus() }),
unaryOperationKey(SHORT, "toChar", { a -> a.toChar() }),
unaryOperationKey(SHORT, "toLong", { a -> a.toLong() }),
unaryOperationKey(SHORT, "plus", { a -> a.plus() }),
unaryOperationKey(SHORT, "toFloat", { a -> a.toFloat() }),
unaryOperationKey(SHORT, "toDouble", { a -> a.toDouble() }),
unaryOperationKey(SHORT, "toShort", { a -> a.toShort() }),
unaryOperationKey(SHORT, "toByte", { a -> a.toByte() }),
unaryOperationKey(STRING, "toString", { a -> a.toString() })
private val emptyBinaryFun: Function2<BigInteger, BigInteger, BigInteger> = { a, b -> BigInteger("0") }
private val emptyUnaryFun: Function1<Long, Long> = { a -> 1.toLong() }
private val unaryOperations: HashMap<UnaryOperationKey<*>, Pair<Function1<Any?, Any>, Function1<Long, Long>>>
= hashMapOf<UnaryOperationKey<*>, Pair<Function1<Any?, Any>, Function1<Long, Long>>>(
unaryOperation(BOOLEAN, "not", { a -> a.not() }, emptyUnaryFun),
unaryOperation(BYTE, "toInt", { a -> a.toInt() }, emptyUnaryFun),
unaryOperation(BYTE, "minus", { a -> a.minus() }, { a -> a.minus() }),
unaryOperation(BYTE, "toChar", { a -> a.toChar() }, emptyUnaryFun),
unaryOperation(BYTE, "toLong", { a -> a.toLong() }, emptyUnaryFun),
unaryOperation(BYTE, "plus", { a -> a.plus() }, emptyUnaryFun),
unaryOperation(BYTE, "toFloat", { a -> a.toFloat() }, emptyUnaryFun),
unaryOperation(BYTE, "toDouble", { a -> a.toDouble() }, emptyUnaryFun),
unaryOperation(BYTE, "toShort", { a -> a.toShort() }, emptyUnaryFun),
unaryOperation(BYTE, "toByte", { a -> a.toByte() }, emptyUnaryFun),
unaryOperation(CHAR, "toInt", { a -> a.toInt() }, emptyUnaryFun),
unaryOperation(CHAR, "minus", { a -> a.minus() }, emptyUnaryFun),
unaryOperation(CHAR, "toChar", { a -> a.toChar() }, emptyUnaryFun),
unaryOperation(CHAR, "toLong", { a -> a.toLong() }, emptyUnaryFun),
unaryOperation(CHAR, "plus", { a -> a.plus() }, emptyUnaryFun),
unaryOperation(CHAR, "toFloat", { a -> a.toFloat() }, emptyUnaryFun),
unaryOperation(CHAR, "toDouble", { a -> a.toDouble() }, emptyUnaryFun),
unaryOperation(CHAR, "toShort", { a -> a.toShort() }, emptyUnaryFun),
unaryOperation(CHAR, "toByte", { a -> a.toByte() }, emptyUnaryFun),
unaryOperation(DOUBLE, "toInt", { a -> a.toInt() }, emptyUnaryFun),
unaryOperation(DOUBLE, "minus", { a -> a.minus() }, emptyUnaryFun),
unaryOperation(DOUBLE, "toChar", { a -> a.toChar() }, emptyUnaryFun),
unaryOperation(DOUBLE, "toLong", { a -> a.toLong() }, emptyUnaryFun),
unaryOperation(DOUBLE, "plus", { a -> a.plus() }, emptyUnaryFun),
unaryOperation(DOUBLE, "toFloat", { a -> a.toFloat() }, emptyUnaryFun),
unaryOperation(DOUBLE, "toDouble", { a -> a.toDouble() }, emptyUnaryFun),
unaryOperation(DOUBLE, "toShort", { a -> a.toShort() }, emptyUnaryFun),
unaryOperation(DOUBLE, "toByte", { a -> a.toByte() }, emptyUnaryFun),
unaryOperation(FLOAT, "toInt", { a -> a.toInt() }, emptyUnaryFun),
unaryOperation(FLOAT, "minus", { a -> a.minus() }, emptyUnaryFun),
unaryOperation(FLOAT, "toChar", { a -> a.toChar() }, emptyUnaryFun),
unaryOperation(FLOAT, "toLong", { a -> a.toLong() }, emptyUnaryFun),
unaryOperation(FLOAT, "plus", { a -> a.plus() }, emptyUnaryFun),
unaryOperation(FLOAT, "toFloat", { a -> a.toFloat() }, emptyUnaryFun),
unaryOperation(FLOAT, "toDouble", { a -> a.toDouble() }, emptyUnaryFun),
unaryOperation(FLOAT, "toShort", { a -> a.toShort() }, emptyUnaryFun),
unaryOperation(FLOAT, "toByte", { a -> a.toByte() }, emptyUnaryFun),
unaryOperation(INT, "plus", { a -> a.plus() }, emptyUnaryFun),
unaryOperation(INT, "toShort", { a -> a.toShort() }, emptyUnaryFun),
unaryOperation(INT, "toByte", { a -> a.toByte() }, emptyUnaryFun),
unaryOperation(INT, "inv", { a -> a.inv() }, emptyUnaryFun),
unaryOperation(INT, "toInt", { a -> a.toInt() }, emptyUnaryFun),
unaryOperation(INT, "minus", { a -> a.minus() }, { a -> a.minus() }),
unaryOperation(INT, "toChar", { a -> a.toChar() }, emptyUnaryFun),
unaryOperation(INT, "toLong", { a -> a.toLong() }, emptyUnaryFun),
unaryOperation(INT, "toDouble", { a -> a.toDouble() }, emptyUnaryFun),
unaryOperation(INT, "toFloat", { a -> a.toFloat() }, emptyUnaryFun),
unaryOperation(LONG, "plus", { a -> a.plus() }, emptyUnaryFun),
unaryOperation(LONG, "toShort", { a -> a.toShort() }, emptyUnaryFun),
unaryOperation(LONG, "toByte", { a -> a.toByte() }, emptyUnaryFun),
unaryOperation(LONG, "inv", { a -> a.inv() }, emptyUnaryFun),
unaryOperation(LONG, "toInt", { a -> a.toInt() }, emptyUnaryFun),
unaryOperation(LONG, "minus", { a -> a.minus() }, { a -> a.minus() }),
unaryOperation(LONG, "toChar", { a -> a.toChar() }, emptyUnaryFun),
unaryOperation(LONG, "toLong", { a -> a.toLong() }, emptyUnaryFun),
unaryOperation(LONG, "toDouble", { a -> a.toDouble() }, emptyUnaryFun),
unaryOperation(LONG, "toFloat", { a -> a.toFloat() }, emptyUnaryFun),
unaryOperation(SHORT, "toInt", { a -> a.toInt() }, emptyUnaryFun),
unaryOperation(SHORT, "minus", { a -> a.minus() }, { a -> a.minus() }),
unaryOperation(SHORT, "toChar", { a -> a.toChar() }, emptyUnaryFun),
unaryOperation(SHORT, "toLong", { a -> a.toLong() }, emptyUnaryFun),
unaryOperation(SHORT, "plus", { a -> a.plus() }, emptyUnaryFun),
unaryOperation(SHORT, "toFloat", { a -> a.toFloat() }, emptyUnaryFun),
unaryOperation(SHORT, "toDouble", { a -> a.toDouble() }, emptyUnaryFun),
unaryOperation(SHORT, "toShort", { a -> a.toShort() }, emptyUnaryFun),
unaryOperation(SHORT, "toByte", { a -> a.toByte() }, emptyUnaryFun),
unaryOperation(STRING, "toString", { a -> a.toString() }, emptyUnaryFun)
)
private val binaryOperations = hashMapOf<BinaryOperationKey<*, *>, (Any?, Any?) -> Any>(
binaryOperationKey(BOOLEAN, BOOLEAN, "xor", { a, b -> a.xor(b) }),
binaryOperationKey(BOOLEAN, BOOLEAN, "or", { a, b -> a.or(b) }),
binaryOperationKey(BOOLEAN, ANY, "equals", { a, b -> a.equals(b) }),
binaryOperationKey(BOOLEAN, BOOLEAN, "and", { a, b -> a.and(b) }),
binaryOperationKey(BYTE, BYTE, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(BYTE, CHAR, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(BYTE, DOUBLE, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(BYTE, FLOAT, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(BYTE, INT, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(BYTE, LONG, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(BYTE, SHORT, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(BYTE, BYTE, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(BYTE, CHAR, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(BYTE, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(BYTE, FLOAT, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(BYTE, INT, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(BYTE, LONG, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(BYTE, SHORT, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(BYTE, BYTE, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(BYTE, CHAR, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(BYTE, DOUBLE, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(BYTE, FLOAT, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(BYTE, INT, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(BYTE, LONG, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(BYTE, SHORT, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(BYTE, BYTE, "div", { a, b -> a.div(b) }),
binaryOperationKey(BYTE, CHAR, "div", { a, b -> a.div(b) }),
binaryOperationKey(BYTE, DOUBLE, "div", { a, b -> a.div(b) }),
binaryOperationKey(BYTE, FLOAT, "div", { a, b -> a.div(b) }),
binaryOperationKey(BYTE, INT, "div", { a, b -> a.div(b) }),
binaryOperationKey(BYTE, LONG, "div", { a, b -> a.div(b) }),
binaryOperationKey(BYTE, SHORT, "div", { a, b -> a.div(b) }),
binaryOperationKey(BYTE, BYTE, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(BYTE, CHAR, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(BYTE, DOUBLE, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(BYTE, FLOAT, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(BYTE, INT, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(BYTE, LONG, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(BYTE, SHORT, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(BYTE, BYTE, "times", { a, b -> a.times(b) }),
binaryOperationKey(BYTE, CHAR, "times", { a, b -> a.times(b) }),
binaryOperationKey(BYTE, DOUBLE, "times", { a, b -> a.times(b) }),
binaryOperationKey(BYTE, FLOAT, "times", { a, b -> a.times(b) }),
binaryOperationKey(BYTE, INT, "times", { a, b -> a.times(b) }),
binaryOperationKey(BYTE, LONG, "times", { a, b -> a.times(b) }),
binaryOperationKey(BYTE, SHORT, "times", { a, b -> a.times(b) }),
binaryOperationKey(BYTE, ANY, "equals", { a, b -> a.equals(b) }),
binaryOperationKey(CHAR, BYTE, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(CHAR, CHAR, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(CHAR, DOUBLE, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(CHAR, FLOAT, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(CHAR, INT, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(CHAR, LONG, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(CHAR, SHORT, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(CHAR, BYTE, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(CHAR, CHAR, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(CHAR, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(CHAR, FLOAT, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(CHAR, INT, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(CHAR, LONG, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(CHAR, SHORT, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(CHAR, BYTE, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(CHAR, DOUBLE, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(CHAR, FLOAT, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(CHAR, INT, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(CHAR, LONG, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(CHAR, SHORT, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(CHAR, BYTE, "div", { a, b -> a.div(b) }),
binaryOperationKey(CHAR, DOUBLE, "div", { a, b -> a.div(b) }),
binaryOperationKey(CHAR, FLOAT, "div", { a, b -> a.div(b) }),
binaryOperationKey(CHAR, INT, "div", { a, b -> a.div(b) }),
binaryOperationKey(CHAR, LONG, "div", { a, b -> a.div(b) }),
binaryOperationKey(CHAR, SHORT, "div", { a, b -> a.div(b) }),
binaryOperationKey(CHAR, BYTE, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(CHAR, DOUBLE, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(CHAR, FLOAT, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(CHAR, INT, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(CHAR, LONG, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(CHAR, SHORT, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(CHAR, BYTE, "times", { a, b -> a.times(b) }),
binaryOperationKey(CHAR, DOUBLE, "times", { a, b -> a.times(b) }),
binaryOperationKey(CHAR, FLOAT, "times", { a, b -> a.times(b) }),
binaryOperationKey(CHAR, INT, "times", { a, b -> a.times(b) }),
binaryOperationKey(CHAR, LONG, "times", { a, b -> a.times(b) }),
binaryOperationKey(CHAR, SHORT, "times", { a, b -> a.times(b) }),
binaryOperationKey(CHAR, ANY, "equals", { a, b -> a.equals(b) }),
binaryOperationKey(DOUBLE, BYTE, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(DOUBLE, CHAR, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(DOUBLE, DOUBLE, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(DOUBLE, FLOAT, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(DOUBLE, INT, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(DOUBLE, LONG, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(DOUBLE, SHORT, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(DOUBLE, BYTE, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(DOUBLE, CHAR, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(DOUBLE, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(DOUBLE, FLOAT, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(DOUBLE, INT, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(DOUBLE, LONG, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(DOUBLE, SHORT, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(DOUBLE, BYTE, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(DOUBLE, CHAR, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(DOUBLE, DOUBLE, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(DOUBLE, FLOAT, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(DOUBLE, INT, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(DOUBLE, LONG, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(DOUBLE, SHORT, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(DOUBLE, BYTE, "div", { a, b -> a.div(b) }),
binaryOperationKey(DOUBLE, CHAR, "div", { a, b -> a.div(b) }),
binaryOperationKey(DOUBLE, DOUBLE, "div", { a, b -> a.div(b) }),
binaryOperationKey(DOUBLE, FLOAT, "div", { a, b -> a.div(b) }),
binaryOperationKey(DOUBLE, INT, "div", { a, b -> a.div(b) }),
binaryOperationKey(DOUBLE, LONG, "div", { a, b -> a.div(b) }),
binaryOperationKey(DOUBLE, SHORT, "div", { a, b -> a.div(b) }),
binaryOperationKey(DOUBLE, BYTE, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(DOUBLE, DOUBLE, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(DOUBLE, FLOAT, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(DOUBLE, INT, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(DOUBLE, LONG, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(DOUBLE, SHORT, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(DOUBLE, BYTE, "times", { a, b -> a.times(b) }),
binaryOperationKey(DOUBLE, CHAR, "times", { a, b -> a.times(b) }),
binaryOperationKey(DOUBLE, DOUBLE, "times", { a, b -> a.times(b) }),
binaryOperationKey(DOUBLE, FLOAT, "times", { a, b -> a.times(b) }),
binaryOperationKey(DOUBLE, INT, "times", { a, b -> a.times(b) }),
binaryOperationKey(DOUBLE, LONG, "times", { a, b -> a.times(b) }),
binaryOperationKey(DOUBLE, SHORT, "times", { a, b -> a.times(b) }),
binaryOperationKey(DOUBLE, ANY, "equals", { a, b -> a.equals(b) }),
binaryOperationKey(FLOAT, BYTE, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(FLOAT, CHAR, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(FLOAT, DOUBLE, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(FLOAT, FLOAT, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(FLOAT, INT, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(FLOAT, LONG, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(FLOAT, SHORT, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(FLOAT, BYTE, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(FLOAT, CHAR, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(FLOAT, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(FLOAT, FLOAT, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(FLOAT, INT, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(FLOAT, LONG, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(FLOAT, SHORT, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(FLOAT, BYTE, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(FLOAT, CHAR, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(FLOAT, DOUBLE, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(FLOAT, FLOAT, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(FLOAT, INT, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(FLOAT, LONG, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(FLOAT, SHORT, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(FLOAT, BYTE, "div", { a, b -> a.div(b) }),
binaryOperationKey(FLOAT, CHAR, "div", { a, b -> a.div(b) }),
binaryOperationKey(FLOAT, DOUBLE, "div", { a, b -> a.div(b) }),
binaryOperationKey(FLOAT, FLOAT, "div", { a, b -> a.div(b) }),
binaryOperationKey(FLOAT, INT, "div", { a, b -> a.div(b) }),
binaryOperationKey(FLOAT, LONG, "div", { a, b -> a.div(b) }),
binaryOperationKey(FLOAT, SHORT, "div", { a, b -> a.div(b) }),
binaryOperationKey(FLOAT, BYTE, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(FLOAT, CHAR, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(FLOAT, DOUBLE, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(FLOAT, FLOAT, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(FLOAT, INT, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(FLOAT, LONG, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(FLOAT, SHORT, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(FLOAT, BYTE, "times", { a, b -> a.times(b) }),
binaryOperationKey(FLOAT, CHAR, "times", { a, b -> a.times(b) }),
binaryOperationKey(FLOAT, DOUBLE, "times", { a, b -> a.times(b) }),
binaryOperationKey(FLOAT, FLOAT, "times", { a, b -> a.times(b) }),
binaryOperationKey(FLOAT, INT, "times", { a, b -> a.times(b) }),
binaryOperationKey(FLOAT, LONG, "times", { a, b -> a.times(b) }),
binaryOperationKey(FLOAT, SHORT, "times", { a, b -> a.times(b) }),
binaryOperationKey(FLOAT, ANY, "equals", { a, b -> a.equals(b) }),
binaryOperationKey(INT, BYTE, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(INT, CHAR, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(INT, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(INT, FLOAT, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(INT, INT, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(INT, LONG, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(INT, SHORT, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(INT, BYTE, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(INT, CHAR, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(INT, DOUBLE, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(INT, FLOAT, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(INT, INT, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(INT, LONG, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(INT, SHORT, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(INT, INT, "shl", { a, b -> a.shl(b) }),
binaryOperationKey(INT, INT, "ushr", { a, b -> a.ushr(b) }),
binaryOperationKey(INT, BYTE, "div", { a, b -> a.div(b) }),
binaryOperationKey(INT, CHAR, "div", { a, b -> a.div(b) }),
binaryOperationKey(INT, DOUBLE, "div", { a, b -> a.div(b) }),
binaryOperationKey(INT, FLOAT, "div", { a, b -> a.div(b) }),
binaryOperationKey(INT, INT, "div", { a, b -> a.div(b) }),
binaryOperationKey(INT, LONG, "div", { a, b -> a.div(b) }),
binaryOperationKey(INT, SHORT, "div", { a, b -> a.div(b) }),
binaryOperationKey(INT, INT, "shr", { a, b -> a.shr(b) }),
binaryOperationKey(INT, BYTE, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(INT, CHAR, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(INT, DOUBLE, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(INT, FLOAT, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(INT, INT, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(INT, LONG, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(INT, SHORT, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(INT, BYTE, "times", { a, b -> a.times(b) }),
binaryOperationKey(INT, CHAR, "times", { a, b -> a.times(b) }),
binaryOperationKey(INT, DOUBLE, "times", { a, b -> a.times(b) }),
binaryOperationKey(INT, FLOAT, "times", { a, b -> a.times(b) }),
binaryOperationKey(INT, INT, "times", { a, b -> a.times(b) }),
binaryOperationKey(INT, LONG, "times", { a, b -> a.times(b) }),
binaryOperationKey(INT, SHORT, "times", { a, b -> a.times(b) }),
binaryOperationKey(INT, INT, "or", { a, b -> a.or(b) }),
binaryOperationKey(INT, BYTE, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(INT, CHAR, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(INT, DOUBLE, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(INT, FLOAT, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(INT, INT, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(INT, LONG, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(INT, SHORT, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(INT, INT, "and", { a, b -> a.and(b) }),
binaryOperationKey(INT, INT, "xor", { a, b -> a.xor(b) }),
binaryOperationKey(INT, ANY, "equals", { a, b -> a.equals(b) }),
binaryOperationKey(LONG, BYTE, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(LONG, CHAR, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(LONG, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(LONG, FLOAT, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(LONG, INT, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(LONG, LONG, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(LONG, SHORT, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(LONG, BYTE, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(LONG, CHAR, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(LONG, DOUBLE, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(LONG, FLOAT, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(LONG, INT, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(LONG, LONG, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(LONG, SHORT, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(LONG, INT, "shl", { a, b -> a.shl(b) }),
binaryOperationKey(LONG, INT, "ushr", { a, b -> a.ushr(b) }),
binaryOperationKey(LONG, BYTE, "div", { a, b -> a.div(b) }),
binaryOperationKey(LONG, CHAR, "div", { a, b -> a.div(b) }),
binaryOperationKey(LONG, DOUBLE, "div", { a, b -> a.div(b) }),
binaryOperationKey(LONG, FLOAT, "div", { a, b -> a.div(b) }),
binaryOperationKey(LONG, INT, "div", { a, b -> a.div(b) }),
binaryOperationKey(LONG, LONG, "div", { a, b -> a.div(b) }),
binaryOperationKey(LONG, SHORT, "div", { a, b -> a.div(b) }),
binaryOperationKey(LONG, INT, "shr", { a, b -> a.shr(b) }),
binaryOperationKey(LONG, BYTE, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(LONG, CHAR, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(LONG, DOUBLE, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(LONG, FLOAT, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(LONG, INT, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(LONG, LONG, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(LONG, SHORT, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(LONG, BYTE, "times", { a, b -> a.times(b) }),
binaryOperationKey(LONG, CHAR, "times", { a, b -> a.times(b) }),
binaryOperationKey(LONG, DOUBLE, "times", { a, b -> a.times(b) }),
binaryOperationKey(LONG, FLOAT, "times", { a, b -> a.times(b) }),
binaryOperationKey(LONG, INT, "times", { a, b -> a.times(b) }),
binaryOperationKey(LONG, LONG, "times", { a, b -> a.times(b) }),
binaryOperationKey(LONG, SHORT, "times", { a, b -> a.times(b) }),
binaryOperationKey(LONG, LONG, "or", { a, b -> a.or(b) }),
binaryOperationKey(LONG, BYTE, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(LONG, CHAR, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(LONG, DOUBLE, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(LONG, FLOAT, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(LONG, INT, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(LONG, LONG, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(LONG, SHORT, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(LONG, LONG, "and", { a, b -> a.and(b) }),
binaryOperationKey(LONG, LONG, "xor", { a, b -> a.xor(b) }),
binaryOperationKey(LONG, ANY, "equals", { a, b -> a.equals(b) }),
binaryOperationKey(SHORT, BYTE, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(SHORT, CHAR, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(SHORT, DOUBLE, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(SHORT, FLOAT, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(SHORT, INT, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(SHORT, LONG, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(SHORT, SHORT, "minus", { a, b -> a.minus(b) }),
binaryOperationKey(SHORT, BYTE, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(SHORT, CHAR, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(SHORT, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(SHORT, FLOAT, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(SHORT, INT, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(SHORT, LONG, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(SHORT, SHORT, "compareTo", { a, b -> a.compareTo(b) }),
binaryOperationKey(SHORT, BYTE, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(SHORT, CHAR, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(SHORT, DOUBLE, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(SHORT, FLOAT, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(SHORT, INT, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(SHORT, LONG, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(SHORT, SHORT, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(SHORT, BYTE, "div", { a, b -> a.div(b) }),
binaryOperationKey(SHORT, CHAR, "div", { a, b -> a.div(b) }),
binaryOperationKey(SHORT, DOUBLE, "div", { a, b -> a.div(b) }),
binaryOperationKey(SHORT, FLOAT, "div", { a, b -> a.div(b) }),
binaryOperationKey(SHORT, INT, "div", { a, b -> a.div(b) }),
binaryOperationKey(SHORT, LONG, "div", { a, b -> a.div(b) }),
binaryOperationKey(SHORT, SHORT, "div", { a, b -> a.div(b) }),
binaryOperationKey(SHORT, BYTE, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(SHORT, CHAR, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(SHORT, DOUBLE, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(SHORT, FLOAT, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(SHORT, INT, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(SHORT, LONG, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(SHORT, SHORT, "mod", { a, b -> a.mod(b) }),
binaryOperationKey(SHORT, BYTE, "times", { a, b -> a.times(b) }),
binaryOperationKey(SHORT, CHAR, "times", { a, b -> a.times(b) }),
binaryOperationKey(SHORT, DOUBLE, "times", { a, b -> a.times(b) }),
binaryOperationKey(SHORT, FLOAT, "times", { a, b -> a.times(b) }),
binaryOperationKey(SHORT, INT, "times", { a, b -> a.times(b) }),
binaryOperationKey(SHORT, LONG, "times", { a, b -> a.times(b) }),
binaryOperationKey(SHORT, SHORT, "times", { a, b -> a.times(b) }),
binaryOperationKey(SHORT, ANY, "equals", { a, b -> a.equals(b) }),
binaryOperationKey(STRING, ANY, "plus", { a, b -> a.plus(b) }),
binaryOperationKey(STRING, INT, "get", { a, b -> a.get(b) }),
binaryOperationKey(STRING, ANY, "equals", { a, b -> a.equals(b) }),
binaryOperationKey(STRING, STRING, "compareTo", { a, b -> a.compareTo(b) })
private val binaryOperations: HashMap<BinaryOperationKey<*, *>, Pair<Function2<Any?, Any?, Any>, Function2<BigInteger, BigInteger, BigInteger>>>
= hashMapOf<BinaryOperationKey<*, *>, Pair<Function2<Any?, Any?, Any>, Function2<BigInteger, BigInteger, BigInteger>>>(
binaryOperation(BOOLEAN, BOOLEAN, "xor", { a, b -> a.xor(b) }, emptyBinaryFun),
binaryOperation(BOOLEAN, BOOLEAN, "or", { a, b -> a.or(b) }, emptyBinaryFun),
binaryOperation(BOOLEAN, ANY, "equals", { a, b -> a.equals(b) }, emptyBinaryFun),
binaryOperation(BOOLEAN, BOOLEAN, "and", { a, b -> a.and(b) }, emptyBinaryFun),
binaryOperation(BYTE, BYTE, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }),
binaryOperation(BYTE, CHAR, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(BYTE, DOUBLE, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(BYTE, FLOAT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(BYTE, INT, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }),
binaryOperation(BYTE, LONG, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }),
binaryOperation(BYTE, SHORT, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }),
binaryOperation(BYTE, BYTE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(BYTE, CHAR, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(BYTE, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(BYTE, FLOAT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(BYTE, INT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(BYTE, LONG, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(BYTE, SHORT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(BYTE, BYTE, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }),
binaryOperation(BYTE, CHAR, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(BYTE, DOUBLE, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(BYTE, FLOAT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(BYTE, INT, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }),
binaryOperation(BYTE, LONG, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }),
binaryOperation(BYTE, SHORT, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }),
binaryOperation(BYTE, BYTE, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }),
binaryOperation(BYTE, CHAR, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(BYTE, DOUBLE, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(BYTE, FLOAT, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(BYTE, INT, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }),
binaryOperation(BYTE, LONG, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }),
binaryOperation(BYTE, SHORT, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }),
binaryOperation(BYTE, BYTE, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(BYTE, CHAR, "mod", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(BYTE, DOUBLE, "mod", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(BYTE, FLOAT, "mod", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(BYTE, INT, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(BYTE, LONG, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(BYTE, SHORT, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(BYTE, BYTE, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }),
binaryOperation(BYTE, CHAR, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(BYTE, DOUBLE, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(BYTE, FLOAT, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(BYTE, INT, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }),
binaryOperation(BYTE, LONG, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }),
binaryOperation(BYTE, SHORT, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }),
binaryOperation(BYTE, ANY, "equals", { a, b -> a.equals(b) }, emptyBinaryFun),
binaryOperation(CHAR, BYTE, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(CHAR, CHAR, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(CHAR, DOUBLE, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(CHAR, FLOAT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(CHAR, INT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(CHAR, LONG, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(CHAR, SHORT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(CHAR, BYTE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(CHAR, CHAR, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(CHAR, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(CHAR, FLOAT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(CHAR, INT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(CHAR, LONG, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(CHAR, SHORT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(CHAR, BYTE, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(CHAR, DOUBLE, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(CHAR, FLOAT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(CHAR, INT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(CHAR, LONG, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(CHAR, SHORT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(CHAR, BYTE, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(CHAR, DOUBLE, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(CHAR, FLOAT, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(CHAR, INT, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(CHAR, LONG, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(CHAR, SHORT, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(CHAR, BYTE, "mod", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(CHAR, DOUBLE, "mod", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(CHAR, FLOAT, "mod", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(CHAR, INT, "mod", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(CHAR, LONG, "mod", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(CHAR, SHORT, "mod", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(CHAR, BYTE, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(CHAR, DOUBLE, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(CHAR, FLOAT, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(CHAR, INT, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(CHAR, LONG, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(CHAR, SHORT, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(CHAR, ANY, "equals", { a, b -> a.equals(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, BYTE, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, CHAR, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, DOUBLE, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, FLOAT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, INT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, LONG, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, SHORT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, BYTE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, CHAR, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, FLOAT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, INT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, LONG, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, SHORT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, BYTE, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, CHAR, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, DOUBLE, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, FLOAT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, INT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, LONG, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, SHORT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, BYTE, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, CHAR, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, DOUBLE, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, FLOAT, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, INT, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, LONG, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, SHORT, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, BYTE, "mod", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, DOUBLE, "mod", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, FLOAT, "mod", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, INT, "mod", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, LONG, "mod", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, SHORT, "mod", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, BYTE, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, CHAR, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, DOUBLE, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, FLOAT, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, INT, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, LONG, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, SHORT, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, ANY, "equals", { a, b -> a.equals(b) }, emptyBinaryFun),
binaryOperation(FLOAT, BYTE, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(FLOAT, CHAR, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(FLOAT, DOUBLE, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(FLOAT, FLOAT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(FLOAT, INT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(FLOAT, LONG, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(FLOAT, SHORT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(FLOAT, BYTE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(FLOAT, CHAR, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(FLOAT, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(FLOAT, FLOAT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(FLOAT, INT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(FLOAT, LONG, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(FLOAT, SHORT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(FLOAT, BYTE, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(FLOAT, CHAR, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(FLOAT, DOUBLE, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(FLOAT, FLOAT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(FLOAT, INT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(FLOAT, LONG, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(FLOAT, SHORT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(FLOAT, BYTE, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(FLOAT, CHAR, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(FLOAT, DOUBLE, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(FLOAT, FLOAT, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(FLOAT, INT, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(FLOAT, LONG, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(FLOAT, SHORT, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(FLOAT, BYTE, "mod", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(FLOAT, CHAR, "mod", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(FLOAT, DOUBLE, "mod", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(FLOAT, FLOAT, "mod", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(FLOAT, INT, "mod", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(FLOAT, LONG, "mod", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(FLOAT, SHORT, "mod", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(FLOAT, BYTE, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(FLOAT, CHAR, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(FLOAT, DOUBLE, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(FLOAT, FLOAT, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(FLOAT, INT, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(FLOAT, LONG, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(FLOAT, SHORT, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(FLOAT, ANY, "equals", { a, b -> a.equals(b) }, emptyBinaryFun),
binaryOperation(INT, BYTE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(INT, CHAR, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(INT, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(INT, FLOAT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(INT, INT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(INT, LONG, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(INT, SHORT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(INT, BYTE, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }),
binaryOperation(INT, CHAR, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(INT, DOUBLE, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(INT, FLOAT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(INT, INT, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }),
binaryOperation(INT, LONG, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }),
binaryOperation(INT, SHORT, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }),
binaryOperation(INT, INT, "shl", { a, b -> a.shl(b) }, emptyBinaryFun),
binaryOperation(INT, INT, "ushr", { a, b -> a.ushr(b) }, emptyBinaryFun),
binaryOperation(INT, BYTE, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }),
binaryOperation(INT, CHAR, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(INT, DOUBLE, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(INT, FLOAT, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(INT, INT, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }),
binaryOperation(INT, LONG, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }),
binaryOperation(INT, SHORT, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }),
binaryOperation(INT, INT, "shr", { a, b -> a.shr(b) }, emptyBinaryFun),
binaryOperation(INT, BYTE, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(INT, CHAR, "mod", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(INT, DOUBLE, "mod", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(INT, FLOAT, "mod", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(INT, INT, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(INT, LONG, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(INT, SHORT, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(INT, BYTE, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }),
binaryOperation(INT, CHAR, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(INT, DOUBLE, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(INT, FLOAT, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(INT, INT, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }),
binaryOperation(INT, LONG, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }),
binaryOperation(INT, SHORT, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }),
binaryOperation(INT, INT, "or", { a, b -> a.or(b) }, { a, b -> a.or(b) }),
binaryOperation(INT, BYTE, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }),
binaryOperation(INT, CHAR, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(INT, DOUBLE, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(INT, FLOAT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(INT, INT, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }),
binaryOperation(INT, LONG, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }),
binaryOperation(INT, SHORT, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }),
binaryOperation(INT, INT, "and", { a, b -> a.and(b) }, { a, b -> a.and(b) }),
binaryOperation(INT, INT, "xor", { a, b -> a.xor(b) }, { a, b -> a.xor(b) }),
binaryOperation(INT, ANY, "equals", { a, b -> a.equals(b) }, emptyBinaryFun),
binaryOperation(LONG, BYTE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(LONG, CHAR, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(LONG, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(LONG, FLOAT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(LONG, INT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(LONG, LONG, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(LONG, SHORT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(LONG, BYTE, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }),
binaryOperation(LONG, CHAR, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(LONG, DOUBLE, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(LONG, FLOAT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(LONG, INT, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }),
binaryOperation(LONG, LONG, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }),
binaryOperation(LONG, SHORT, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }),
binaryOperation(LONG, INT, "shl", { a, b -> a.shl(b) }, emptyBinaryFun),
binaryOperation(LONG, INT, "ushr", { a, b -> a.ushr(b) }, emptyBinaryFun),
binaryOperation(LONG, BYTE, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }),
binaryOperation(LONG, CHAR, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(LONG, DOUBLE, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(LONG, FLOAT, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(LONG, INT, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }),
binaryOperation(LONG, LONG, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }),
binaryOperation(LONG, SHORT, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }),
binaryOperation(LONG, INT, "shr", { a, b -> a.shr(b) }, emptyBinaryFun),
binaryOperation(LONG, BYTE, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(LONG, CHAR, "mod", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(LONG, DOUBLE, "mod", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(LONG, FLOAT, "mod", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(LONG, INT, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(LONG, LONG, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(LONG, SHORT, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(LONG, BYTE, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }),
binaryOperation(LONG, CHAR, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(LONG, DOUBLE, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(LONG, FLOAT, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(LONG, INT, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }),
binaryOperation(LONG, LONG, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }),
binaryOperation(LONG, SHORT, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }),
binaryOperation(LONG, LONG, "or", { a, b -> a.or(b) }, { a, b -> a.or(b) }),
binaryOperation(LONG, BYTE, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }),
binaryOperation(LONG, CHAR, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(LONG, DOUBLE, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(LONG, FLOAT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(LONG, INT, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }),
binaryOperation(LONG, LONG, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }),
binaryOperation(LONG, SHORT, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }),
binaryOperation(LONG, LONG, "and", { a, b -> a.and(b) }, { a, b -> a.and(b) }),
binaryOperation(LONG, LONG, "xor", { a, b -> a.xor(b) }, { a, b -> a.xor(b) }),
binaryOperation(LONG, ANY, "equals", { a, b -> a.equals(b) }, emptyBinaryFun),
binaryOperation(SHORT, BYTE, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }),
binaryOperation(SHORT, CHAR, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(SHORT, DOUBLE, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(SHORT, FLOAT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
binaryOperation(SHORT, INT, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }),
binaryOperation(SHORT, LONG, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }),
binaryOperation(SHORT, SHORT, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }),
binaryOperation(SHORT, BYTE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(SHORT, CHAR, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(SHORT, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(SHORT, FLOAT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(SHORT, INT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(SHORT, LONG, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(SHORT, SHORT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(SHORT, BYTE, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }),
binaryOperation(SHORT, CHAR, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(SHORT, DOUBLE, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(SHORT, FLOAT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(SHORT, INT, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }),
binaryOperation(SHORT, LONG, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }),
binaryOperation(SHORT, SHORT, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }),
binaryOperation(SHORT, BYTE, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }),
binaryOperation(SHORT, CHAR, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(SHORT, DOUBLE, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(SHORT, FLOAT, "div", { a, b -> a.div(b) }, emptyBinaryFun),
binaryOperation(SHORT, INT, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }),
binaryOperation(SHORT, LONG, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }),
binaryOperation(SHORT, SHORT, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }),
binaryOperation(SHORT, BYTE, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(SHORT, CHAR, "mod", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(SHORT, DOUBLE, "mod", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(SHORT, FLOAT, "mod", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(SHORT, INT, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(SHORT, LONG, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(SHORT, SHORT, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(SHORT, BYTE, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }),
binaryOperation(SHORT, CHAR, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(SHORT, DOUBLE, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(SHORT, FLOAT, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(SHORT, INT, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }),
binaryOperation(SHORT, LONG, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }),
binaryOperation(SHORT, SHORT, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }),
binaryOperation(SHORT, ANY, "equals", { a, b -> a.equals(b) }, emptyBinaryFun),
binaryOperation(STRING, ANY, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(STRING, INT, "get", { a, b -> a.get(b) }, emptyBinaryFun),
binaryOperation(STRING, ANY, "equals", { a, b -> a.equals(b) }, emptyBinaryFun),
binaryOperation(STRING, STRING, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun)
)