diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/boot.clj | 177 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Compiler.java | 43 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Numbers.java | 410 | ||||
-rw-r--r-- | src/jvm/clojure/lang/RT.java | 171 | ||||
-rw-r--r-- | src/primmath.clj | 32 |
5 files changed, 688 insertions, 145 deletions
diff --git a/src/boot.clj b/src/boot.clj index 96ab8804..7a2ba4f7 100644 --- a/src/boot.clj +++ b/src/boot.clj @@ -468,33 +468,41 @@ (defn * "Returns the product of nums. (*) returns 1." + {:inline (fn [x y] `(. clojure.lang.Numbers (multiply ~x ~y))) + :inline-arities #{2}} ([] 1) ([x] (cast Number x)) - ([x y] (. clojure.lang.Numbers (multiply x y))) + ([#^Number x #^Number y] (. clojure.lang.Numbers (multiply x y))) ([x y & more] (reduce * (* x y) more))) (defn / "If no denominators are supplied, returns 1/numerator, else returns numerator divided by all of the denominators." + {:inline (fn [x y] `(. clojure.lang.Numbers (divide ~x ~y))) + :inline-arities #{2}} ([x] (/ 1 x)) - ([x y] (. clojure.lang.Numbers (divide x y))) + ([#^Number x #^Number y] (. clojure.lang.Numbers (divide x y))) ([x y & more] (reduce / (/ x y) more))) (defn - "If no ys are supplied, returns the negation of x, else subtracts the ys from x and returns the result." - ([x] (. clojure.lang.Numbers (negate x))) - ([x y] (. clojure.lang.Numbers (subtract x y))) + {:inline (fn [& args] `(. clojure.lang.Numbers (minus ~@args))) + :inline-arities #{1 2}} + ([x] (. clojure.lang.Numbers (minus x))) + ([#^Number x #^Number y] (. clojure.lang.Numbers (minus x y))) ([x y & more] (reduce - (- x y) more))) (defn < "Returns non-nil if nums are in monotonically increasing order, otherwise false." + {:inline (fn [x y] `(. clojure.lang.Numbers (lt ~x ~y))) + :inline-arities #{2}} ([x] true) - ([x y] (. clojure.lang.Numbers (lt x y))) + ([#^Number x #^Number y] (. clojure.lang.Numbers (lt x y))) ([x y & more] (if (< x y) (if (rest more) @@ -505,8 +513,10 @@ (defn <= "Returns non-nil if nums are in monotonically non-decreasing order, otherwise false." + {:inline (fn [x y] `(. clojure.lang.Numbers (lte ~x ~y))) + :inline-arities #{2}} ([x] true) - ([x y] (. clojure.lang.Numbers (lte x y))) + ([#^Number x #^Number y] (. clojure.lang.Numbers (lte x y))) ([x y & more] (if (<= x y) (if (rest more) @@ -517,8 +527,10 @@ (defn > "Returns non-nil if nums are in monotonically decreasing order, otherwise false." + {:inline (fn [x y] `(. clojure.lang.Numbers (gt ~x ~y))) + :inline-arities #{2}} ([x] true) - ([x y] (. clojure.lang.Numbers (gt x y))) + ([#^Number x #^Number y] (. clojure.lang.Numbers (gt x y))) ([x y & more] (if (> x y) (if (rest more) @@ -529,8 +541,10 @@ (defn >= "Returns non-nil if nums are in monotonically non-increasing order, otherwise false." + {:inline (fn [x y] `(. clojure.lang.Numbers (gte ~x ~y))) + :inline-arities #{2}} ([x] true) - ([x y] (. clojure.lang.Numbers (gte x y))) + ([#^Number x #^Number y] (. clojure.lang.Numbers (gte x y))) ([x y & more] (if (>= x y) (if (rest more) @@ -540,8 +554,10 @@ (defn == "Returns non-nil if nums all have the same value, otherwise false" + {:inline (fn [x y] `(. clojure.lang.Numbers (equiv ~x ~y))) + :inline-arities #{2}} ([x] true) - ([x y] (. clojure.lang.Numbers (equiv x y))) + ([#^Number x #^Number y] (. clojure.lang.Numbers (equiv x y))) ([x y & more] (if (== x y) (if (rest more) @@ -565,25 +581,66 @@ (defn inc "Returns a number one greater than num." + {:inline (fn [x] `(. clojure.lang.Numbers (inc ~x)))} [x] (. clojure.lang.Numbers (inc x))) (defn dec "Returns a number one less than num." + {:inline (fn [x] `(. clojure.lang.Numbers (dec ~x)))} [x] (. clojure.lang.Numbers (dec x))) +(defn unchecked-inc + "Returns a number one greater than x, an int or long. + Note - uses a primitive operator subject to overflow." + {:inline (fn [x] `(. clojure.lang.Numbers (unchecked_inc ~x)))} + [x] (. clojure.lang.Numbers (unchecked_inc x))) + +(defn unchecked-dec + "Returns a number one less than x, an int or long. + Note - uses a primitive operator subject to overflow." + {:inline (fn [x] `(. clojure.lang.Numbers (unchecked_dec ~x)))} + [x] (. clojure.lang.Numbers (unchecked_dec x))) + +(defn unchecked-negate + "Returns the negation of x, an int or long. + Note - uses a primitive operator subject to overflow." + {:inline (fn [x] `(. clojure.lang.Numbers (unchecked_negate ~x)))} + [x] (. clojure.lang.Numbers (unchecked_negate x))) + +(defn unchecked-add + "Returns the sum of x and y, both int or long. + Note - uses a primitive operator subject to overflow." + {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_add ~x ~y)))} + [x y] (. clojure.lang.Numbers (unchecked_add x y))) + +(defn unchecked-subtract + "Returns the difference of x and y, both int or long. + Note - uses a primitive operator subject to overflow." + {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_subtract ~x ~y)))} + [x y] (. clojure.lang.Numbers (unchecked_subtract x y))) + +(defn unchecked-multiply + "Returns the product of x and y, both int or long. + Note - uses a primitive operator subject to overflow." + {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_multiply ~x ~y)))} + [x y] (. clojure.lang.Numbers (unchecked_multiply x y))) + (defn pos? "Returns true if num is greater than zero, else false" - {:tag Boolean} + {:tag Boolean + :inline (fn [x] `(. clojure.lang.Numbers (isPos ~x)))} [x] (. clojure.lang.Numbers (isPos x))) (defn neg? "Returns true if num is less than zero, else false" - {:tag Boolean} + {:tag Boolean + :inline (fn [x] `(. clojure.lang.Numbers (isNeg ~x)))} [x] (. clojure.lang.Numbers (isNeg x))) (defn zero? "Returns true if num is zero, else false" - {:tag Boolean} + {:tag Boolean + :inline (fn [x] `(. clojure.lang.Numbers (isZero ~x)))} [x] (. clojure.lang.Numbers (isZero x))) (defn quot @@ -1291,10 +1348,11 @@ not-every? (comp not every?)) "Repeatedly executes body (presumably for side-effects) with name bound to integers from 0 through n-1." [i n & body] - `(loop [~i 0 n# ~n] - (when (< ~i n#) - ~@body - (recur (inc ~i) n#)))) + `(let [n# (int ~n)] + (loop [~i (int 0)] + (when (< ~i n#) + ~@body + (recur (unchecked-inc ~i)))))) (defn import "import-list => (package-symbol class-name-symbols*) @@ -1433,7 +1491,7 @@ not-every? (comp not every?)) [expr] `(let [start# (. System (nanoTime)) ret# ~expr] - (prn (str "Elapsed time: " (/ (- (. System (nanoTime)) start#) 1000000.0) " msecs")) + (prn (str "Elapsed time: " (/ (double (- (. System (nanoTime)) start#)) 1000000.0) " msecs")) ret#)) (defn num @@ -1501,11 +1559,20 @@ not-every? (comp not every?)) (defn alength "Returns the length of the Java array. Works on arrays of all types." - [array] (. Array (getLength array))) + {:inline (fn [a] `(. clojure.lang.RT (alength ~a)))} + [array] (. clojure.lang.RT (alength array))) + +(defn aclone + "Returns a clone of the Java array. Works on arrays of known + types." + {:inline (fn [a] `(. clojure.lang.RT (aclone ~a)))} + [array] (. clojure.lang.RT (aclone array))) (defn aget "Returns the value at the index/indices. Works on Java arrays of all types." + {:inline (fn [a i] `(. clojure.lang.RT (aget ~a ~i))) + :inline-arities #{2}} ([array idx] (. Array (get array idx))) ([array idx & idxs] @@ -1514,6 +1581,8 @@ not-every? (comp not every?)) (defn aset "Sets the value at the index/indices. Works on Java arrays of reference types. Returns val." + {:inline (fn [a i v] `(. clojure.lang.RT (aset ~a ~i ~v))) + :inline-arities #{3}} ([array idx val] (. Array (set array idx val)) val) @@ -2443,4 +2512,74 @@ not-every? (comp not every?)) (defn empty "Returns an empty collection of the same category as coll, or nil" [#^clojure.lang.IPersistentCollection coll] - (.empty coll))
\ No newline at end of file + (.empty coll)) + +(defmacro amap + "Maps an expression across an array a, using an index named idx, and + return value named ret, initialized to a clone of a, then setting each element of + ret to the evaluation of expr, returning the new array ret." + [a idx ret expr] + `(let [a# ~a + ~ret (aclone a#)] + (loop [~idx (int 0)] + (if (< ~idx (alength a#)) + (do + (aset ~ret ~idx ~expr) + (recur (unchecked-inc ~idx))) + ~ret)))) + +(defmacro areduce + "Reduces an expression across an array a, using an index named idx, + and return value named ret, initialized to init, setting ret to the evaluation of expr at + each step, returning ret." + [a idx ret init expr] + `(let [a# ~a] + (loop [~idx (int 0) ~ret ~init] + (if (< ~idx (alength a#)) + (recur (unchecked-inc ~idx) ~expr) + ~ret)))) + +(defn float-array + "Creates an array of floats" + {:inline (fn [& args] `(. clojure.lang.Numbers float_array ~@args)) + :inline-arities #{1 2}} + ([size-or-seq] (. clojure.lang.Numbers float_array size-or-seq)) + ([size init-val-or-seq] (. clojure.lang.Numbers float_array size init-val-or-seq))) + +(defn double-array + "Creates an array of doubles" + {:inline (fn [& args] `(. clojure.lang.Numbers double_array ~@args)) + :inline-arities #{1 2}} + ([size-or-seq] (. clojure.lang.Numbers double_array size-or-seq)) + ([size init-val-or-seq] (. clojure.lang.Numbers double_array size init-val-or-seq))) + +(defn int-array + "Creates an array of ints" + {:inline (fn [& args] `(. clojure.lang.Numbers int_array ~@args)) + :inline-arities #{1 2}} + ([size-or-seq] (. clojure.lang.Numbers int_array size-or-seq)) + ([size init-val-or-seq] (. clojure.lang.Numbers int_array size init-val-or-seq))) + +(defn long-array + "Creates an array of ints" + {:inline (fn [& args] `(. clojure.lang.Numbers long_array ~@args)) + :inline-arities #{1 2}} + ([size-or-seq] (. clojure.lang.Numbers long_array size-or-seq)) + ([size init-val-or-seq] (. clojure.lang.Numbers long_array size init-val-or-seq))) + +(definline floats + "Casts to float[]" + [xs] `(. clojure.lang.Numbers floats ~xs)) + +(definline ints + "Casts to int[]" + [xs] `(. clojure.lang.Numbers ints ~xs)) + +(definline doubles + "Casts to double[]" + [xs] `(. clojure.lang.Numbers doubles ~xs)) + +(definline longs + "Casts to long[]" + [xs] `(. clojure.lang.Numbers longs ~xs)) + diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java index 99c7b660..c1961f78 100644 --- a/src/jvm/clojure/lang/Compiler.java +++ b/src/jvm/clojure/lang/Compiler.java @@ -12,13 +12,13 @@ package clojure.lang; -/* +//* import clojure.asm.*; import clojure.asm.commons.Method; import clojure.asm.commons.GeneratorAdapter; -/*/ -//* +//*/ +/* import org.objectweb.asm.*; import org.objectweb.asm.commons.Method; @@ -733,15 +733,23 @@ static public abstract class HostExpr implements Expr, MaybePrimitiveExpr{ Symbol sym = (Symbol) form; if(sym.ns == null) //if ns-qualified can't be classname { -// if(sym.name.equals("int")) -// c = int.class; -// else if(sym.name.equals("long")) -// c = long.class; -// else if(sym.name.equals("float")) -// c = float.class; -// else if(sym.name.equals("double")) -// c = double.class; -// else + if(sym.name.equals("ints")) + c = int[].class; + else if(sym.name.equals("longs")) + c = long[].class; + else if(sym.name.equals("floats")) + c = float[].class; + else if(sym.name.equals("doubles")) + c = double[].class; + else if(sym.name.equals("chars")) + c = double[].class; + else if(sym.name.equals("shorts")) + c = short[].class; + else if(sym.name.equals("bytes")) + c = byte[].class; + else if(sym.name.equals("booleans")) + c = boolean[].class; + else if(sym.name.indexOf('.') > 0 || sym.name.charAt(0) == '[') c = RT.classForName(sym.name); else @@ -1875,8 +1883,8 @@ static boolean subsumes(Class[] c1, Class[] c2){ if(!(c1[i] == c2[i] || c2[i].isPrimitive() && c1[i] == Object.class)) { if(c1[i].isPrimitive() && c2[i] == Object.class -// || Number.class.isAssignableFrom(c1[i]) && c2[i].isPrimitive() -|| c2[i].isAssignableFrom(c1[i])) + //|| Number.class.isAssignableFrom(c1[i]) && c2[i].isPrimitive() + || c2[i].isAssignableFrom(c1[i])) better = true; else return false; @@ -2302,6 +2310,7 @@ static class EmptyExpr implements Expr{ final static Type HASHSET_TYPE = Type.getType(PersistentHashSet.class); final static Type VECTOR_TYPE = Type.getType(PersistentVector.class); final static Type LIST_TYPE = Type.getType(PersistentList.class); + final static Type EMPTY_LIST_TYPE = Type.getType(PersistentList.EmptyList.class); public EmptyExpr(Object coll){ @@ -2314,7 +2323,7 @@ static class EmptyExpr implements Expr{ public void emit(C context, FnExpr fn, GeneratorAdapter gen){ if(coll instanceof IPersistentList) - gen.getStatic(LIST_TYPE, "EMPTY", LIST_TYPE); + gen.getStatic(LIST_TYPE, "EMPTY", EMPTY_LIST_TYPE); else if(coll instanceof IPersistentVector) gen.getStatic(VECTOR_TYPE, "EMPTY", VECTOR_TYPE); else if(coll instanceof IPersistentMap) @@ -2743,8 +2752,8 @@ static public class FnExpr implements Expr{ //derived from AFn/RestFn ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); // ClassWriter cw = new ClassWriter(0); - //ClassVisitor cv = cw; - ClassVisitor cv = new TraceClassVisitor(new CheckClassAdapter(cw), new PrintWriter(System.out)); + ClassVisitor cv = cw; + //ClassVisitor cv = new TraceClassVisitor(new CheckClassAdapter(cw), new PrintWriter(System.out)); //ClassVisitor cv = new TraceClassVisitor(cw, new PrintWriter(System.out)); cv.visit(V1_5, ACC_PUBLIC, internalName, null, isVariadic() ? "clojure/lang/RestFn" : "clojure/lang/AFn", null); String source = (String) SOURCE.get(); diff --git a/src/jvm/clojure/lang/Numbers.java b/src/jvm/clojure/lang/Numbers.java index 6e469f31..44984f06 100644 --- a/src/jvm/clojure/lang/Numbers.java +++ b/src/jvm/clojure/lang/Numbers.java @@ -99,48 +99,48 @@ static interface BitOps{ } -static public boolean isZero(Number x){ - return ops(x).isZero(x); +static public boolean isZero(Object x){ + return ops(x).isZero((Number)x); } -static public boolean isPos(Number x){ - return ops(x).isPos(x); +static public boolean isPos(Object x){ + return ops(x).isPos((Number)x); } -static public boolean isNeg(Number x){ - return ops(x).isNeg(x); +static public boolean isNeg(Object x){ + return ops(x).isNeg((Number)x); } -static public Number negate(Number x){ - return ops(x).negate(x); +static public Number minus(Object x){ + return ops(x).negate((Number)x); } -static public Number inc(Number x){ - return ops(x).inc(x); +static public Number inc(Object x){ + return ops(x).inc((Number)x); } -static public Number dec(Number x){ - return ops(x).dec(x); +static public Number dec(Object x){ + return ops(x).dec((Number)x); } -static public Number add(Number x, Number y){ - return ops(x).combine(ops(y)).add(x, y); +static public Number add(Object x, Object y){ + return ops(x).combine(ops(y)).add((Number)x, (Number)y); } -static public Number subtract(Number x, Number y){ +static public Number minus(Object x, Object y){ Ops yops = ops(y); - return ops(x).combine(yops).add(x, yops.negate(y)); + return ops(x).combine(yops).add((Number)x, yops.negate((Number)y)); } -static public Number multiply(Number x, Number y){ - return ops(x).combine(ops(y)).multiply(x, y); +static public Number multiply(Object x, Object y){ + return ops(x).combine(ops(y)).multiply((Number)x, (Number)y); } -static public Number divide(Number x, Number y){ +static public Number divide(Object x, Object y){ Ops yops = ops(y); - if(yops.isZero(y)) + if(yops.isZero((Number)y)) throw new ArithmeticException("Divide by zero"); - return ops(x).combine(yops).divide(x, y); + return ops(x).combine(yops).divide((Number)x, (Number)y); } static public Number quotient(Number x, Number y){ @@ -191,20 +191,20 @@ static public boolean equiv(Number x, Number y){ return ops(x).combine(ops(y)).equiv(x, y); } -static public boolean lt(Number x, Number y){ - return ops(x).combine(ops(y)).lt(x, y); +static public boolean lt(Object x, Object y){ + return ops(x).combine(ops(y)).lt((Number)x, (Number)y); } -static public boolean lte(Number x, Number y){ - return !ops(x).combine(ops(y)).lt(y, x); +static public boolean lte(Object x, Object y){ + return !ops(x).combine(ops(y)).lt((Number)y, (Number)x); } -static public boolean gt(Number x, Number y){ - return ops(x).combine(ops(y)).lt(y, x); +static public boolean gt(Object x, Object y){ + return ops(x).combine(ops(y)).lt((Number)y, (Number)x); } -static public boolean gte(Number x, Number y){ - return !ops(x).combine(ops(y)).lt(x, y); +static public boolean gte(Object x, Object y){ + return !ops(x).combine(ops(y)).lt((Number)x, (Number)y); } static public int compare(Number x, Number y){ @@ -713,7 +713,7 @@ final static class RatioOps implements Ops{ Ratio ry = toRatio(y); BigInteger q = rx.numerator.multiply(ry.denominator).divide( rx.denominator.multiply(ry.numerator)); - return Numbers.subtract(x, Numbers.multiply(q, y)); + return Numbers.minus(x, Numbers.multiply(q, y)); } public boolean equiv(Number x, Number y){ @@ -1250,67 +1250,212 @@ static BitOps bitOps(Object x){ // executor.invokeAll(ops); // } + + static public float[] float_array(int size, Object init){ + float[] ret = new float[size]; + if(init instanceof Number) + { + float f = ((Number) init).floatValue(); + for(int i = 0; i < ret.length; i++) + ret[i] = f; + } + else + { + ISeq s = RT.seq(init); + for(int i = 0; i < size && s != null; i++, s = s.rest()) + ret[i] = ((Number) s.first()).floatValue(); + } + return ret; + } + + static public float[] float_array(Object sizeOrSeq){ + if(sizeOrSeq instanceof Number) + return new float[((Number) sizeOrSeq).intValue()]; + else + { + ISeq s = RT.seq(sizeOrSeq); + int size = s.count(); + float[] ret = new float[size]; + for(int i = 0; i < size && s != null; i++, s = s.rest()) + ret[i] = ((Number) s.first()).intValue(); + return ret; + } + } + +static public double[] double_array(int size, Object init){ + double[] ret = new double[size]; + if(init instanceof Number) + { + double f = ((Number) init).doubleValue(); + for(int i = 0; i < ret.length; i++) + ret[i] = f; + } + else + { + ISeq s = RT.seq(init); + for(int i = 0; i < size && s != null; i++, s = s.rest()) + ret[i] = ((Number) s.first()).doubleValue(); + } + return ret; +} + +static public double[] double_array(Object sizeOrSeq){ + if(sizeOrSeq instanceof Number) + return new double[((Number) sizeOrSeq).intValue()]; + else + { + ISeq s = RT.seq(sizeOrSeq); + int size = s.count(); + double[] ret = new double[size]; + for(int i = 0; i < size && s != null; i++, s = s.rest()) + ret[i] = ((Number) s.first()).intValue(); + return ret; + } +} + +static public int[] int_array(int size, Object init){ + int[] ret = new int[size]; + if(init instanceof Number) + { + int f = ((Number) init).intValue(); + for(int i = 0; i < ret.length; i++) + ret[i] = f; + } + else + { + ISeq s = RT.seq(init); + for(int i = 0; i < size && s != null; i++, s = s.rest()) + ret[i] = ((Number) s.first()).intValue(); + } + return ret; +} + +static public int[] int_array(Object sizeOrSeq){ + if(sizeOrSeq instanceof Number) + return new int[((Number) sizeOrSeq).intValue()]; + else + { + ISeq s = RT.seq(sizeOrSeq); + int size = s.count(); + int[] ret = new int[size]; + for(int i = 0; i < size && s != null; i++, s = s.rest()) + ret[i] = ((Number) s.first()).intValue(); + return ret; + } +} + +static public long[] long_array(int size, Object init){ + long[] ret = new long[size]; + if(init instanceof Number) + { + long f = ((Number) init).longValue(); + for(int i = 0; i < ret.length; i++) + ret[i] = f; + } + else + { + ISeq s = RT.seq(init); + for(int i = 0; i < size && s != null; i++, s = s.rest()) + ret[i] = ((Number) s.first()).longValue(); + } + return ret; +} + +static public long[] long_array(Object sizeOrSeq){ + if(sizeOrSeq instanceof Number) + return new long[((Number) sizeOrSeq).intValue()]; + else + { + ISeq s = RT.seq(sizeOrSeq); + int size = s.count(); + long[] ret = new long[size]; + for(int i = 0; i < size && s != null; i++, s = s.rest()) + ret[i] = ((Number) s.first()).intValue(); + return ret; + } +} + +static public float[] floats(Object array){ + return (float[]) array; +} + +static public double[] doubles(Object array){ + return (double[]) array; +} + +static public int[] ints(Object array){ + return (int[]) array; +} + +static public long[] longs(Object array){ + return (long[]) array; +} + +static public Number num(Object x){ + return (Number) x; +} + static public Number num(float x){ return x; } -static public float prim_add(float x, float y){ +static public float add(float x, float y){ return x + y; } -static public float prim_subtract(float x, float y){ +static public float minus(float x, float y){ return x - y; } -static public float prim_negate(float x){ +static public float minus(float x){ return -x; } -static public float prim_inc(float x){ +static public float inc(float x){ return x + 1; } -static public float prim_dec(float x){ +static public float dec(float x){ return x - 1; } -static public float prim_multiply(float x, float y){ +static public float multiply(float x, float y){ return x * y; } -static public float prim_divide(float x, float y){ +static public float divide(float x, float y){ return x / y; } -static public boolean prim_equiv(float x, float y){ +static public boolean equiv(float x, float y){ return x == y; } -static public boolean prim_lt(float x, float y){ +static public boolean lt(float x, float y){ return x < y; } -static public boolean prim_lte(float x, float y){ +static public boolean lte(float x, float y){ return x <= y; } -static public boolean prim_gt(float x, float y){ +static public boolean gt(float x, float y){ return x > y; } -static public boolean prim_gte(float x, float y){ +static public boolean gte(float x, float y){ return x >= y; } -static public boolean prim_isPos(float x){ +static public boolean isPos(float x){ return x > 0; } -static public boolean prim_isNeg(float x){ +static public boolean isNeg(float x){ return x < 0; } -static public boolean prim_isZero(float x){ +static public boolean isZero(float x){ return x == 0; } @@ -1318,127 +1463,170 @@ static public Number num(double x){ return x; } -static public double prim_add(double x, double y){ +static public double add(double x, double y){ return x + y; } -static public double prim_subtract(double x, double y){ +static public double minus(double x, double y){ return x - y; } -static public double prim_negate(double x){ +static public double minus(double x){ return -x; } -static public double prim_inc(double x){ +static public double inc(double x){ return x + 1; } -static public double prim_dec(double x){ +static public double dec(double x){ return x - 1; } -static public double prim_multiply(double x, double y){ +static public double multiply(double x, double y){ return x * y; } -static public double prim_divide(double x, double y){ +static public double divide(double x, double y){ return x / y; } -static public boolean prim_equiv(double x, double y){ +static public boolean equiv(double x, double y){ return x == y; } -static public boolean prim_lt(double x, double y){ +static public boolean lt(double x, double y){ return x < y; } -static public boolean prim_lte(double x, double y){ +static public boolean lte(double x, double y){ return x <= y; } -static public boolean prim_gt(double x, double y){ +static public boolean gt(double x, double y){ return x > y; } -static public boolean prim_gte(double x, double y){ +static public boolean gte(double x, double y){ return x >= y; } -static public boolean prim_isPos(double x){ +static public boolean isPos(double x){ return x > 0; } -static public boolean prim_isNeg(double x){ +static public boolean isNeg(double x){ return x < 0; } -static public boolean prim_isZero(double x){ +static public boolean isZero(double x){ return x == 0; } +static int throwIntOverflow(){ + throw new ArithmeticException("integer overflow"); +} + static public Number num(int x){ return x; } -static public int prim_add(int x, int y){ +static public int unchecked_add(int x, int y){ return x + y; } -static public int prim_subtract(int x, int y){ +static public int unchecked_subtract(int x, int y){ return x - y; } -static public int prim_negate(int x){ +static public int unchecked_negate(int x){ return -x; } -static public int prim_inc(int x){ +static public int unchecked_inc(int x){ return x + 1; } -static public int prim_dec(int x){ +static public int unchecked_dec(int x){ return x - 1; } -static public int prim_multiply(int x, int y){ +static public int unchecked_multiply(int x, int y){ return x * y; } -static public int prim_divide(int x, int 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 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 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 multiply(int x, int y){ + int ret = x * y; + if (y != 0 && ret/y != x) + return throwIntOverflow(); + return ret; +} + +static public int divide(int x, int y){ return x / y; } -static public boolean prim_equiv(int x, int y){ +static public boolean equiv(int x, int y){ return x == y; } -static public boolean prim_lt(int x, int y){ +static public boolean lt(int x, int y){ return x < y; } -static public boolean prim_lte(int x, int y){ +static public boolean lte(int x, int y){ return x <= y; } -static public boolean prim_gt(int x, int y){ +static public boolean gt(int x, int y){ return x > y; } -static public boolean prim_gte(int x, int y){ +static public boolean gte(int x, int y){ return x >= y; } -static public boolean prim_isPos(int x){ +static public boolean isPos(int x){ return x > 0; } -static public boolean prim_isNeg(int x){ +static public boolean isNeg(int x){ return x < 0; } -static public boolean prim_isZero(int x){ +static public boolean isZero(int x){ return x == 0; } @@ -1446,66 +1634,106 @@ static public Number num(long x){ return x; } -static public long prim_add(long x, long y){ +static public long unchecked_add(long x, long y){ return x + y; } -static public long prim_subtract(long x, long y){ +static public long unchecked_subtract(long x, long y){ return x - y; } -static public long prim_negate(long x){ +static public long unchecked_negate(long x){ return -x; } -static public long prim_inc(long x){ +static public long unchecked_inc(long x){ return x + 1; } -static public long prim_dec(long x){ +static public long unchecked_dec(long x){ return x - 1; } -static public long prim_multiply(long x, long y){ +static public long unchecked_multiply(long x, long y){ return x * y; } -static public long prim_divide(long x, long y){ +static public long add(long x, long y){ + long ret = x + y; + if ((ret ^ x) < 0 && (ret ^ y) < 0) + return throwIntOverflow(); + return ret; +} + +static public long minus(long x, long y){ + long ret = x - y; + if ((ret ^ x) < 0 && (ret ^ -y) < 0) + return throwIntOverflow(); + return ret; +} + +static public long minus(long x){ + if(x == Integer.MIN_VALUE) + return throwIntOverflow(); + return -x; +} + +static public long inc(long x){ + if(x == Integer.MAX_VALUE) + return throwIntOverflow(); + return x + 1; +} + +static public long dec(long x){ + if(x == Integer.MIN_VALUE) + return throwIntOverflow(); + return x - 1; +} + +static public long multiply(long x, long y){ + long ret = x * y; + if (y != 0 && ret/y != x) + return throwIntOverflow(); + return ret; +} + +static public long divide(long x, long y){ return x / y; } -static public boolean prim_equiv(long x, long y){ +static public boolean equiv(long x, long y){ return x == y; } -static public boolean prim_lt(long x, long y){ +static public boolean lt(long x, long y){ return x < y; } -static public boolean prim_lte(long x, long y){ +static public boolean lte(long x, long y){ return x <= y; } -static public boolean prim_gt(long x, long y){ +static public boolean gt(long x, long y){ return x > y; } -static public boolean prim_gte(long x, long y){ +static public boolean gte(long x, long y){ return x >= y; } -static public boolean prim_isPos(long x){ +static public boolean isPos(long x){ return x > 0; } -static public boolean prim_isNeg(long x){ +static public boolean isNeg(long x){ return x < 0; } -static public boolean prim_isZero(long x){ +static public boolean isZero(long x){ return x == 0; } +/* static public class F{ static public float add(float x, float y){ return x + y; @@ -3218,5 +3446,5 @@ static public class L{ } } - +*/ } diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java index 75f831a8..0cf2e852 100644 --- a/src/jvm/clojure/lang/RT.java +++ b/src/jvm/clojure/lang/RT.java @@ -286,10 +286,10 @@ static public void init() throws Exception{ static void doInit() throws Exception{ loadResourceScript(RT.class, "boot.clj"); - loadResourceScript(RT.class, "primmath.clj"); + //loadResourceScript(RT.class, "primmath.clj"); loadResourceScript(RT.class, "proxy.clj"); loadResourceScript(RT.class, "zip.clj"); - //loadResourceScript(RT.class, "xml.clj"); + loadResourceScript(RT.class, "xml.clj"); loadResourceScript(RT.class, "set.clj"); Var.pushThreadBindings( @@ -1288,4 +1288,171 @@ static public Class classForName(String name) throws ClassNotFoundException{ return Class.forName(name, false, RT.ROOT_CLASSLOADER); } + +static public float aget(float[] xs, int i){ + return xs[i]; +} + +static public float aset(float[] xs, int i, float v){ + xs[i] = v; + return v; +} + +static public int alength(float[] xs){ + return xs.length; +} + +static public float[] aclone(float[] xs){ + return xs.clone(); +} + +static public double aget(double[] xs, int i){ + return xs[i]; +} + +static public double aset(double[] xs, int i, double v){ + xs[i] = v; + return v; +} + +static public int alength(double[] xs){ + return xs.length; +} + +static public double[] aclone(double[] xs){ + return xs.clone(); +} + +static public int aget(int[] xs, int i){ + return xs[i]; +} + +static public int aset(int[] xs, int i, int v){ + xs[i] = v; + return v; +} + +static public int alength(int[] xs){ + return xs.length; +} + +static public int[] aclone(int[] xs){ + return xs.clone(); +} + +static public long aget(long[] xs, int i){ + return xs[i]; +} + +static public long aset(long[] xs, int i, long v){ + xs[i] = |