summaryrefslogtreecommitdiff
path: root/src/jvm/clojure
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2008-04-02 03:13:50 +0000
committerRich Hickey <richhickey@gmail.com>2008-04-02 03:13:50 +0000
commitcf71a664aa513b3e4b232b0d3cccf1b3e2b88c4f (patch)
treea710d22772e1366892f9b2d3e0f2a0c1e93dd730 /src/jvm/clojure
parenta639a2d64ec8d555761598e3f613b145dbbb3341 (diff)
range seq, internal reduce in ISeq
Diffstat (limited to 'src/jvm/clojure')
-rw-r--r--src/jvm/clojure/lang/APersistentVector.java14
-rw-r--r--src/jvm/clojure/lang/ASeq.java14
-rw-r--r--src/jvm/clojure/lang/ArraySeq.java14
-rw-r--r--src/jvm/clojure/lang/ISeq.java4
-rw-r--r--src/jvm/clojure/lang/Numbers.java88
-rw-r--r--src/jvm/clojure/lang/Range.java60
6 files changed, 166 insertions, 28 deletions
diff --git a/src/jvm/clojure/lang/APersistentVector.java b/src/jvm/clojure/lang/APersistentVector.java
index ffadc444..e6da23b9 100644
--- a/src/jvm/clojure/lang/APersistentVector.java
+++ b/src/jvm/clojure/lang/APersistentVector.java
@@ -268,6 +268,20 @@ static class Seq extends ASeq implements IndexedSeq{
public PersistentVector.Seq withMeta(IPersistentMap meta){
return new PersistentVector.Seq(meta, v, i);
}
+
+ public Object reduce(IFn f) throws Exception{
+ Object ret = v.nth(i);
+ for(int x = i + 1; x < v.count(); x++)
+ ret = f.invoke(ret, x);
+ return ret;
+ }
+
+ public Object reduce(IFn f, Object start) throws Exception{
+ Object ret = f.invoke(start, v.nth(i));
+ for(int x = i + 1; x < v.count(); x++)
+ ret = f.invoke(ret, x);
+ return ret;
+ }
}
static class RSeq extends ASeq implements IndexedSeq{
diff --git a/src/jvm/clojure/lang/ASeq.java b/src/jvm/clojure/lang/ASeq.java
index d19c8906..ac821f5e 100644
--- a/src/jvm/clojure/lang/ASeq.java
+++ b/src/jvm/clojure/lang/ASeq.java
@@ -54,6 +54,20 @@ public int hashCode(){
return _hash;
}
+public Object reduce(IFn f) throws Exception{
+ Object ret = first();
+ for(ISeq s = rest();s != null;s=s.rest())
+ ret = f.invoke(ret,s.first());
+ return ret;
+}
+
+public Object reduce(IFn f, Object start) throws Exception{
+ Object ret = f.invoke(start,first());
+ for(ISeq s = rest();s != null;s=s.rest())
+ ret = f.invoke(ret,s.first());
+ return ret;
+}
+
//public Object peek(){
// return first();
//}
diff --git a/src/jvm/clojure/lang/ArraySeq.java b/src/jvm/clojure/lang/ArraySeq.java
index f23cc1c0..9c19127d 100644
--- a/src/jvm/clojure/lang/ArraySeq.java
+++ b/src/jvm/clojure/lang/ArraySeq.java
@@ -67,4 +67,18 @@ public int index(){
public ArraySeq withMeta(IPersistentMap meta){
return new ArraySeq(meta, array, i);
}
+
+public Object reduce(IFn f) throws Exception{
+ Object ret = array[i];
+ for(int x = i+1;x < array.length;x++)
+ ret = f.invoke(ret, x);
+ return ret;
+}
+
+public Object reduce(IFn f, Object start) throws Exception{
+ Object ret = f.invoke(start,array[i]);
+ for(int x = i+1;x < array.length;x++)
+ ret = f.invoke(ret, x);
+ return ret;
+}
}
diff --git a/src/jvm/clojure/lang/ISeq.java b/src/jvm/clojure/lang/ISeq.java
index 08c66cf9..2fdd8eec 100644
--- a/src/jvm/clojure/lang/ISeq.java
+++ b/src/jvm/clojure/lang/ISeq.java
@@ -24,4 +24,8 @@ ISeq rest();
ISeq cons(Object o);
+Object reduce(IFn f) throws Exception;
+
+Object reduce(IFn f, Object start) throws Exception;
+
}
diff --git a/src/jvm/clojure/lang/Numbers.java b/src/jvm/clojure/lang/Numbers.java
index f1ce33e0..b8bf2f1a 100644
--- a/src/jvm/clojure/lang/Numbers.java
+++ b/src/jvm/clojure/lang/Numbers.java
@@ -99,9 +99,28 @@ static BigInteger toBigInteger(Object x){
return BigInteger.valueOf(((Number) x).longValue());
}
+static BigDecimal toBigDecimal(Object x){
+ if(x instanceof BigDecimal)
+ return (BigDecimal) x;
+ else if(x instanceof BigInteger)
+ return new BigDecimal((BigInteger) x);
+ else
+ return BigDecimal.valueOf(((Number) x).longValue());
+}
+
static Ratio toRatio(Object x){
if(x instanceof Ratio)
return (Ratio) x;
+ else if(x instanceof BigDecimal)
+ {
+ BigDecimal bx = (BigDecimal) x;
+ BigInteger bv = bx.unscaledValue();
+ int scale = bx.scale();
+ if(scale < 0)
+ return new Ratio(bv, BigInteger.TEN.pow(-scale));
+ else
+ return new Ratio(bv.multiply(BigInteger.TEN.pow(scale)), BigInteger.ONE);
+ }
return new Ratio(toBigInteger(x), BigInteger.ONE);
}
@@ -121,7 +140,7 @@ static public Object divide(BigInteger n, BigInteger d){
if(d.equals(BigInteger.ONE))
return reduce(n);
return new Ratio((d.signum() < 0 ? n.negate() : n),
- (d.signum() < 0 ? d.negate() : d));
+ (d.signum() < 0 ? d.negate() : d));
}
static interface Ops{
@@ -132,7 +151,7 @@ static Ops intOps = new Ops(){
public Object add(Object x, Object y){
long ret = ((Number) x).longValue() + ((Number) y).longValue();
if(ret <= Integer.MAX_VALUE && ret >= Integer.MIN_VALUE)
- return (int)ret;
+ return (int) ret;
return ret;
}
};
@@ -153,38 +172,51 @@ static Ops ratioOps = new Ops(){
public Object add(Object x, Object y){
Ratio rx = toRatio(x);
Ratio ry = toRatio(y);
- return divide(rx.numerator.multiply(rx.denominator)
- .add(rx.numerator.multiply(ry.denominator))
- , ry.denominator.multiply(rx.denominator));
+ return divide(rx.numerator.multiply(rx.denominator)
+ .add(rx.numerator.multiply(ry.denominator))
+ , ry.denominator.multiply(rx.denominator));
}
};
-/*
-static Ops ops(Object x, Object y){
- Class xc = x.getClass();
- Class yc = y.getClass();
- if(xc == Integer.class && yc == Integer.class)
- return intOps;
- else if(xc.isArray() || yc.isArray())
- {
+static Ops bigdecOps = new Ops(){
+ public Object add(Object x, Object y){
+ return toBigDecimal(x).add(toBigDecimal(y));
+ }
+};
- }
- else if(xc == Double.class || yc == Double.class)
- return doubleOps;
- else if(xc == Float.class || yc == Float.class)
- return floatOps;
- else if(xc == Ratio.class || yc == Ratio.class)
- return ratioOps;
- else if(xc == BigDecimal.class || yc == BigDecimal.class)
- return bigdecOps;
- else if(xc == BigInteger.class || yc == BigInteger.class
- || xc == Long.class || yc == Long.class)
- return bigintOps;
-
- return intOps;
+static Ops bigintOps = new Ops(){
+ public Object add(Object x, Object y){
+ return reduce(toBigInteger(x).add(toBigInteger(y)));
+ }
+};
+
+/*
+static Ops ops(Object x, Object y){
+ Class xc = x.getClass();
+ Class yc = y.getClass();
+
+ if(xc == Integer.class && yc == Integer.class)
+ return intOps;
+ else if(xc.isArray() || yc.isArray())
+ {
+
+ }
+ else if(xc == Double.class || yc == Double.class)
+ return doubleOps;
+ else if(xc == Float.class || yc == Float.class)
+ return floatOps;
+ else if(xc == Ratio.class || yc == Ratio.class)
+ return ratioOps;
+ else if(xc == BigDecimal.class || yc == BigDecimal.class)
+ return bigdecOps;
+ else if(xc == BigInteger.class || yc == BigInteger.class
+ || xc == Long.class || yc == Long.class)
+ return bigintOps;
+
+ return intOps;
}
// */
- /*
+/*
static Object add(Object x, Object y){
Class c = x.getClass();
if(c == Integer.class)
diff --git a/src/jvm/clojure/lang/Range.java b/src/jvm/clojure/lang/Range.java
new file mode 100644
index 00000000..e5d51761
--- /dev/null
+++ b/src/jvm/clojure/lang/Range.java
@@ -0,0 +1,60 @@
+/**
+ * Copyright (c) Rich Hickey. All rights reserved.
+ * The use and distribution terms for this software are covered by the
+ * Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
+ * which can be found in the file CPL.TXT at the root of this distribution.
+ * By using this software in any fashion, you are agreeing to be bound by
+ * the terms of this license.
+ * You must not remove this notice, or any other, from this software.
+ **/
+
+/* rich Apr 1, 2008 */
+
+package clojure.lang;
+
+public class Range extends ASeq{
+final int end;
+final int n;
+
+public Range(int start, int end){
+ this.end = end;
+ this.n = start;
+}
+
+public Range(IPersistentMap meta, int start, int end){
+ super(meta);
+ this.end = end;
+ this.n = start;
+}
+
+public Obj withMeta(IPersistentMap meta){
+ if(meta == meta())
+ return this;
+ return new Range(meta(), end, n);
+}
+
+public Object first(){
+ return n;
+}
+
+public ISeq rest(){
+ if(n < end-1)
+ return new Range(_meta, n + 1, end);
+ return null;
+}
+
+public Object reduce(IFn f) throws Exception{
+ Object ret = n;
+ for(int x = n+1;x < end;x++)
+ ret = f.invoke(ret, x);
+ return ret;
+}
+
+public Object reduce(IFn f, Object start) throws Exception{
+ Object ret = f.invoke(start,n);
+ for(int x = n+1;x < end;x++)
+ ret = f.invoke(ret, x);
+ return ret;
+}
+
+}