diff options
author | Rich Hickey <richhickey@gmail.com> | 2008-04-02 03:13:50 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2008-04-02 03:13:50 +0000 |
commit | cf71a664aa513b3e4b232b0d3cccf1b3e2b88c4f (patch) | |
tree | a710d22772e1366892f9b2d3e0f2a0c1e93dd730 /src/jvm | |
parent | a639a2d64ec8d555761598e3f613b145dbbb3341 (diff) |
range seq, internal reduce in ISeq
Diffstat (limited to 'src/jvm')
-rw-r--r-- | src/jvm/clojure/lang/APersistentVector.java | 14 | ||||
-rw-r--r-- | src/jvm/clojure/lang/ASeq.java | 14 | ||||
-rw-r--r-- | src/jvm/clojure/lang/ArraySeq.java | 14 | ||||
-rw-r--r-- | src/jvm/clojure/lang/ISeq.java | 4 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Numbers.java | 88 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Range.java | 60 |
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; +} + +} |