package vitry.prelude;
import static vitry.runtime.VitryRuntime.FALSE;
import static vitry.runtime.VitryRuntime.TRUE;
import java.math.BigInteger;
import vitry.runtime.BigRational;
import vitry.runtime.RestFunction;
import vitry.runtime.Symbol;
import vitry.runtime.error.TypeError;
import vitry.runtime.struct.Seq;
import vitry.runtime.struct.Seqs;
public class sub extends RestFunction
{
public Object applyVar(Seq<?> args) {
return applyVar(Seqs.toArray(args));
}
public Object applyVar(Object[] args) {
switch (args.length) {
case 1:
return negate(args[0]);
case 2:
return BINARY.apply(args[0], args[1]);
default:
throw new IllegalArgumentException();
}
}
private static final MathPrimitive BINARY = new MathPrimitive()
{
final Symbol withBool(Symbol x, Symbol y)
{
return x != y ? TRUE : FALSE;
}
final BigInteger withInt(BigInteger x, BigInteger y)
{
return x.subtract(y);
}
final BigRational withRat(BigRational x, BigRational y)
{
return x.subtract(y);
}
final Float withFloat(float x, float y)
{
return x - y;
}
final Double withDouble(double x, double y)
{
return x - y;
}
};
private Object negate(Object x)
{
if (x instanceof BigRational)
return ((BigRational) x).negate();
if (x instanceof BigInteger)
return ((BigInteger) x).negate();
if (x instanceof Float)
return ((Float) x).floatValue() * -1;
if (x instanceof Double)
return ((Double) x).doubleValue() * -1;
throw new TypeError("Can not apply " + this + " to " + x);
}
}