diff options
Diffstat (limited to 'src/jvm')
-rw-r--r-- | src/jvm/clojure/lang/Compiler.java | 483 | ||||
-rw-r--r-- | src/jvm/clojure/lang/LispReader.java | 2 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Numbers.java | 1258 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Reflector.java | 21 |
4 files changed, 968 insertions, 796 deletions
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java index 29e8fbbd..9f8c7b5f 100644 --- a/src/jvm/clojure/lang/Compiler.java +++ b/src/jvm/clojure/lang/Compiler.java @@ -139,6 +139,7 @@ private static final Type SYMBOL_TYPE = Type.getType(Symbol.class); private static final Type IFN_TYPE = Type.getType(IFn.class); private static final Type AFUNCTION_TYPE = Type.getType(AFunction.class); private static final Type RT_TYPE = Type.getType(RT.class); +private static final Type NUMBERS_TYPE = Type.getType(Numbers.class); final static Type CLASS_TYPE = Type.getType(Class.class); final static Type NS_TYPE = Type.getType(Namespace.class); final static Type UTIL_TYPE = Type.getType(Util.class); @@ -726,22 +727,20 @@ static public abstract class HostExpr implements Expr, MaybePrimitiveExpr{ else { if(returnType == int.class) - //gen.invokeStatic(NUM_TYPE, fromIntMethod); gen.invokeStatic(INTEGER_TYPE, intValueOfMethod); else if(returnType == float.class) { - //gen.visitInsn(F2D); - gen.invokeStatic(FLOAT_TYPE, floatValueOfMethod); - //m = floatValueOfMethod; + gen.visitInsn(F2D); + gen.invokeStatic(DOUBLE_TYPE, doubleValueOfMethod); } else if(returnType == double.class) gen.invokeStatic(DOUBLE_TYPE, doubleValueOfMethod); - else if(returnType == long.class) - gen.invokeStatic(LONG_TYPE, longValueOfMethod); - else if(returnType == byte.class) - gen.invokeStatic(BYTE_TYPE, byteValueOfMethod); - else if(returnType == short.class) - gen.invokeStatic(SHORT_TYPE, shortValueOfMethod); + else if(returnType == long.class) + gen.invokeStatic(NUMBERS_TYPE, Method.getMethod("Number num(long)")); + else if(returnType == byte.class) + gen.invokeStatic(BYTE_TYPE, byteValueOfMethod); + else if(returnType == short.class) + gen.invokeStatic(SHORT_TYPE, shortValueOfMethod); } } } @@ -1163,9 +1162,35 @@ static abstract class MethodExpr extends HostExpr{ Expr e = (Expr) args.nth(i); try { - if(maybePrimitiveType(e) == parameterTypes[i]) + final Class primc = maybePrimitiveType(e); + if(primc == parameterTypes[i]) { - ((MaybePrimitiveExpr) e).emitUnboxed(C.EXPRESSION, objx, gen); + final MaybePrimitiveExpr pe = (MaybePrimitiveExpr) e; + pe.emitUnboxed(C.EXPRESSION, objx, gen); + } + else if(primc == int.class && parameterTypes[i] == long.class) + { + final MaybePrimitiveExpr pe = (MaybePrimitiveExpr) e; + pe.emitUnboxed(C.EXPRESSION, objx, gen); + gen.visitInsn(I2L); + } + else if(primc == long.class && parameterTypes[i] == int.class) + { + final MaybePrimitiveExpr pe = (MaybePrimitiveExpr) e; + pe.emitUnboxed(C.EXPRESSION, objx, gen); + gen.invokeStatic(RT_TYPE, Method.getMethod("int intCast(long)")); + } + else if(primc == float.class && parameterTypes[i] == double.class) + { + final MaybePrimitiveExpr pe = (MaybePrimitiveExpr) e; + pe.emitUnboxed(C.EXPRESSION, objx, gen); + gen.visitInsn(F2D); + } + else if(primc == double.class && parameterTypes[i] == float.class) + { + final MaybePrimitiveExpr pe = (MaybePrimitiveExpr) e; + pe.emitUnboxed(C.EXPRESSION, objx, gen); + gen.visitInsn(D2F); } else { @@ -1508,6 +1533,66 @@ static class UnresolvedVarExpr implements Expr{ } } +static class NumberExpr extends LiteralExpr implements MaybePrimitiveExpr{ + final Number n; + public final int id; + + public NumberExpr(Number n){ + this.n = n; + this.id = registerConstant(n); + } + + Object val(){ + return n; + } + + public void emit(C context, ObjExpr objx, GeneratorAdapter gen){ + if(context != C.STATEMENT) + { + objx.emitConstant(gen, id); +// emitUnboxed(context,objx,gen); +// HostExpr.emitBoxReturn(objx,gen,getJavaClass()); + } + } + + public boolean hasJavaClass() throws Exception{ + return true; + } + + public Class getJavaClass(){ + if(n instanceof Integer) + return long.class; + else if(n instanceof Double) + return double.class; + else if(n instanceof Long) + return long.class; + else + throw new IllegalStateException("Unsupported Number type: " + n.getClass().getName()); + } + + public boolean canEmitPrimitive(){ + return true; + } + + public void emitUnboxed(C context, ObjExpr objx, GeneratorAdapter gen){ + if(n instanceof Integer) + gen.push(n.longValue()); + else if(n instanceof Double) + gen.push(n.doubleValue()); + else if(n instanceof Long) + gen.push(n.longValue()); + } + + static public Expr parse(Number form){ + if(form instanceof Integer + || form instanceof Double + || form instanceof Long) + return new NumberExpr(form); + else + return new ConstantExpr(form); + } +} + static class ConstantExpr extends LiteralExpr{ //stuff quoted vals in classloader at compile time, pull out at runtime //this won't work for static compilation... @@ -3938,119 +4023,124 @@ static public class ObjExpr implements Expr{ gen.push(((Integer) value).intValue()); gen.invokeStatic(Type.getType(Integer.class), Method.getMethod("Integer valueOf(int)")); } + else if(value instanceof Long) + { + gen.push(((Long) value).longValue()); + gen.invokeStatic(Type.getType(Long.class), Method.getMethod("Long valueOf(long)")); + } else if(value instanceof Double) { gen.push(((Double) value).doubleValue()); gen.invokeStatic(Type.getType(Double.class), Method.getMethod("Double valueOf(double)")); } - else if(value instanceof Character) - { - gen.push(((Character) value).charValue()); - gen.invokeStatic(Type.getType(Character.class), Method.getMethod("Character valueOf(char)")); - } - else if(value instanceof Class) - { - Class cc = (Class)value; - if(cc.isPrimitive()) - { - Type bt; - if ( cc == boolean.class ) bt = Type.getType(Boolean.class); - else if ( cc == byte.class ) bt = Type.getType(Byte.class); - else if ( cc == char.class ) bt = Type.getType(Character.class); - else if ( cc == double.class ) bt = Type.getType(Double.class); - else if ( cc == float.class ) bt = Type.getType(Float.class); - else if ( cc == int.class ) bt = Type.getType(Integer.class); - else if ( cc == long.class ) bt = Type.getType(Long.class); - else if ( cc == short.class ) bt = Type.getType(Short.class); - else throw new RuntimeException( - "Can't embed unknown primitive in code: " + value); - gen.getStatic( bt, "TYPE", Type.getType(Class.class) ); - } - else - { - gen.push(destubClassName(cc.getName())); - gen.invokeStatic(Type.getType(Class.class), Method.getMethod("Class forName(String)")); - } - } - else if(value instanceof Symbol) - { - gen.push(((Symbol) value).ns); - gen.push(((Symbol) value).name); - gen.invokeStatic(Type.getType(Symbol.class), - Method.getMethod("clojure.lang.Symbol create(String,String)")); - } - else if(value instanceof Keyword) - { - emitValue(((Keyword) value).sym, gen); - gen.invokeStatic(Type.getType(Keyword.class), - Method.getMethod("clojure.lang.Keyword intern(clojure.lang.Symbol)")); - } + else if(value instanceof Character) + { + gen.push(((Character) value).charValue()); + gen.invokeStatic(Type.getType(Character.class), Method.getMethod("Character valueOf(char)")); + } + else if(value instanceof Class) + { + Class cc = (Class)value; + if(cc.isPrimitive()) + { + Type bt; + if ( cc == boolean.class ) bt = Type.getType(Boolean.class); + else if ( cc == byte.class ) bt = Type.getType(Byte.class); + else if ( cc == char.class ) bt = Type.getType(Character.class); + else if ( cc == double.class ) bt = Type.getType(Double.class); + else if ( cc == float.class ) bt = Type.getType(Float.class); + else if ( cc == int.class ) bt = Type.getType(Integer.class); + else if ( cc == long.class ) bt = Type.getType(Long.class); + else if ( cc == short.class ) bt = Type.getType(Short.class); + else throw new RuntimeException( + "Can't embed unknown primitive in code: " + value); + gen.getStatic( bt, "TYPE", Type.getType(Class.class) ); + } + else + { + gen.push(destubClassName(cc.getName())); + gen.invokeStatic(Type.getType(Class.class), Method.getMethod("Class forName(String)")); + } + } + else if(value instanceof Symbol) + { + gen.push(((Symbol) value).ns); + gen.push(((Symbol) value).name); + gen.invokeStatic(Type.getType(Symbol.class), + Method.getMethod("clojure.lang.Symbol create(String,String)")); + } + else if(value instanceof Keyword) + { + emitValue(((Keyword) value).sym, gen); + gen.invokeStatic(Type.getType(Keyword.class), + Method.getMethod("clojure.lang.Keyword intern(clojure.lang.Symbol)")); + } // else if(value instanceof KeywordCallSite) // { // emitValue(((KeywordCallSite) value).k.sym, gen); // gen.invokeStatic(Type.getType(KeywordCallSite.class), // Method.getMethod("clojure.lang.KeywordCallSite create(clojure.lang.Symbol)")); // } - else if(value instanceof Var) - { - Var var = (Var) value; - gen.push(var.ns.name.toString()); - gen.push(var.sym.toString()); - gen.invokeStatic(RT_TYPE, Method.getMethod("clojure.lang.Var var(String,String)")); - } - else if(value instanceof IPersistentMap) - { - List entries = new ArrayList(); - for(Map.Entry entry : (Set<Map.Entry>) ((Map) value).entrySet()) - { - entries.add(entry.getKey()); - entries.add(entry.getValue()); - } - emitListAsObjectArray(entries, gen); - gen.invokeStatic(RT_TYPE, - Method.getMethod("clojure.lang.IPersistentMap map(Object[])")); - } - else if(value instanceof IPersistentVector) - { - emitListAsObjectArray(value, gen); - gen.invokeStatic(RT_TYPE, Method.getMethod( - "clojure.lang.IPersistentVector vector(Object[])")); - } - else if(value instanceof ISeq || value instanceof IPersistentList) - { - emitListAsObjectArray(value, gen); - gen.invokeStatic(Type.getType(java.util.Arrays.class), - Method.getMethod("java.util.List asList(Object[])")); - gen.invokeStatic(Type.getType(PersistentList.class), - Method.getMethod( - "clojure.lang.IPersistentList create(java.util.List)")); - } - else - { - String cs = null; - try - { - cs = RT.printString(value); - //System.out.println("WARNING SLOW CODE: " + value.getClass() + " -> " + cs); - } - catch(Exception e) - { - throw new RuntimeException( - "Can't embed object in code, maybe print-dup not defined: " + - value); - } - if(cs.length() == 0) - throw new RuntimeException( - "Can't embed unreadable object in code: " + value); - - if(cs.startsWith("#<")) - throw new RuntimeException( - "Can't embed unreadable object in code: " + cs); - - gen.push(cs); - gen.invokeStatic(RT_TYPE, readStringMethod); - partial = false; - } + else if(value instanceof Var) + { + Var var = (Var) value; + gen.push(var.ns.name.toString()); + gen.push(var.sym.toString()); + gen.invokeStatic(RT_TYPE, Method.getMethod("clojure.lang.Var var(String,String)")); + } + else if(value instanceof IPersistentMap) + { + List entries = new ArrayList(); + for(Map.Entry entry : (Set<Map.Entry>) ((Map) value).entrySet()) + { + entries.add(entry.getKey()); + entries.add(entry.getValue()); + } + emitListAsObjectArray(entries, gen); + gen.invokeStatic(RT_TYPE, + Method.getMethod("clojure.lang.IPersistentMap map(Object[])")); + } + else if(value instanceof IPersistentVector) + { + emitListAsObjectArray(value, gen); + gen.invokeStatic(RT_TYPE, Method.getMethod( + "clojure.lang.IPersistentVector vector(Object[])")); + } + else if(value instanceof ISeq || value instanceof IPersistentList) + { + emitListAsObjectArray(value, gen); + gen.invokeStatic(Type.getType(java.util.Arrays.class), + Method.getMethod("java.util.List asList(Object[])")); + gen.invokeStatic(Type.getType(PersistentList.class), + Method.getMethod( + "clojure.lang.IPersistentList create(java.util.List)")); + } + else + { + String cs = null; + try + { + cs = RT.printString(value); + //System.out.println("WARNING SLOW CODE: " + value.getClass() + " -> " + cs); + } + catch(Exception e) + { + throw new RuntimeException( + "Can't embed object in code, maybe print-dup not defined: " + + value); + } + if(cs.length() == 0) + throw new RuntimeException( + "Can't embed unreadable object in code: " + value); + + if(cs.startsWith("#<")) + throw new RuntimeException( + "Can't embed unreadable object in code: " + cs); + + gen.push(cs); + gen.invokeStatic(RT_TYPE, readStringMethod); + partial = false; + } if(partial) { @@ -4558,26 +4648,8 @@ public static class FnMethod extends ObjMethod{ try { Var.pushThreadBindings(RT.map(LOOP_LABEL, loopLabel, METHOD, this)); - MaybePrimitiveExpr be = (MaybePrimitiveExpr) body; - if(Util.isPrimitive(retClass) && be.canEmitPrimitive()) - { - if(be.getJavaClass() == retClass) - be.emitUnboxed(C.RETURN,fn,gen); - //todo - support the standard widening conversions - else - throw new IllegalArgumentException("Mismatched primitive return, expected: " - + retClass + ", had: " + be.getJavaClass()); - } - else - { - body.emit(C.RETURN, fn, gen); - if(retClass == void.class) - { - gen.pop(); - } - else - gen.unbox(getReturnType()); - } + emitBody(objx, gen, retClass, body); + Label end = gen.mark(); for(ISeq lbs = argLocals.seq(); lbs != null; lbs = lbs.next()) { @@ -4739,6 +4811,7 @@ abstract public static class ObjMethod{ PersistentHashSet localsUsedInCatchFinally = PersistentHashSet.EMPTY; protected IPersistentMap methodMeta; + public final IPersistentMap locals(){ return locals; } @@ -4768,6 +4841,48 @@ abstract public static class ObjMethod{ this.objx = objx; } + static void emitBody(ObjExpr objx, GeneratorAdapter gen, Class retClass, Expr body) throws Exception{ + MaybePrimitiveExpr be = (MaybePrimitiveExpr) body; + if(Util.isPrimitive(retClass) && be.canEmitPrimitive()) + { + Class bc = maybePrimitiveType(be); + if(bc == retClass) + be.emitUnboxed(C.RETURN, objx, gen); + else if(retClass == long.class && bc == int.class) + { + be.emitUnboxed(C.RETURN, objx, gen); + gen.visitInsn(I2L); + } + else if(retClass == double.class && bc == float.class) + { + be.emitUnboxed(C.RETURN, objx, gen); + gen.visitInsn(F2D); + } + else if(retClass == int.class && bc == long.class) + { + be.emitUnboxed(C.RETURN, objx, gen); + gen.invokeStatic(RT_TYPE, Method.getMethod("int intCast(long)")); + } + else if(retClass == float.class && bc == double.class) + { + be.emitUnboxed(C.RETURN, objx, gen); + gen.visitInsn(D2F); + } + else + throw new IllegalArgumentException("Mismatched primitive return, expected: " + + retClass + ", had: " + be.getJavaClass()); + } + else + { + body.emit(C.RETURN, objx, gen); + if(retClass == void.class) + { + gen.pop(); + } + else + gen.unbox(Type.getType(retClass)); + } + } abstract int numParams(); abstract String getMethodName(); abstract Type getReturnType(); @@ -5245,6 +5360,13 @@ public static class LetExpr implements Expr, MaybePrimitiveExpr{ if(sym.getNamespace() != null) throw new Exception("Can't let qualified name: " + sym); Expr init = analyze(C.EXPRESSION, bindings.nth(i + 1), sym.name); + if(isLoop) + { + if(maybePrimitiveType(init) == int.class) + init = new StaticMethodExpr("", 0, null, RT.class, "longCast", RT.vector(init)); + else if(maybePrimitiveType(init) == float.class) + init = new StaticMethodExpr("", 0, null, RT.class, "doubleCast", RT.vector(init)); + } //sequential enhancement of env (like Lisp let*) LocalBinding lb = registerLocal(sym, tagOf(sym), init,false); BindingInit bi = new BindingInit(lb, init); @@ -5389,18 +5511,47 @@ public static class RecurExpr implements Expr{ Class primc = lb.getPrimitiveType(); try { - if(!(arg instanceof MaybePrimitiveExpr && arg.hasJavaClass() && arg.getJavaClass() == primc)) - throw new IllegalArgumentException("recur arg for primitive local: " + + final Class pc = maybePrimitiveType(arg); + if(pc == primc) + ((MaybePrimitiveExpr) arg).emitUnboxed(C.EXPRESSION, objx, gen); + else if(primc == long.class && pc == int.class) + { + ((MaybePrimitiveExpr) arg).emitUnboxed(C.EXPRESSION, objx, gen); + gen.visitInsn(I2L); + } + else if(primc == double.class && pc == float.class) + { + ((MaybePrimitiveExpr) arg).emitUnboxed(C.EXPRESSION, objx, gen); + gen.visitInsn(F2D); + } + else if(primc == int.class && pc == long.class) + { + ((MaybePrimitiveExpr) arg).emitUnboxed(C.EXPRESSION, objx, gen); + gen.invokeStatic(RT_TYPE, Method.getMethod("int intCast(long)")); + } + else if(primc == float.class && pc == double.class) + { + ((MaybePrimitiveExpr) arg).emitUnboxed(C.EXPRESSION, objx, gen); + gen.visitInsn(D2F); + } + else + { + if(RT.booleanCast(RT.WARN_ON_REFLECTION.deref())) + //throw new IllegalArgumentException + RT.errPrintWriter().println + ("recur arg for primitive local: " + lb.name + " must be matching primitive, had: " + (arg.hasJavaClass() ? arg.getJavaClass().getName():"Object") + ", needed: " + primc.getName()); + arg.emit(C.EXPRESSION, objx, gen); + HostExpr.emitUnboxArg(objx,gen,primc); + } } catch(Exception e) { throw new RuntimeException(e); } - ((MaybePrimitiveExpr) arg).emitUnboxed(C.EXPRESSION, objx, gen); } else { @@ -5501,28 +5652,28 @@ private static Expr analyze(C context, Object form, String name) throws Exceptio return analyzeSymbol((Symbol) form); else if(fclass == Keyword.class) return registerKeyword((Keyword) form); -// else if(form instanceof Num) -// return new NumExpr((Num) form); + else if(form instanceof Number) + return NumberExpr.parse((Number) form); else if(fclass == String.class) return new StringExpr(((String) form).intern()); // else if(fclass == Character.class) // return new CharExpr((Character) form); - else if(form instanceof IPersistentCollection && ((IPersistentCollection) form).count() == 0) - { - Expr ret = new EmptyExpr(form); - if(RT.meta(form) != null) - ret = new MetaExpr(ret, MapExpr - .parse(context == C.EVAL ? context : C.EXPRESSION, ((IObj) form).meta())); - return ret; - } - else if(form instanceof ISeq) - return analyzeSeq(context, (ISeq) form, name); - else if(form instanceof IPersistentVector) - return VectorExpr.parse(context, (IPersistentVector) form); - else if(form instanceof IPersistentMap) - return MapExpr.parse(context, (IPersistentMap) form); - else if(form instanceof IPersistentSet) - return SetExpr.parse(context, (IPersistentSet) form); + else if(form instanceof IPersistentCollection && ((IPersistentCollection) form).count() == 0) + { + Expr ret = new EmptyExpr(form); + if(RT.meta(form) != null) + ret = new MetaExpr(ret, MapExpr + .parse(context == C.EVAL ? context : C.EXPRESSION, ((IObj) form).meta())); + return ret; + } + else if(form instanceof ISeq) + return analyzeSeq(context, (ISeq) form, name); + else if(form instanceof IPersistentVector) + return VectorExpr.parse(context, (IPersistentVector) form); + else if(form instanceof IPersistentMap) + return MapExpr.parse(context, (IPersistentMap) form); + else if(form instanceof IPersistentSet) + return SetExpr.parse(context, (IPersistentSet) form); // else //throw new UnsupportedOperationException(); @@ -7004,27 +7155,7 @@ public static class NewInstanceMethod extends ObjMethod{ try { Var.pushThreadBindings(RT.map(LOOP_LABEL, loopLabel, METHOD, this)); - MaybePrimitiveExpr be = (MaybePrimitiveExpr) body; - if(Util.isPrimitive(retClass) && be.canEmitPrimitive()) - { - if(be.getJavaClass() == retClass) - be.emitUnboxed(C.RETURN,obj,gen); - //todo - support the standard widening conversions - else - throw new IllegalArgumentException("Mismatched primitive return, expected: " - + retClass + ", had: " + be.getJavaClass()); - } - else - { - body.emit(C.RETURN, obj, gen); - if(retClass == void.class) - { - gen.pop(); - } - else - gen.unbox(retType); - } - + emitBody(objx, gen, retClass, body); Label end = gen.mark(); gen.visitLocalVariable("this", obj.objtype.getDescriptor(), null, loopLabel, end, 0); for(ISeq lbs = argLocals.seq(); lbs != null; lbs = lbs.next()) diff --git a/src/jvm/clojure/lang/LispReader.java b/src/jvm/clojure/lang/LispReader.java index 409ec858..1d95c741 100644 --- a/src/jvm/clojure/lang/LispReader.java +++ b/src/jvm/clojure/lang/LispReader.java @@ -330,7 +330,7 @@ private static Object matchNumber(String s){ { if(m.group(8) != null) return BigInteger.ZERO; - return new Long(0); + return Numbers.num(0); } boolean negate = (m.group(1).equals("-")); String n; diff --git a/src/jvm/clojure/lang/Numbers.java b/src/jvm/clojure/lang/Numbers.java index bdbe1612..722791fd 100644 --- a/src/jvm/clojure/lang/Numbers.java +++ b/src/jvm/clojure/lang/Numbers.java @@ -151,7 +151,7 @@ static Number quotient(double n, double d){ double q = n / d; if(q <= Long.MAX_VALUE && q >= Long.MIN_VALUE) { - return (long) q; + return box((long) q); } else { //bigint quotient @@ -163,12 +163,12 @@ static Number remainder(double n, double d){ double q = n / d; if(q <= Long.MAX_VALUE && q >= Long.MIN_VALUE) { - return (n - ((int) q) * d); + return Double.valueOf((n - ((int) q) * d)); } else { //bigint quotient Number bq = new BigDecimal(q).toBigInteger(); - return (n - bq.doubleValue() * d); + return Double.valueOf((n - bq.doubleValue() * d)); } } @@ -253,13 +253,32 @@ static public Number rationalize(Number x){ return x; } +static Number box(int val){ + return Integer.valueOf(val); +} + +static Number box(long val){ + if(val >= Integer.MIN_VALUE && val <= Integer.MAX_VALUE) + return Integer.valueOf((int) val); + else + return Long.valueOf(val); +} + +static Double box(double val){ + return Double.valueOf(val); +} + +static Double box(float val){ + return Double.valueOf((double) val); +} + static public Number reduceBigInteger(BigInteger val){ int bitLength = val.bitLength(); - if(bitLength < 32) - return val.intValue(); - else +// if(bitLength < 32) +// return val.intValue(); +// else if(bitLength < 64) - return val.longValue(); + return box(val.longValue()); else return val; } @@ -269,7 +288,7 @@ static public Number divide(BigInteger n, BigInteger d){ throw new ArithmeticException("Divide by zero"); BigInteger gcd = n.gcd(d); if(gcd.equals(BigInteger.ZERO)) - return 0; + return BigInteger.ZERO; n = n.divide(gcd); d = d.divide(gcd); if(d.equals(BigInteger.ONE)) @@ -329,11 +348,13 @@ static public Number shiftLeft(Object x, Object n){ return bitOps(x).shiftLeft((Number)x, ((Number)n).intValue()); } -static public int shiftLeft(int x, int n){ +static public int shiftLeftInt(int x, int n){ return x << n; } static public long shiftLeft(long x, int n){ + if(n < 0) + return shiftRight(x, -n); return x << n; } @@ -341,7 +362,13 @@ static public Number shiftRight(Object x, Object n){ return bitOps(x).shiftRight((Number)x, ((Number)n).intValue()); } -static public int shiftRight(int x, int n){ +static public int shiftRightInt(int x, int n){ + return x >> n; +} + +static public long shiftRight(long x, int n){ + if(n < 0) + return shiftLeft(x, -n); return x >> n; } @@ -383,11 +410,11 @@ final static class LongOps implements Ops{ } final public Number add(Number x, Number y){ - return Numbers.add(x.longValue(),y.longValue()); + return box(Numbers.add(x.longValue(),y.longValue())); } final public Number multiply(Number x, Number y){ - return Numbers.multiply(x.longValue(),y.longValue()); + return box(Numbers.multiply(x.longValue(), y.longValue())); } static long gcd(long u, long v){ @@ -405,12 +432,12 @@ final static class LongOps implements Ops{ long val = y.longValue(); long gcd = gcd(n, val); if(gcd == 0) - return 0; + return Integer.valueOf(0); n = n / gcd; long d = val / gcd; if(d == 1) - return n; + return box(n); if(d < 0) { n = -n; @@ -420,11 +447,11 @@ final static class LongOps implements Ops{ } public Number quotient(Number x, Number y){ - return x.longValue() / y.longValue(); + return box(x.longValue() / y.longValue()); } public Number remainder(Number x, Number y){ - return x.longValue() % y.longValue(); + return box(x.longValue() % y.longValue()); } public boolean equiv(Number x, Number y){ @@ -438,17 +465,17 @@ final static class LongOps implements Ops{ //public Number subtract(Number x, Number y); final public Number negate(Number x){ long val = x.longValue(); - return Numbers.minus(val); + return box(Numbers.minus(val)); } public Number inc(Number x){ long val = x.longValue(); - return Numbers.inc(val); + return box(Numbers.inc(val)); } public Number dec(Number x){ long val = x.longValue(); - return Numbers.dec(val); + return box(Numbers.dec(val)); } } @@ -490,15 +517,15 @@ final static class DoubleOps implements Ops{ } final public Number add(Number x, Number y){ - return x.doubleValue() + y.doubleValue(); + return Double.valueOf(x.doubleValue() + y.doubleValue()); } final public Number multiply(Number x, Number y){ - return x.doubleValue() * y.doubleValue(); + return Double.valueOf(x.doubleValue() * y.doubleValue()); } public Number divide(Number x, Number y){ - return x.doubleValue() / y.doubleValue(); + return Double.valueOf(x.doubleValue() / y.doubleValue()); } public Number quotient(Number x, Number y){ @@ -519,15 +546,15 @@ final static class DoubleOps implements Ops{ //public Number subtract(Number x, Number y); final public Number negate(Number x){ - return -x.doubleValue(); + return Double.valueOf(-x.doubleValue()); } public Number inc(Number x){ - return x.doubleValue() + 1; + return Double.valueOf(x.doubleValue() + 1); } public Number dec(Number x){ - return x.doubleValue() - 1; + return Double.valueOf(x.doubleValue() - 1); } } @@ -846,42 +873,42 @@ final static class LongBitOps implements BitOps{ } public Number not(Number x){ - return ~x.longValue(); + return box(~x.longValue()); } public Number and(Number x, Number y){ - return x.longValue() & y.longValue(); + return box(x.longValue() & y.longValue()); } public Number or(Number x, Number y){ - return x.longValue() | y.longValue(); + return box(x.longValue() | y.longValue()); } public Number xor(Number x, Number y){ - return x.longValue() ^ y.longValue(); + return box(x.longValue() ^ y.longValue()); } public Number andNot(Number x, Number y){ - return x.longValue() & ~y.longValue(); + return box(x.longValue() & ~y.longValue()); } public Number clearBit(Number x, int n){ if(n < 63) - return x.longValue() & ~(1L << n); + return (box(x.longValue() & ~(1L << n))); else return toBigInteger(x).clearBit(n); } public Number setBit(Number x, int n){ if(n < 63) - return x.longValue() | (1L << n); + return box(x.longValue() | (1L << n)); else return toBigInteger(x).setBit(n); } public Number flipBit(Number x, int n){ if(n < 63) - return x.longValue() ^ (1L << n); + return box(x.longValue() ^ (1L << n)); else return toBigInteger(x).flipBit(n); } @@ -896,13 +923,13 @@ final static class LongBitOps implements BitOps{ public Number shiftLeft(Number x, int n){ if(n < 0) return shiftRight(x, -n); - return Numbers.shiftLeft(x.longValue(),n); + return box(Numbers.shiftLeft(x.longValue(), n)); } public Number shiftRight(Number x, int n){ if(n < 0) return shiftLeft(x, -n); - return x.longValue() >> n; + return box(x.longValue() >> n); } } @@ -1319,71 +1346,71 @@ static public Number num(Object x){ } static public Number num(float x){ - return x; + return Double.valueOf(x); } -static public float add(float x, float y){ - return x + y; -} - -static public float minus(float x, float y){ - return x - y; -} +//static public float add(float x, float y){ +// return x + y; +//} +// +//static public float minus(float x, float y){ +// return x - y; +//} -static public float minus(float x){ - return -x; -} +//static public float minus(float x){ +// return -x; +//} -static public float inc(float x){ - return x + 1; -} +//static public float inc(float x){ +// return x + 1; +//} -static public float dec(float x){ - return x - 1; -} +//static public float dec(float x){ +// return x - 1; +//} -static public float multiply(float x, float y){ - return x * y; -} +//static public float multiply(float x, float y){ +// return x * y; +//} -static public float divide(float x, float y){ - return x / y; -} +//static public float divide(float x, float y){ +// return x / y; +//} -static public boolean equiv(float x, float y){ - return x == y; -} +//static public boolean equiv(float x, float y){ +// return x == y; +//} -static public boolean lt(float x, float y){ - return x < y; -} +//static public boolean lt(float x, float y){ +// return x < y; +//} -static public boolean lte(float x, float y){ - return x <= y; -} +//static public boolean lte(float x, float y){ +// return x <= y; +//} -static public boolean gt(float x, float y){ - return x > y; -} +//static public boolean gt(float x, float y){ +// return x > y; +//} -static public boolean gte(float x, float y){ - return x >= y; -} +//static public boolean gte(float x, float y){ +// return x >= y; +//} -static public boolean isPos(float x){ - return x > 0; -} +//static public boolean isPos(float x){ +// return x > 0; +//} -static public boolean isNeg(float x){ - return x < 0; -} +//static public boolean isNeg(float x){ +// return x < 0; +//} -static public boolean isZero(float x){ - return x == 0; -} +//static public boolean isZero(float x){ +// return x == 0; +//} static public Number num(double x){ - return x; + return Double.valueOf(x); } static public double add(double x, double y){ @@ -1451,168 +1478,168 @@ static int throwIntOverflow(){ } static public Number num(int x){ - return x; + return Integer.valueOf(x); } -static public int unchecked_add(int x, int y){ +static public int unchecked_int_add(int x, int y){ return x + y; } -static public int unchecked_subtract(int x, int y){ +static public int unchecked_int_subtract(int x, int y){ return x - y; } -static public int unchecked_negate(int x){ +static public int unchecked_int_negate(int x){ return -x; } -static public int unchecked_inc(int x){ +static public int unchecked_int_inc(int x){ return x + 1; } -static public int unchecked_dec(int x){ +static public int unchecked_int_dec(int x){ return x - 1; } -static public int unchecked_multiply(int x, int y){ +static public int unchecked_int_multiply(int x, int y){ return x * y; } -static public int add(int x, int y){ - int ret = x + y; - if ((ret ^ x) < 0 && (ret ^ y) < 0) - return throwIntOverflow(); - return ret; -} +//static public int add(int x, int y){ +// int ret = x + y; +// if ((ret ^ x) < 0 && (ret ^ y) < 0) +// return throwIntOverflow(); +// return ret; +//} -static public int not(int x){ - return ~x; -} +//static public int not(int x){ +// return ~x; +//} static public long not(long x){ return ~x; } -static public int and(int x, int y){ - return x & y; -} +//static public int and(int x, int y){ +// return x & y; +//} static public long and(long x, long y){ |