summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/boot.clj177
-rw-r--r--src/jvm/clojure/lang/Compiler.java43
-rw-r--r--src/jvm/clojure/lang/Numbers.java410
-rw-r--r--src/jvm/clojure/lang/RT.java171
-rw-r--r--src/primmath.clj32
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] =