package cn.liutils.ripple;
import cn.liutils.ripple.RippleException.RippleRuntimeException;
/**
* Implementation of basic calculations
* @author acaly
*
*/
public final class Calculation {
//IMPORTANT function names in this class is used as hard-coded string in CodeGenerator.
private Calculation() {}
public static Object castObject(int value) {
return value;
}
public static Object castObject(double value) {
return value;
}
public static Object castObject(boolean value) {
return value;
}
public static int castInt(Object value) {
if(value instanceof Integer)
return (Integer) value;
if(value instanceof Double)
return (int) (double) value;
if(value instanceof Float)
return (int) (float) value;
throw new RippleRuntimeException("Cannot cast to integer");
}
public static double castDouble(Object value) {
if(value instanceof Double)
return (Double) value;
if(value instanceof Integer)
return (Integer) value;
if(value instanceof Float)
return (Float) value;
throw new RippleRuntimeException("Cannot cast " + value + " to double");
}
public static boolean castBoolean(Object value) {
if (value instanceof Boolean)
return (Boolean) value;
throw new RippleRuntimeException("Cannot cast to boolean");
}
public static boolean checkType(Object value) {
if (value == null) return false;
return value instanceof Integer ||
value instanceof Double || value instanceof Boolean || value instanceof Float;
}
public static IFunction getFunctionOverload(ScriptProgram program, String path, String funcPath, int nargs) {
ScriptFunction sf = program.root.getFunction(new Path(new Path(funcPath).getParent(), path));
if (sf != null) {
IFunction f = sf.cacheOverload(nargs);
if (f != null) return f;
}
sf = program.root.getFunction(new Path(path));
if (sf != null) {
IFunction f = sf.cacheOverload(nargs);
if (f != null) return f;
}
throw new RippleRuntimeException("Function '" + path + "' not found");
}
public static void throwRuntimeException(String message) {
throw new RippleRuntimeException(message);
}
public static Object binAdd(Object a, Object b) {
if(a instanceof Integer && b instanceof Integer) {
return (Integer) a + (Integer) b;
} else {
return castDouble(a) + castDouble(b);
}
}
public static Object binSubstract(Object a, Object b) {
if(a instanceof Integer && b instanceof Integer) {
return (Integer) a - (Integer) b;
} else {
return castDouble(a) - castDouble(b);
}
}
public static Object binMultiply(Object a, Object b) {
if(a instanceof Integer && b instanceof Integer) {
return (Integer) a * (Integer) b;
} else {
return castDouble(a) * castDouble(b);
}
}
public static Object binDivide(Object a, Object b) {
if(a instanceof Integer && b instanceof Integer) {
return (Integer) a / (Integer) b;
} else {
return castDouble(a) / castDouble(b);
}
}
public static Object binEqual(Object a, Object b) {
if(a instanceof Integer && b instanceof Integer) {
return (Integer) a == (Integer) b;
} else {
return castDouble(a) == castDouble(b);
}
}
public static Object binNotEqual(Object a, Object b) {
if(a instanceof Integer && b instanceof Integer) {
return (Integer) a != (Integer) b;
} else {
return castDouble(a) != castDouble(b);
}
}
public static Object binGreater(Object a, Object b) {
if(a instanceof Integer && b instanceof Integer) {
return (Integer) a > (Integer) b;
} else {
return castDouble(a) > castDouble(b);
}
}
public static Object binLesser(Object a, Object b) {
if(a instanceof Integer && b instanceof Integer) {
return (Integer) a < (Integer) b;
} else {
return castDouble(a) < castDouble(b);
}
}
public static Object binGreaterEqual(Object a, Object b) {
if(a instanceof Integer && b instanceof Integer) {
return (Integer) a >= (Integer) b;
} else {
return castDouble(a) >= castDouble(b);
}
}
public static Object binLesserEqual(Object a, Object b) {
if(a instanceof Integer && b instanceof Integer) {
return (Integer) a <= (Integer) b;
} else {
return castDouble(a) <= castDouble(b);
}
}
public static Object binAnd(Object a, Object b) {
if (a instanceof Boolean && b instanceof Boolean) {
return (Boolean) a && (Boolean) b;
}
throw new RippleRuntimeException("Unsupported operand type in binary and");
}
public static Object binOr(Object a, Object b) {
if (a instanceof Boolean && b instanceof Boolean) {
return (Boolean) a || (Boolean) b;
}
throw new RippleRuntimeException("Unsupported operand type in binary or");
}
public static Object unMinus(Object a) {
if (a instanceof Integer) {
return -(Integer) a;
} else if (a instanceof Double) {
return -(Double) a;
} else if (a instanceof Float) {
return -(Float) a;
}
throw new RippleRuntimeException("Unsupported operand type in unary minus");
}
public static Object unNot(Object a) {
if (a instanceof Boolean) {
return !(Boolean) a;
}
throw new RippleRuntimeException("Unsupported operand type in unary not");
}
}