summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2007-09-15 21:29:29 +0000
committerRich Hickey <richhickey@gmail.com>2007-09-15 21:29:29 +0000
commit8cbacf156a7a42c7ff1a816783e1afda1781becb (patch)
tree304bdd22103301c07f709a0f7b51cdc24cd637a9
parentcccaea9bcb03f737d79581284b51d7e99384d5ea (diff)
compiling non-arity-overloaded static methods to direct calls
-rw-r--r--src/boot.clj10
-rw-r--r--src/jvm/clojure/lang/BigNum.java219
-rw-r--r--src/jvm/clojure/lang/Compiler.java39
-rw-r--r--src/jvm/clojure/lang/DoubleNum.java222
-rw-r--r--src/jvm/clojure/lang/FixNum.java219
-rw-r--r--src/jvm/clojure/lang/Num.java119
-rw-r--r--src/jvm/clojure/lang/OldCompiler.java6
-rw-r--r--src/jvm/clojure/lang/RT.java2
-rw-r--r--src/jvm/clojure/lang/RatioNum.java208
9 files changed, 456 insertions, 588 deletions
diff --git a/src/boot.clj b/src/boot.clj
index 3005a182..f5889648 100644
--- a/src/boot.clj
+++ b/src/boot.clj
@@ -162,19 +162,19 @@
(and (thisfn x y) (apply thisfn y rest))))
(defn inc [x]
- (. x (onePlus)))
+ (. Num (inc x)))
(defn dec [x]
- (. x (oneMinus)))
+ (. Num (dec x)))
(defn pos? [x]
- (. x (plusp)))
+ (. Num (posPred x)))
(defn neg? [x]
- (. x (minusp)))
+ (. Num (negPred x)))
(defn zero? [x]
- (== x 0))
+ (. Num (zeroPred x)))
(defn complement [f]
(fn [& args]
diff --git a/src/jvm/clojure/lang/BigNum.java b/src/jvm/clojure/lang/BigNum.java
index 52fa5151..aaa862d1 100644
--- a/src/jvm/clojure/lang/BigNum.java
+++ b/src/jvm/clojure/lang/BigNum.java
@@ -17,204 +17,169 @@ import java.math.BigInteger;
public class BigNum extends IntegerNum{
public BigInteger val;
-public boolean equals(Object arg0)
- {
+public boolean equals(Object arg0){
return arg0 != null
&& arg0 instanceof BigNum
&& ((BigNum) arg0).val == val;
- }
+}
-public int hashCode()
- {
+public int hashCode(){
return val.hashCode();
- }
+}
-public String toString()
- {
+public String toString(){
return val.toString();
- }
+}
-public BigNum(long val)
- {
+public BigNum(long val){
this.val = BigInteger.valueOf(val);
- }
+}
-public BigNum(BigInteger val)
- {
+public BigNum(BigInteger val){
this.val = val;
- }
+}
-public double doubleValue()
- {
+public double doubleValue(){
return val.doubleValue();
- }
+}
-public float floatValue()
- {
+public float floatValue(){
return val.floatValue();
- }
+}
-public int intValue()
- {
+public int intValue(){
return val.intValue();
- }
+}
-public long longValue()
- {
+public long longValue(){
return val.longValue();
- }
+}
-public boolean equiv(Num rhs)
- {
+public boolean equiv(Num rhs){
return rhs.equivTo(val);
- }
+}
-public boolean equivTo(BigInteger x)
- {
+public boolean equivTo(BigInteger x){
return x.equals(val);
- }
+}
-public boolean equivTo(int x)
- {
+public boolean equivTo(int x){
//must be outside of range of int or would be one itself
return false;
- }
+}
-public boolean equivTo(RatioNum x)
- {
+public boolean equivTo(RatioNum x){
//wouldn't still be a RatioNum if it was an integer
return false;
- }
+}
-public boolean lt(Num rhs)
- {
+public boolean lt(Num rhs){
return rhs.gt(val);
- }
+}
-public boolean gt(BigInteger x)
- {
+public boolean gt(BigInteger x){
return x.compareTo(val) < 0;
- }
+}
-public boolean gt(int x)
- {
+public boolean gt(int x){
return BigInteger.valueOf(x).compareTo(val) < 0;
- }
+}
-public boolean gt(RatioNum x)
- {
+public boolean gt(RatioNum x){
return x.numerator.lt(x.denominator.multiply(val));
- }
+}
-public Num add(Num rhs)
- {
+public Num add(Num rhs){
return rhs.addTo(val);
- }
+}
-public Num addTo(BigInteger x)
- {
+public Num addTo(BigInteger x){
return Num.from(x.add(val));
- }
+}
-public Num addTo(int x)
- {
+public Num addTo(int x){
return Num.from(val.add(BigInteger.valueOf(x)));
- }
+}
-public Num addTo(RatioNum x)
- {
+public Num addTo(RatioNum x){
return x.addTo(val);
- }
+}
-public Num subtractFrom(Num x)
- {
+public Num subtractFrom(Num x){
return x.addTo(val.negate());
- }
+}
-public Num multiplyBy(Num rhs)
- {
+public Num multiplyBy(Num rhs){
return rhs.multiply(val);
- }
+}
-public Num multiply(BigInteger x)
- {
+public Num multiply(BigInteger x){
return Num.from(x.multiply(val));
- }
+}
-public Num multiply(int x)
- {
+public Num multiply(int x){
return Num.from(val.multiply(BigInteger.valueOf(x)));
- }
+}
-public Num multiply(RatioNum x)
- {
+public Num multiply(RatioNum x){
return x.multiply(val);
- }
+}
-public Num divideBy(Num rhs)
- {
+public Num divideBy(Num rhs){
return rhs.divide(val);
- }
+}
-public Num divide(BigInteger n)
- {
+public Num divide(BigInteger n){
return Num.divide(n, val);
- }
+}
-public Num divide(int n)
- {
+public Num divide(int n){
return Num.divide(BigInteger.valueOf(n), val);
- }
+}
-public Num divide(RatioNum x)
- {
+public Num divide(RatioNum x){
return Num.divide(x.numerator, x.denominator.multiply(val));
- }
-
-public Object truncateDivide( Num num)
- {
- return num.truncateBy( val);
- }
-
-public Object truncateBy( int div)
- {
- return Num.truncateBigints( val, BigInteger.valueOf(div));
- }
-
-public Object truncateBy( BigInteger div)
- {
- return Num.truncateBigints( val, div);
- }
-
-public Object truncateBy( RatioNum div)
- {
- Num q = (Num) Num.truncate( div.denominator.multiply(val), div.numerator);
- return RT.setValues( q, q.multiplyBy(div).subtractFrom(this));
- }
-
-public Num negate()
- {
+}
+
+public Object truncateDivide(Num num){
+ return num.truncateBy(val);
+}
+
+public Object truncateBy(int div){
+ return Num.truncateBigints(val, BigInteger.valueOf(div));
+}
+
+public Object truncateBy(BigInteger div){
+ return Num.truncateBigints(val, div);
+}
+
+public Object truncateBy(RatioNum div){
+ Num q = (Num) Num.truncate(div.denominator.multiply(val), div.numerator);
+ return RT.setValues(q, q.multiplyBy(div).subtractFrom(this));
+}
+
+public Num negate(){
return Num.from(val.negate());
- }
+}
-public boolean minusp()
- {
+public boolean minusp(){
return val.signum() < 0;
- }
+}
-public boolean plusp()
- {
+public boolean plusp(){
return val.signum() > 0;
- }
+}
+
+public boolean zerop(){
+ return val.compareTo(BigInteger.ZERO) == 0;
+}
-public Num oneMinus()
- {
+public Num oneMinus(){
return Num.from(val.subtract(BigInteger.ONE));
- }
+}
-public Num onePlus()
- {
+public Num onePlus(){
return Num.from(val.add(BigInteger.ONE));
- }
+}
}
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java
index 65718aea..5a2ce375 100644
--- a/src/jvm/clojure/lang/Compiler.java
+++ b/src/jvm/clojure/lang/Compiler.java
@@ -366,6 +366,7 @@ static abstract class HostExpr implements Expr{
final static Type CHAR_TYPE = Type.getType(Character.class);
final static Type NUMBER_TYPE = Type.getType(Number.class);
final static Method charValueMethod = Method.getMethod("char charValue()");
+ final static Method valueOfMethod = Method.getMethod("Character valueOf(char c)");
final static Method intValueMethod = Method.getMethod("int intValue()");
final static Method longValueMethod = Method.getMethod("long longValue()");
final static Method floatValueMethod = Method.getMethod("float floatValue()");
@@ -373,6 +374,10 @@ static abstract class HostExpr implements Expr{
final static Method byteValueMethod = Method.getMethod("byte byteValue()");
final static Method shortValueMethod = Method.getMethod("short shortValue()");
+ final static Method fromIntMethod = Method.getMethod("clojure.lang.Num from(int)");
+ final static Method fromLongMethod = Method.getMethod("clojure.lang.Num from(long)");
+ final static Method fromDoubleMethod = Method.getMethod("clojure.lang.Num from(double)");
+
public static void emitBoxReturn(FnExpr fn, GeneratorAdapter gen, Class returnType){
if(returnType.isPrimitive())
{
@@ -380,38 +385,38 @@ static abstract class HostExpr implements Expr{
{
Label falseLabel = gen.newLabel();
Label endLabel = gen.newLabel();
- gen.ifNull(falseLabel);
- gen.push(1);
+ gen.ifZCmp(GeneratorAdapter.EQ, falseLabel);
+ gen.getStatic(RT_TYPE, "T", SYMBOL_TYPE);
gen.goTo(endLabel);
gen.mark(falseLabel);
- gen.push(0);
+ NIL_EXPR.emit(C.EXPRESSION, fn, gen);
gen.mark(endLabel);
}
else if(returnType == char.class)
{
- gen.checkCast(CHAR_TYPE);
- gen.invokeStatic(CHAR_TYPE, charValueMethod);
+ gen.invokeStatic(CHAR_TYPE, valueOfMethod);
}
else
{
- Method m = intValueMethod;
- gen.checkCast(NUMBER_TYPE);
+ Method m = fromIntMethod;
if(returnType == int.class)
- m = intValueMethod;
+ m = fromIntMethod;
else if(returnType == float.class)
- m = floatValueMethod;
+ {
+ gen.visitInsn(F2D);
+ m = fromDoubleMethod;
+ }
else if(returnType == double.class)
- m = doubleValueMethod;
+ m = fromDoubleMethod;
else if(returnType == long.class)
- m = longValueMethod;
+ m = fromLongMethod;
else if(returnType == byte.class)
- m = byteValueMethod;
+ m = fromIntMethod;
else if(returnType == short.class)
- m = shortValueMethod;
- gen.invokeStatic(NUMBER_TYPE, m);
+ m = fromIntMethod;
+ gen.invokeStatic(NUM_TYPE, m);
}
}
-
}
public static void emitUnboxArg(FnExpr fn, GeneratorAdapter gen, Class paramType){
@@ -1568,9 +1573,9 @@ static class FnExpr implements Expr{
IPersistentCollection methods = null;
for(int i = 0; i < methodArray.length; i++)
if(methodArray[i] != null)
- methods = RT.cons(methodArray[i], methods);
+ methods = RT.conj(methodArray[i], methods);
if(variadicMethod != null)
- methods = RT.cons(variadicMethod, methods);
+ methods = RT.conj(variadicMethod, methods);
fn.methods = methods;
fn.variadicMethod = variadicMethod;
diff --git a/src/jvm/clojure/lang/DoubleNum.java b/src/jvm/clojure/lang/DoubleNum.java
index 283cd583..3e19e9ac 100644
--- a/src/jvm/clojure/lang/DoubleNum.java
+++ b/src/jvm/clojure/lang/DoubleNum.java
@@ -18,150 +18,122 @@ import java.math.BigDecimal;
public class DoubleNum extends FloatNum{
double val;
-public DoubleNum(double val)
- {
+public DoubleNum(double val){
this.val = val;
- }
+}
-public double doubleValue()
- {
+public double doubleValue(){
return val;
- }
+}
-public float floatValue()
- {
+public float floatValue(){
return (float) val;
- }
+}
-public int intValue()
- {
+public int intValue(){
return (int) val;
- }
+}
-public long longValue()
- {
+public long longValue(){
return (long) val;
- }
+}
final static BigInteger BIGTEN = BigInteger.valueOf(10);
-public Num toRational()
- {
+public Num toRational(){
BigDecimal d = new BigDecimal(val);
return Num.divide(d.unscaledValue(), BIGTEN.pow(d.scale()));
- }
+}
-public boolean equiv(Num rhs)
- {
+public boolean equiv(Num rhs){
if(rhs instanceof RatioNum)
return equivTo((RatioNum) rhs);
return val == rhs.doubleValue();
- }
+}
-public boolean equivTo(BigInteger x)
- {
+public boolean equivTo(BigInteger x){
return val == x.doubleValue();
- }
+}
-public boolean equivTo(int x)
- {
+public boolean equivTo(int x){
return x == val;
- }
+}
-public boolean equivTo(RatioNum x)
- {
+public boolean equivTo(RatioNum x){
return toRational().equivTo(x);
- }
+}
-public boolean lt(Num rhs)
- {
+public boolean lt(Num rhs){
if(rhs instanceof RatioNum)
return toRational().lt(rhs);
return val < rhs.doubleValue();
- }
+}
-public boolean gt(BigInteger x)
- {
+public boolean gt(BigInteger x){
return val > x.doubleValue();
- }
+}
-public boolean gt(int x)
- {
+public boolean gt(int x){
return val > x;
- }
+}
-public boolean gt(RatioNum x)
- {
+public boolean gt(RatioNum x){
return toRational().gt(x);
- }
+}
-public Num add(Num rhs)
- {
+public Num add(Num rhs){
return Num.from(val + rhs.doubleValue());
- }
+}
-public Num addTo(int x)
- {
+public Num addTo(int x){
return Num.from(val + x);
- }
+}
-public Num addTo(BigInteger x)
- {
+public Num addTo(BigInteger x){
return Num.from(val + x.doubleValue());
- }
+}
-public Num addTo(RatioNum x)
- {
+public Num addTo(RatioNum x){
return Num.from(val + x.doubleValue());
- }
+}
-public Num subtractFrom(Num x)
- {
+public Num subtractFrom(Num x){
return Num.from(x.doubleValue() - val);
- }
+}
-public Num multiplyBy(Num rhs)
- {
+public Num multiplyBy(Num rhs){
return Num.from(val * rhs.doubleValue());
- }
+}
-public Num multiply(int x)
- {
+public Num multiply(int x){
return Num.from(val * x);
- }
+}
-public Num multiply(BigInteger x)
- {
+public Num multiply(BigInteger x){
return Num.from(val * x.doubleValue());
- }
+}
-public Num multiply(RatioNum x)
- {
+public Num multiply(RatioNum x){
return Num.from(val * x.doubleValue());
- }
+}
-public Num divideBy(Num rhs)
- {
+public Num divideBy(Num rhs){
return Num.from(val / rhs.doubleValue());
- }
+}
-public Num divide(int x)
- {
+public Num divide(int x){
return Num.from(x / val);
- }
+}
-public Num divide(BigInteger x)
- {
+public Num divide(BigInteger x){
return Num.from(x.doubleValue() / val);
- }
+}
-public Num divide(RatioNum x)
- {
+public Num divide(RatioNum x){
return Num.from(x.doubleValue() / val);
- }
+}
-static Object truncate(double n, double d)
- {
+static Object truncate(double n, double d){
double q = n / d;
if(q <= Integer.MAX_VALUE && q >= Integer.MIN_VALUE)
{
@@ -174,71 +146,63 @@ static Object truncate(double n, double d)
return RT.setValues(bq,
Num.from(n - bq.doubleValue() * d));
}
- }
-
-public Object truncateBy( BigInteger x)
- {
- return truncate( val, x.doubleValue());
- }
-
-public Object truncateBy( int x)
- {
- return truncate( val, x);
- }
-
-public Object truncateBy( RatioNum x)
- {
- return truncate( val, x.doubleValue());
- }
-
-public Object truncateDivide( Num num)
- {
- return truncate( num.doubleValue(), val);
- }
-
-public Num negate()
- {
+}
+
+public Object truncateBy(BigInteger x){
+ return truncate(val, x.doubleValue());
+}
+
+public Object truncateBy(int x){
+ return truncate(val, x);
+}
+
+public Object truncateBy(RatioNum x){
+ return truncate(val, x.doubleValue());
+}
+
+public Object truncateDivide(Num num){
+ return truncate(num.doubleValue(), val);
+}
+
+public Num negate(){
return Num.from(-val);
- }
+}
-public boolean equals(Object arg0)
- {
+public boolean equals(Object arg0){
return arg0 != null
&& arg0 instanceof DoubleNum
&& Double.doubleToLongBits(((DoubleNum) arg0).val) ==
Double.doubleToLongBits(val);
- }
+}
-public int hashCode()
- {
+public int hashCode(){
long v = Double.doubleToLongBits(val);
return (int) (v ^ (v >>> 32));
- }
+}
-public String toString()
- {
+public String toString(){
return Double.toString(val);
- }
+}
-public boolean minusp()
- {
+public boolean minusp(){
return val < 0;
- }
+}
-public boolean plusp()
- {
+public boolean plusp(){
return val > 0;
- }
+}
+
+public boolean zerop(){
+ return val == 0;
+}
-public Num oneMinus()
- {
+public Num oneMinus(){
return Num.from(val - 1);
- }
+}
-public Num onePlus()
- {
+public Num onePlus(){
return Num.from(val + 1);
- }
+}
}
diff --git a/src/jvm/clojure/lang/FixNum.java b/src/jvm/clojure/lang/FixNum.java
index a5eb1ec5..99ef0ce6 100644
--- a/src/jvm/clojure/lang/FixNum.java
+++ b/src/jvm/clojure/lang/FixNum.java
@@ -17,168 +17,136 @@ import java.math.BigInteger;
public class FixNum extends IntegerNum{
public int val;
-public boolean equals(Object arg0)
- {
+public boolean equals(Object arg0){
return arg0 != null
&& arg0 instanceof FixNum
&& ((FixNum) arg0).val == val;
- }
+}
-public int hashCode()
- {
+public int hashCode(){
return val;
- }
+}
-public String toString()
- {
+public String toString(){
return Integer.toString(val);
- }
+}
-public FixNum(int val)
- {
+public FixNum(int val){
this.val = val;
- }
+}
-public double doubleValue()
- {
+public double doubleValue(){
return (double) val;
- }
+}
-public float floatValue()
- {
+public float floatValue(){
return (float) val;
- }
+}
-public int intValue()
- {
+public int intValue(){
return val;
- }
+}
-public long longValue()
- {
+public long longValue(){
return (long) val;
- }
+}
-public boolean equiv(Num rhs)
- {
+public boolean equiv(Num rhs){
return rhs.equivTo(val);
- }
+}
-public boolean equivTo(BigInteger x)
- {
+public boolean equivTo(BigInteger x){
//wouldn't still be a BigInteger if it fit in int
return false;
- }
+}
-public boolean equivTo(int x)
- {
+public boolean equivTo(int x){
return x == val;
- }
+}
-public boolean equivTo(RatioNum x)
- {
+public boolean equivTo(RatioNum x){
//wouldn't still be a RatioNum if it was an integer
return false;
- }
+}
-public boolean lt(Num rhs)
- {
+public boolean lt(Num rhs){
return rhs.gt(val);
- }
+}
-public boolean gt(BigInteger x)
- {
+public boolean gt(BigInteger x){
return x.compareTo(BigInteger.valueOf(val)) < 0;
- }
+}
-public boolean gt(int x)
- {
+public boolean gt(int x){
return x < val;
- }
+}
-public boolean gt(RatioNum x)
- {
+public boolean gt(RatioNum x){
return x.numerator.lt(x.denominator.multiply(val));
- }
+}
-public Num add(Num rhs)
- {
+public Num add(Num rhs){
return rhs.addTo(val);
- }
+}
-public Num addTo(BigInteger x)
- {
+public Num addTo(BigInteger x){
return Num.from(x.add(BigInteger.valueOf(val)));
- }
+}
-public Num addTo(int x)
- {
+public Num addTo(int x){
return Num.from((long) x + val);
- }
+}
-public Num addTo(RatioNum x)
- {
+public Num addTo(RatioNum x){
return x.addTo(val);
- }
+}
-public Num subtractFrom(Num x)
- {
+public Num subtractFrom(Num x){
return x.addTo(-val);
- }
+}
-public Num multiplyBy(Num rhs)
- {
+public Num multiplyBy(Num rhs){
return rhs.multiply(val);
- }
+}
-public Num multiply(BigInteger x)
- {
+public Num multiply(BigInteger x){
return Num.from(x.multiply(BigInteger.valueOf(val)));
- }
+}
-public Num multiply(int x)
- {
+public Num multiply(int x){
return Num.from((long) x * val);
- }
+}
-public Num multiply(RatioNum x)
- {
+public Num multiply(RatioNum x){
return x.multiply(val);
- }
-
-public Object truncateDivide( Num num)
- {
- return num.truncateBy( val);
- }
-
-public Object truncateBy( int div)
- {
- return RT.setValues( Num.from(val / div), Num.from(val % div));
- }
-
-public Object truncateBy( BigInteger div)
- {
- return Num.truncateBigints( BigInteger.valueOf(val), div);
- }
-
-public Object truncateBy( RatioNum div)
- {
- Num q = (Num) Num.truncate( div.denominator.multiply(val), div.numerator);
- return RT.setValues( q, q.multiplyBy(div).subtractFrom(this));
- }
-
-public Num divideBy(Num rhs)
- {
+}
+
+public Object truncateDivide(Num num){
+ return num.truncateBy(val);
+}
+
+public Object truncateBy(int div){
+ return RT.setValues(Num.from(val / div), Num.from(val % div));
+}
+
+public Object truncateBy(BigInteger div){
+ return Num.truncateBigints(BigInteger.valueOf(val), div);
+}
+
+public Object truncateBy(RatioNum div){
+ Num q = (Num) Num.truncate(div.denominator.multiply(val), div.numerator);
+ return RT.setValues(q, q.multiplyBy(div).subtractFrom(this));
+}
+
+public Num divideBy(Num rhs){
return rhs.divide(val);
- }
+}
-public Num divide(BigInteger n)
- {
+public Num divide(BigInteger n){
return Num.divide(n, BigInteger.valueOf(val));
- }
+}
-static int gcd(int u, int v)
- {
+static int gcd(int u, int v){
while(v != 0)
{
int r = u % v;
@@ -186,10 +154,9 @@ static int gcd(int u, int v)
v = r;
}
return u;
- }
+}
-public Num divide(int n)
- {
+public Num divide(int n){
int gcd = gcd(n, val);
if(gcd == 0)
return Num.ZERO;
@@ -204,36 +171,34 @@ public Num divide(int n)
d = -d;
}
return new RatioNum((IntegerNum) Num.from(n), (IntegerNum) Num.from(d));
- }
+}
-public Num divide(RatioNum x)
- {
+public Num divide(RatioNum x){
return Num.divide(x.numerator, x.denominator.multiply(val));
- }
+}
-public Num negate()
- {
+public Num negate(){
return Num.from(-val);
- }
+}
-public boolean minusp()
- {
+public boolean minusp(){
return val < 0;
- }
+}
-public boolean plusp()
- {
+public boolean plusp(){
return val > 0;
- }
+}
+
+public boolean zerop(){
+ return val == 0;
+}
-public Num oneMinus()
- {
+public Num oneMinus(){
return Num.from(val - 1);
- }
+}
-public Num onePlus()
- {
+public Num onePlus(){
return Num.from(val + 1);
- }
+}
}
diff --git a/src/jvm/clojure/lang/Num.java b/src/jvm/clojure/lang/Num.java
index c2d3d990..de2f7638 100644
--- a/src/jvm/clojure/lang/Num.java
+++ b/src/jvm/clojure/lang/Num.java
@@ -19,35 +19,30 @@ public abstract class Num extends Number implements Comparable{
public final static Num ZERO = from(0);
public final static Num ONE = from(1);
-static public Num from(int val)
- {
+static public Num from(int val){
//todo - cache a bunch of small fixnums
return new FixNum(val);
- }
+}
-static public Num from(double val)
- {
+static public Num from(double val){
return new DoubleNum(val);
- }
+}
-static public Num from(long val)
- {
+static public Num from(long val){
if(val <= Integer.MAX_VALUE && val >= Integer.MIN_VALUE)
return from((int) val);
else
return new BigNum(val);
- }
+}
-static public Num from(BigInteger val)
- {
+static public Num from(BigInteger val){
if(val.bitLength() < 32)
return from(val.intValue());
else
return new BigNum(val);
- }
+}
-static public Num from(Object x)
- {
+static public Num from(Object x){
if(x instanceof Num)
return (Num) x;
else
@@ -64,14 +59,13 @@ static public Num from(Object x)
else
return Num.from(((Number) x).intValue());
}
- }
+}
-static public Num add(Object x, Object y)
- {
+static public Num add(Object x, Object y){
//if(x instanceof Num && y instanceof Num)
//return ((Num)x).add((Num) y);
return Num.from(x).add(Num.from(y));
- }
+}
abstract public Num add(Num rhs);
@@ -81,18 +75,16 @@ abstract public Num addTo(BigInteger x);
abstract public Num addTo(RatioNum x);
-static public Num subtract(Object x, Object y)
- {
+static public Num subtract(Object x, Object y){
return Num.from(y).subtractFrom(Num.from(x));
- }
+}
//this double-dispatches to addTo(-self)
abstract public Num subtractFrom(Num rhs);
-static public Num multiply(Object x, Object y)
- {
+static public Num multiply(Object x, Object y){
return Num.from(x).multiplyBy(Num.from(y));
- }
+}
abstract public Num multiplyBy(Num rhs);
@@ -102,10 +94,9 @@ abstract public Num multiply(BigInteger x);
abstract public Num multiply(RatioNum x);
-static public Num divide(Object x, Object y)
- {
+static public Num divide(Object x, Object y){
return Num.from(x).divideBy(Num.from(y));
- }
+}
abstract public Num divideBy(Num rhs);
@@ -115,10 +106,9 @@ abstract public Num divide(BigInteger x);
abstract public Num divide(RatioNum x);
-static public Object truncate(Object num, Object div)
- {
- return Num.from(div).truncateDivide( Num.from(num));
- }
+static public Object truncate(Object num, Object div){
+ return Num.from(div).truncateDivide(Num.from(num));
+}
abstract public Object truncateDivide(Num rhs);
@@ -128,14 +118,12 @@ abstract public Object truncateBy(BigInteger x);
abstract public Object truncateBy(RatioNum x);
-static public Object truncateBigints(BigInteger n, BigInteger d)
- {
+static public Object truncateBigints(BigInteger n, BigInteger d){
BigInteger[] result = n.divideAndRemainder(d);
return RT.setValues(Num.from(result[0]), Num.from(result[1]));
- }
+}
-static public Num divide(BigInteger n, BigInteger d)
- {
+static public Num divide(BigInteger n, BigInteger d){
BigInteger gcd = n.gcd(d);
if(gcd.equals(BigInteger.ZERO))
return Num.ZERO;
@@ -145,12 +133,11 @@ static public Num divide(BigInteger n, BigInteger d)
return Num.from(n);
return new RatioNum((IntegerNum) Num.from(d.signum() < 0 ? n.negate() : n),
(IntegerNum) Num.from(d.signum() < 0 ? d.negate() : d));
- }
+}
-static public boolean equiv(Object x, Object y)
- {
+static public boolean equiv(Object x, Object y){
return Num.from(x).equiv(Num.from(y));
- }
+}
abstract public boolean equiv(Num rhs);
@@ -160,29 +147,25 @@ abstract public boolean equivTo(BigInteger x);
abstract public boolean equivTo(RatioNum x);
-static public boolean lt(Object x, Object y)
- {
+static public boolean lt(Object x, Object y){
return Num.from(x).lt(Num.from(y));
- }
+}
-static public boolean lte(Object x, Object y)
- {
+static public boolean lte(Object x, Object y){
Num lx = Num.from(x);
Num ly = Num.from(y);
return lx.lt(ly) || lx.equiv(ly);
- }
+}
-static public boolean gt(Object x, Object y)
- {
+static public boolean gt(Object x, Object y){
return Num.from(y).lt(Num.from(x));
- }
+}
-static public boolean gte(Object x, Object y)
- {
+static public boolean gte(Object x, Object y){
Num lx = Num.from(x);
Num ly = Num.from(y);
return ly.lt(lx) || lx.equiv(ly);
- }
+}
abstract public boolean lt(Num rhs);
@@ -192,10 +175,29 @@ abstract public boolean gt(BigInteger x);
abstract public boolean gt(RatioNum x);
-static public Num negate(Object x)
- {
+static public Num negate(Object x){
return Num.from(x).negate();
- }
+}
+
+static public Object negPred(Num n){
+ return n.minusp() ? RT.T : null;
+}
+
+static public Object posPred(Num n){
+ return n.plusp() ? RT.T : null;
+}
+
+static public Object zeroPred(Num n){
+ return n.zerop() ? RT.T : null;
+}
+
+static public Num dec(Num n){
+ return n.oneMinus();
+}
+
+static public Num inc(Num n){
+ return n.onePlus();
+}
abstract public Num negate();
@@ -203,12 +205,13 @@ abstract public boolean minusp();
abstract public boolean plusp();
+abstract public boolean zerop();
+
abstract public Num oneMinus();
abstract public Num onePlus();
-public int compareTo(Object object)
- {
+public int compareTo(Object object){
Num other = Num.from(object);
if(this.equiv(other))
return 0;
@@ -216,5 +219,5 @@ public int compareTo(Object object)
return -1;
else
return 1;
- }
+}
}
diff --git a/src/jvm/clojure/lang/OldCompiler.java b/src/jvm/clojure/lang/OldCompiler.java
index d227e609..6d044508 100644
--- a/src/jvm/clojure/lang/OldCompiler.java
+++ b/src/jvm/clojure/lang/OldCompiler.java<