From 6ab3e4cd672092823a04c944210a23c29142785d Mon Sep 17 00:00:00 2001 From: Rich Hickey Date: Tue, 15 Jun 2010 23:13:05 -0400 Subject: Unify numeric semantics around longs, with throw on overflow. Allow numeric literals to be primitive initializers. Canonicalize boxing of integers, if it fits in int, is Integer, else Long, thus primitive coercions can't be used to get particular boxed types, use Long/valueOf etc. Ask for BigIntegers if you want arbitrary precision, new literal number format - append 'N' for BigInteger. BigIntegers do not reduce automatically, are contagious. New particular names for unchecked ops - unchecked-xxx-int or unchecked-xxx-long. You should need far fewer hints for primitive perf, and avoid int casts and any casting of numeric literals, see: http://gist.github.com/440102 --- src/clj/clojure/core.clj | 140 ++-- src/clj/clojure/genclass.clj | 6 +- src/clj/clojure/gvec.clj | 6 +- src/jvm/clojure/lang/Compiler.java | 483 ++++++++----- src/jvm/clojure/lang/LispReader.java | 2 +- src/jvm/clojure/lang/Numbers.java | 1258 +++++++++++++++++----------------- src/jvm/clojure/lang/Reflector.java | 21 +- 7 files changed, 1072 insertions(+), 844 deletions(-) (limited to 'src') diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj index 3ec651f0..157b25d7 100644 --- a/src/clj/clojure/core.clj +++ b/src/clj/clojure/core.clj @@ -970,61 +970,117 @@ :added "1.0"} [x] (. clojure.lang.Numbers (dec x))) -(defn unchecked-inc - "Returns a number one greater than x, an int or long. +(defn unchecked-inc-int + "Returns a number one greater than x, an int. Note - uses a primitive operator subject to overflow." - {:inline (fn [x] `(. clojure.lang.Numbers (unchecked_inc ~x))) + {:inline (fn [x] `(. clojure.lang.Numbers (unchecked_int_inc ~x))) :added "1.0"} - [x] (. clojure.lang.Numbers (unchecked_inc x))) + [x] (. clojure.lang.Numbers (unchecked_int_inc x))) -(defn unchecked-dec - "Returns a number one less than x, an int or long. +(defn unchecked-inc-long + "Returns a number one greater than x, a long. Note - uses a primitive operator subject to overflow." - {:inline (fn [x] `(. clojure.lang.Numbers (unchecked_dec ~x))) + {:inline (fn [x] `(. clojure.lang.Numbers (unchecked_long_inc ~x))) :added "1.0"} - [x] (. clojure.lang.Numbers (unchecked_dec x))) + [x] (. clojure.lang.Numbers (unchecked_long_inc x))) -(defn unchecked-negate - "Returns the negation of x, an int or long. +(defn unchecked-dec-int + "Returns a number one less than x, an int. Note - uses a primitive operator subject to overflow." - {:inline (fn [x] `(. clojure.lang.Numbers (unchecked_negate ~x))) + {:inline (fn [x] `(. clojure.lang.Numbers (unchecked_int_dec ~x))) :added "1.0"} - [x] (. clojure.lang.Numbers (unchecked_negate x))) + [x] (. clojure.lang.Numbers (unchecked_int_dec x))) -(defn unchecked-add - "Returns the sum of x and y, both int or long. +(defn unchecked-dec-long + "Returns a number one less than x, a long. Note - uses a primitive operator subject to overflow." - {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_add ~x ~y))) + {:inline (fn [x] `(. clojure.lang.Numbers (unchecked_long_dec ~x))) :added "1.0"} - [x y] (. clojure.lang.Numbers (unchecked_add x y))) + [x] (. clojure.lang.Numbers (unchecked_long_dec x))) -(defn unchecked-subtract - "Returns the difference of x and y, both int or long. +(defn unchecked-negate-int + "Returns the negation of x, an int. Note - uses a primitive operator subject to overflow." - {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_subtract ~x ~y))) + {:inline (fn [x] `(. clojure.lang.Numbers (unchecked_int_negate ~x))) :added "1.0"} - [x y] (. clojure.lang.Numbers (unchecked_subtract x y))) + [x] (. clojure.lang.Numbers (unchecked_int_negate x))) -(defn unchecked-multiply - "Returns the product of x and y, both int or long. +(defn unchecked-negate-long + "Returns the negation of x, a long. Note - uses a primitive operator subject to overflow." - {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_multiply ~x ~y))) + {:inline (fn [x] `(. clojure.lang.Numbers (unchecked_long_negate ~x))) :added "1.0"} - [x y] (. clojure.lang.Numbers (unchecked_multiply x y))) + [x] (. clojure.lang.Numbers (unchecked_long_negate x))) -(defn unchecked-divide - "Returns the division of x by y, both int or long. +(defn unchecked-add-int + "Returns the sum of x and y, both int. + Note - uses a primitive operator subject to overflow." + {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_int_add ~x ~y))) + :added "1.0"} + [x y] (. clojure.lang.Numbers (unchecked_int_add x y))) + +(defn unchecked-add-long + "Returns the sum of x and y, both long. + Note - uses a primitive operator subject to overflow." + {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_long_add ~x ~y))) + :added "1.0"} + [x y] (. clojure.lang.Numbers (unchecked_long_add x y))) + +(defn unchecked-subtract-int + "Returns the difference of x and y, both int. + Note - uses a primitive operator subject to overflow." + {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_int_subtract ~x ~y))) + :added "1.0"} + [x y] (. clojure.lang.Numbers (unchecked_int_subtract x y))) + +(defn unchecked-subtract-long + "Returns the difference of x and y, both long. + Note - uses a primitive operator subject to overflow." + {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_long_subtract ~x ~y))) + :added "1.0"} + [x y] (. clojure.lang.Numbers (unchecked_long_subtract x y))) + +(defn unchecked-multiply-int + "Returns the product of x and y, both int. + Note - uses a primitive operator subject to overflow." + {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_int_multiply ~x ~y))) + :added "1.0"} + [x y] (. clojure.lang.Numbers (unchecked_int_multiply x y))) + +(defn unchecked-multiply-long + "Returns the product of x and y, both long. + Note - uses a primitive operator subject to overflow." + {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_long_multiply ~x ~y))) + :added "1.0"} + [x y] (. clojure.lang.Numbers (unchecked_long_multiply x y))) + +(defn unchecked-divide-int + "Returns the division of x by y, both int. + Note - uses a primitive operator subject to truncation." + {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_int_divide ~x ~y))) + :added "1.0"} + [x y] (. clojure.lang.Numbers (unchecked_int_divide x y))) + +(defn unchecked-divide-long + "Returns the division of x by y, both long. + Note - uses a primitive operator subject to truncation." + {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_long_divide ~x ~y))) + :added "1.0"} + [x y] (. clojure.lang.Numbers (unchecked_long_divide x y))) + +(defn unchecked-remainder-int + "Returns the remainder of division of x by y, both int. Note - uses a primitive operator subject to truncation." - {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_divide ~x ~y))) + {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_int_remainder ~x ~y))) :added "1.0"} - [x y] (. clojure.lang.Numbers (unchecked_divide x y))) + [x y] (. clojure.lang.Numbers (unchecked_int_remainder x y))) -(defn unchecked-remainder - "Returns the remainder of division of x by y, both int or long. +(defn unchecked-remainder-long + "Returns the remainder of division of x by y, both long. Note - uses a primitive operator subject to truncation." - {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_remainder ~x ~y))) + {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_long_remainder ~x ~y))) :added "1.0"} - [x y] (. clojure.lang.Numbers (unchecked_remainder x y))) + [x y] (. clojure.lang.Numbers (unchecked_long_remainder x y))) (defn pos? "Returns true if num is greater than zero, else false" @@ -2183,11 +2239,11 @@ [bindings & body] (let [i (first bindings) n (second bindings)] - `(let [n# (int ~n)] + `(let [n# ~n] (loop [~i (int 0)] (when (< ~i n#) ~@body - (recur (inc ~i))))))) + (recur (unchecked-inc-long ~i))))))) (defn map "Returns a lazy sequence consisting of the result of applying f to the @@ -2553,17 +2609,17 @@ {:tag 'clojure.lang.IChunk}) count- (gensym "count_") i- (gensym "i_") - recform `(recur (next ~seq-) nil (int 0) (int 0)) + recform `(recur (next ~seq-) nil 0 0) steppair (step recform (nnext exprs)) needrec (steppair 0) subform (steppair 1) recform-chunk - `(recur ~seq- ~chunk- ~count- (unchecked-inc ~i-)) + `(recur ~seq- ~chunk- ~count- (unchecked-inc-long ~i-)) steppair-chunk (step recform-chunk (nnext exprs)) subform-chunk (steppair-chunk 1)] [true `(loop [~seq- (seq ~v), ~chunk- nil, - ~count- (int 0), ~i- (int 0)] + ~count- 0, ~i- 0] (if (< ~i- ~count-) (let [~k (.nth ~chunk- ~i-)] ~subform-chunk @@ -2660,11 +2716,11 @@ (= 2 (count bindings)) "exactly 2 forms in binding vector") (let [i (first bindings) n (second bindings)] - `(let [n# (int ~n)] - (loop [~i (int 0)] + `(let [n# ~n] + (loop [~i 0] (when (< ~i n#) ~@body - (recur (unchecked-inc ~i))))))) + (recur (unchecked-inc-long ~i))))))) #_(defn into "Returns a new coll consisting of to-coll with all of the items of @@ -3849,12 +3905,12 @@ (= k :when) `(if ~v ~(do-cmod etc) (recur - (unchecked-inc ~gi))) + (unchecked-inc-long ~gi))) (keyword? k) (err "Invalid 'for' keyword " k) :else `(do (chunk-append ~gb ~body-expr) - (recur (unchecked-inc ~gi)))))] + (recur (unchecked-inc-long ~gi)))))] `(fn ~giter [~gxs] (lazy-seq (loop [~gxs ~gxs] diff --git a/src/clj/clojure/genclass.clj b/src/clj/clojure/genclass.clj index bacc9277..a1e0fcdb 100644 --- a/src/clj/clojure/genclass.clj +++ b/src/clj/clojure/genclass.clj @@ -299,7 +299,7 @@ (arg-types (count ptypes))))) ;expecting [[super-ctor-args] state] returned (. gen dup) - (. gen push 0) + (. gen push (int 0)) (. gen (invokeStatic rt-type nth-method)) (. gen storeLocal local) @@ -307,14 +307,14 @@ (. gen dupX1) (dotimes [i (count super-pclasses)] (. gen loadLocal local) - (. gen push i) + (. gen push (int i)) (. gen (invokeStatic rt-type nth-method)) (. clojure.lang.Compiler$HostExpr (emitUnboxArg nil gen (nth super-pclasses i)))) (. gen (invokeConstructor super-type super-m)) (if state (do - (. gen push 1) + (. gen push (int 1)) (. gen (invokeStatic rt-type nth-method)) (. gen (putField ctype state-name obj-type))) (. gen pop)) diff --git a/src/clj/clojure/gvec.clj b/src/clj/clojure/gvec.clj index feff544a..bfebb2ea 100644 --- a/src/clj/clojure/gvec.clj +++ b/src/clj/clojure/gvec.clj @@ -62,11 +62,11 @@ (if (< aidx (count vec)) (let [node (.arrayFor vec aidx) result (loop [result result - node-idx (bit-and (int 0x1f) aidx)] + node-idx (bit-and 0x1f aidx)] (if (< node-idx (.alength am node)) (recur (f result (.aget am node node-idx)) (inc node-idx)) result))] - (recur result (bit-and (int 0xffe0) (+ aidx (int 32))))) + (recur result (bit-and 0xffe0 (+ aidx 32)))) result))) clojure.lang.ISeq @@ -141,7 +141,7 @@ (if (= i cnt) hash (let [val (.nth this i)] - (recur (unchecked-add (unchecked-multiply (int 31) hash) + (recur (unchecked-add-int (unchecked-multiply-int 31 hash) (clojure.lang.Util/hash val)) (inc i)))))) 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) 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) 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){ return x & y; } -static public int or(int x, int y){ - return x | y; -} +//static public int or(int x, int y){ +// return x | y; +//} static public long or(long x, long y){ return x | y; } -static public int xor(int x, int y){ - return x ^ y; -} +//static public int xor(int x, int y){ +// return x ^ y; +//} static public long xor(long x, long y){ return x ^ y; } -static public int minus(int x, int y){ - int ret = x - y; - if (((ret ^ x) < 0 && (ret ^ ~y) < 0)) - return throwIntOverflow(); - return ret; -} +//static public int minus(int x, int y){ +// int ret = x - y; +// if (((ret ^ x) < 0 && (ret ^ ~y) < 0)) +// return throwIntOverflow(); +// return ret; +//} -static public int minus(int x){ - if(x == Integer.MIN_VALUE) - return throwIntOverflow(); - return -x; -} +//static public int minus(int x){ +// if(x == Integer.MIN_VALUE) +// return throwIntOverflow(); +// return -x; +//} -static public int inc(int x){ - if(x == Integer.MAX_VALUE) - return throwIntOverflow(); - return x + 1; -} +//static public int inc(int x){ +// if(x == Integer.MAX_VALUE) +// return throwIntOverflow(); +// return x + 1; +//} -static public int dec(int x){ - if(x == Integer.MIN_VALUE) - return throwIntOverflow(); - return x - 1; -} +//static public int dec(int x){ +// if(x == Integer.MIN_VALUE) +// return throwIntOverflow(); +// return x - 1; +//} -static public int multiply(int x, int y){ - int ret = x * y; - if (y != 0 && ret/y != x) - return throwIntOverflow(); - return ret; -} +//static public int multiply(int x, int y){ +// int ret = x * y; +// if (y != 0 && ret/y != x) +// return throwIntOverflow(); +// return ret; +//} -static public int unchecked_divide(int x, int y){ +static public int unchecked_int_divide(int x, int y){ return x / y; } -static public int unchecked_remainder(int x, int y){ +static public int unchecked_int_remainder(int x, int y){ return x % y; } -static public boolean equiv(int x, int y){ - return x == y; -} +//static public boolean equiv(int x, int y){ +// return x == y; +//} -static public boolean lt(int x, int y){ - return x < y; -} +//static public boolean lt(int x, int y){ +// return x < y; +//} -static public boolean lte(int x, int y){ - return x <= y; -} +//static public boolean lte(int x, int y){ +// return x <= y; +//} -static public boolean gt(int x, int y){ - return x > y; -} +//static public boolean gt(int x, int y){ +// return x > y; +//} -static public boolean gte(int x, int y){ - return x >= y; -} +//static public boolean gte(int x, int y){ +// return x >= y; +//} -static public boolean isPos(int x){ - return x > 0; -} +//static public boolean isPos(int x){ +// return x > 0; +//} -static public boolean isNeg(int x){ - return x < 0; -} +//static public boolean isNeg(int x){ +// return x < 0; +//} -static public boolean isZero(int x){ - return x == 0; -} +//static public boolean isZero(int x){ +// return x == 0; +//} static public Number num(long x){ - return x; + return box(x); } -static public long unchecked_add(long x, long y){ +static public long unchecked_long_add(long x, long y){ return x + y; } -static public long unchecked_subtract(long x, long y){ +static public long unchecked_long_subtract(long x, long y){ return x - y; } -static public long unchecked_negate(long x){ +static public long unchecked_long_negate(long x){ return -x; } -static public long unchecked_inc(long x){ +static public long unchecked_long_inc(long x){ return x + 1; } -static public long unchecked_dec(long x){ +static public long unchecked_long_dec(long x){ return x - 1; } -static public long unchecked_multiply(long x, long y){ +static public long unchecked_long_multiply(long x, long y){ return x * y; } @@ -1655,11 +1682,11 @@ static public long multiply(long x, long y){ return ret; } -static public long unchecked_divide(long x, long y){ +static public long unchecked_long_divide(long x, long y){ return x / y; } -static public long unchecked_remainder(long x, long y){ +static public long unchecked_long_remainder(long x, long y){ return x % y; } @@ -3412,46 +3439,46 @@ static public class L{ //overload resolution +//* +//static public Number add(int x, Object y){ +// return add((Object)x,y); +//} -static public Number add(int x, Object y){ - return add((Object)x,y); -} - -static public Number add(Object x, int y){ - return add(x,(Object)y); -} +//static public Number add(Object x, int y){ +// return add(x,(Object)y); +//} -static public Number and(int x, Object y){ - return and((Object)x,y); -} +//static public Number and(int x, Object y){ +// return and((Object)x,y); +//} -static public Number and(Object x, int y){ - return and(x,(Object)y); -} +//static public Number and(Object x, int y){ +// return and(x,(Object)y); +//} -static public Number or(int x, Object y){ - return or((Object)x,y); -} +//static public Number or(int x, Object y){ +// return or((Object)x,y); +//} -static public Number or(Object x, int y){ - return or(x,(Object)y); -} +//static public Number or(Object x, int y){ +// return or(x,(Object)y); +//} -static public Number xor(int x, Object y){ - return xor((Object)x,y); -} +//static public Number xor(int x, Object y){ +// return xor((Object)x,y); +//} -static public Number xor(Object x, int y){ - return xor(x,(Object)y); -} +//static public Number xor(Object x, int y){ +// return xor(x,(Object)y); +//} -static public Number add(float x, Object y){ - return add((Object)x,y); -} +//static public Number add(float x, Object y){ +// return add((Object)x,y); +//} -static public Number add(Object x, float y){ - return add(x,(Object)y); -} +//static public Number add(Object x, float y){ +// return add(x,(Object)y); +//} static public Number add(long x, Object y){ return add((Object)x,y); @@ -3469,21 +3496,21 @@ static public Number add(Object x, double y){ return add(x,(Object)y); } -static public Number minus(int x, Object y){ - return minus((Object)x,y); -} +//static public Number minus(int x, Object y){ +// return minus((Object)x,y); +//} -static public Number minus(Object x, int y){ - return minus(x,(Object)y); -} +//static public Number minus(Object x, int y){ +// return minus(x,(Object)y); +//} -static public Number minus(float x, Object y){ - return minus((Object)x,y); -} +//static public Number minus(float x, Object y){ +// return minus((Object)x,y); +//} -static public Number minus(Object x, float y){ - return minus(x,(Object)y); -} +//static public Number minus(Object x, float y){ +// return minus(x,(Object)y); +//} static public Number minus(long x, Object y){ return minus((Object)x,y); @@ -3501,21 +3528,21 @@ static public Number minus(Object x, double y){ return minus(x,(Object)y); } -static public Number multiply(int x, Object y){ - return multiply((Object)x,y); -} +//static public Number multiply(int x, Object y){ +// return multiply((Object)x,y); +//} -static public Number multiply(Object x, int y){ - return multiply(x,(Object)y); -} +//static public Number multiply(Object x, int y){ +// return multiply(x,(Object)y); +//} -static public Number multiply(float x, Object y){ - return multiply((Object)x,y); -} +//static public Number multiply(float x, Object y){ +// return multiply((Object)x,y); +//} -static public Number multiply(Object x, float y){ - return multiply(x,(Object)y); -} +//static public Number multiply(Object x, float y){ +// return multiply(x,(Object)y); +//} static public Number multiply(long x, Object y){ return multiply((Object)x,y); @@ -3533,21 +3560,21 @@ static public Number multiply(Object x, double y){ return multiply(x,(Object)y); } -static public Number divide(int x, Object y){ - return divide((Object)x,y); -} +//static public Number divide(int x, Object y){ +// return divide((Object)x,y); +//} -static public Number divide(Object x, int y){ - return divide(x,(Object)y); -} +//static public Number divide(Object x, int y){ +// return divide(x,(Object)y); +//} -static public Number divide(float x, Object y){ - return divide((Object)x,y); -} +//static public Number divide(float x, Object y){ +// return divide((Object)x,y); +//} -static public Number divide(Object x, float y){ - return divide(x,(Object)y); -} +//static public Number divide(Object x, float y){ +// return divide(x,(Object)y); +//} static public Number divide(long x, Object y){ return divide((Object)x,y); @@ -3565,21 +3592,21 @@ static public Number divide(Object x, double y){ return divide(x,(Object)y); } -static public boolean lt(int x, Object y){ - return lt((Object)x,y); -} +//static public boolean lt(int x, Object y){ +// return lt((Object)x,y); +//} -static public boolean lt(Object x, int y){ - return lt(x,(Object)y); -} +//static public boolean lt(Object x, int y){ +// return lt(x,(Object)y); +//} -static public boolean lt(float x, Object y){ - return lt((Object)x,y); -} +//static public boolean lt(float x, Object y){ +// return lt((Object)x,y); +//} -static public boolean lt(Object x, float y){ - return lt(x,(Object)y); -} +//static public boolean lt(Object x, float y){ +// return lt(x,(Object)y); +//} static public boolean lt(long x, Object y){ return lt((Object)x,y); @@ -3597,21 +3624,21 @@ static public boolean lt(Object x, double y){ return lt(x,(Object)y); } -static public boolean lte(int x, Object y){ - return lte((Object)x,y); -} +//static public boolean lte(int x, Object y){ +// return lte((Object)x,y); +//} -static public boolean lte(Object x, int y){ - return lte(x,(Object)y); -} +//static public boolean lte(Object x, int y){ +// return lte(x,(Object)y); +//} -static public boolean lte(float x, Object y){ - return lte((Object)x,y); -} +//static public boolean lte(float x, Object y){ +// return lte((Object)x,y); +//} -static public boolean lte(Object x, float y){ - return lte(x,(Object)y); -} +//static public boolean lte(Object x, float y){ +// return lte(x,(Object)y); +//} static public boolean lte(long x, Object y){ return lte((Object)x,y); @@ -3629,21 +3656,21 @@ static public boolean lte(Object x, double y){ return lte(x,(Object)y); } -static public boolean gt(int x, Object y){ - return gt((Object)x,y); -} +//static public boolean gt(int x, Object y){ +// return gt((Object)x,y); +//} -static public boolean gt(Object x, int y){ - return gt(x,(Object)y); -} +//static public boolean gt(Object x, int y){ +// return gt(x,(Object)y); +//} -static public boolean gt(float x, Object y){ - return gt((Object)x,y); -} +//static public boolean gt(float x, Object y){ +// return gt((Object)x,y); +//} -static public boolean gt(Object x, float y){ - return gt(x,(Object)y); -} +//static public boolean gt(Object x, float y){ +// return gt(x,(Object)y); +//} static public boolean gt(long x, Object y){ return gt((Object)x,y); @@ -3661,21 +3688,21 @@ static public boolean gt(Object x, double y){ return gt(x,(Object)y); } -static public boolean gte(int x, Object y){ - return gte((Object)x,y); -} +//static public boolean gte(int x, Object y){ +// return gte((Object)x,y); +//} -static public boolean gte(Object x, int y){ - return gte(x,(Object)y); -} +//static public boolean gte(Object x, int y){ +// return gte(x,(Object)y); +//} -static public boolean gte(float x, Object y){ - return gte((Object)x,y); -} +//static public boolean gte(float x, Object y){ +// return gte((Object)x,y); +//} -static public boolean gte(Object x, float y){ - return gte(x,(Object)y); -} +//static public boolean gte(Object x, float y){ +// return gte(x,(Object)y); +//} static public boolean gte(long x, Object y){ return gte((Object)x,y); @@ -3694,21 +3721,21 @@ static public boolean gte(Object x, double y){ } -static public boolean equiv(int x, Object y){ - return equiv((Object)x,y); -} +//static public boolean equiv(int x, Object y){ +// return equiv((Object)x,y); +//} -static public boolean equiv(Object x, int y){ - return equiv(x,(Object)y); -} +//static public boolean equiv(Object x, int y){ +// return equiv(x,(Object)y); +//} -static public boolean equiv(float x, Object y){ - return equiv((Object)x,y); -} +//static public boolean equiv(float x, Object y){ +// return equiv((Object)x,y); +//} -static public boolean equiv(Object x, float y){ - return equiv(x,(Object)y); -} +//static public boolean equiv(Object x, float y){ +// return equiv(x,(Object)y); +//} static public boolean equiv(long x, Object y){ return equiv((Object)x,y); @@ -3726,430 +3753,431 @@ static public boolean equiv(Object x, double y){ return equiv(x,(Object)y); } +//*/ -static public float add(int x, float y){ - return add((float)x,y); -} +//static public float add(int x, float y){ +// return add((float)x,y); +//} -static public float add(float x, int y){ - return add(x,(float)y); -} +//static public float add(float x, int y){ +// return add(x,(float)y); +//} -static public double add(int x, double y){ - return add((double)x,y); -} +//static public double add(int x, double y){ +// return add((double)x,y); +//} -static public double add(double x, int y){ - return add(x,(double)y); -} +//static public double add(double x, int y){ +// return add(x,(double)y); +//} -static public long add(int x, long y){ - return add((long)x,y); -} +//static public long add(int x, long y){ +// return add((long)x,y); +//} -static public long add(long x, int y){ - return add(x,(long)y); -} +//static public long add(long x, int y){ +// return add(x,(long)y); +//} -static public float add(long x, float y){ - return add((float)x,y); -} +//static public float add(long x, float y){ +// return add((float)x,y); +//} -static public float add(float x, long y){ - return add(x,(float)y); -} +//static public float add(float x, long y){ +// return add(x,(float)y); +//} -static public double add(long x, double y){ - return add((double)x,y); -} +//static public double add(long x, double y){ +// return add((double)x,y); +//} -static public double add(double x, long y){ - return add(x,(double)y); -} +//static public double add(double x, long y){ +// return add(x,(double)y); +//} -static public double add(float x, double y){ - return add((double)x,y); -} +//static public double add(float x, double y){ +// return add((double)x,y); +//} -static public double add(double x, float y){ - return add(x,(double)y); -} +//static public double add(double x, float y){ +// return add(x,(double)y); +//} -static public float minus(int x, float y){ - return minus((float)x,y); -} +//static public float minus(int x, float y){ +// return minus((float)x,y); +//} -static public float minus(float x, int y){ - return minus(x,(float)y); -} +//static public float minus(float x, int y){ +// return minus(x,(float)y); +//} -static public double minus(int x, double y){ - return minus((double)x,y); -} +//static public double minus(int x, double y){ +// return minus((double)x,y); +//} -static public double minus(double x, int y){ - return minus(x,(double)y); -} +//static public double minus(double x, int y){ +// return minus(x,(double)y); +//} -static public long minus(int x, long y){ - return minus((long)x,y); -} +//static public long minus(int x, long y){ +// return minus((long)x,y); +//} -static public long minus(long x, int y){ - return minus(x,(long)y); -} +//static public long minus(long x, int y){ +// return minus(x,(long)y); +//} -static public float minus(long x, float y){ - return minus((float)x,y); -} +//static public float minus(long x, float y){ +// return minus((float)x,y); +//} -static public float minus(float x, long y){ - return minus(x,(float)y); -} +//static public float minus(float x, long y){ +// return minus(x,(float)y); +//} -static public double minus(long x, double y){ - return minus((double)x,y); -} +//static public double minus(long x, double y){ +// return minus((double)x,y); +//} -static public double minus(double x, long y){ - return minus(x,(double)y); -} +//static public double minus(double x, long y){ +// return minus(x,(double)y); +//} -static public double minus(float x, double y){ - return minus((double)x,y); -} +//static public double minus(float x, double y){ +// return minus((double)x,y); +//} -static public double minus(double x, float y){ - return minus(x,(double)y); -} +//static public double minus(double x, float y){ +// return minus(x,(double)y); +//} -static public float multiply(int x, float y){ - return multiply((float)x,y); -} +//static public float multiply(int x, float y){ +// return multiply((float)x,y); +//} -static public float multiply(float x, int y){ - return multiply(x,(float)y); -} +//static public float multiply(float x, int y){ +// return multiply(x,(float)y); +//} -static public double multiply(int x, double y){ - return multiply((double)x,y); -} +//static public double multiply(int x, double y){ +// return multiply((double)x,y); +//} -static public double multiply(double x, int y){ - return multiply(x,(double)y); -} +//static public double multiply(double x, int y){ +// return multiply(x,(double)y); +//} -static public long multiply(int x, long y){ - return multiply((long)x,y); -} +//static public long multiply(int x, long y){ +// return multiply((long)x,y); +//} -static public long multiply(long x, int y){ - return multiply(x,(long)y); -} +//static public long multiply(long x, int y){ +// return multiply(x,(long)y); +//} -static public float multiply(long x, float y){ - return multiply((float)x,y); -} +//static public float multiply(long x, float y){ +// return multiply((float)x,y); +//} -static public float multiply(float x, lon