diff options
author | Rich Hickey <richhickey@gmail.com> | 2007-12-18 18:14:30 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2007-12-18 18:14:30 +0000 |
commit | b876bc01060191c4fecef062bdddd190c79fd83f (patch) | |
tree | 80a02e9b2a2db062fddebbddf73f81ca8c362f29 /src | |
parent | 563ce9095b9b2610a845123dec1d8e2884177aa0 (diff) |
added subvec
Diffstat (limited to 'src')
-rw-r--r-- | src/boot.clj | 8 | ||||
-rw-r--r-- | src/jvm/clojure/lang/APersistentVector.java | 349 | ||||
-rw-r--r-- | src/jvm/clojure/lang/IPersistentVector.java | 3 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentVector.java | 280 | ||||
-rw-r--r-- | src/jvm/clojure/lang/RT.java | 8 |
5 files changed, 370 insertions, 278 deletions
diff --git a/src/boot.clj b/src/boot.clj index 3f9a27bd..8094e2b3 100644 --- a/src/boot.clj +++ b/src/boot.clj @@ -913,6 +913,13 @@ (defn accessor [s key] (. clojure.lang.PersistentStructMap (getAccessor s key))) +(defn subvec + ([v start] + (thisfn v start (count v))) + ([v start end] + (. clojure.lang.RT (subvec v start end)))) + + (def *exports* '(clojure load-file eql-ref? @@ -958,5 +965,6 @@ bit-shift-left bit-shift-right bit-and bit-or bit-xor bit-not defstruct struct accessor create-struct + subvec )) diff --git a/src/jvm/clojure/lang/APersistentVector.java b/src/jvm/clojure/lang/APersistentVector.java new file mode 100644 index 00000000..712f90db --- /dev/null +++ b/src/jvm/clojure/lang/APersistentVector.java @@ -0,0 +1,349 @@ +/** + * 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 Dec 18, 2007 */ + +package clojure.lang; + +import java.util.Collection; +import java.util.Iterator; + +public abstract class APersistentVector extends AFn implements IPersistentVector, Iterable, Collection{ +int _hash = -1; + +public APersistentVector(IPersistentMap meta){ + super(meta); +} + +public ISeq seq(){ + if(count() > 0) + return new Seq(this, 0); + return null; +} + +public ISeq rseq(){ + if(count() > 0) + return new RSeq(this, count() - 1); + return null; +} + +public boolean equals(Object obj){ + if(obj instanceof IPersistentVector) + { + IPersistentVector ma = (IPersistentVector) obj; + if(ma.count() != count() || ma.hashCode() != hashCode()) + return false; + for(int i = 0; i < count(); i++) + { + if(!RT.equal(nth(i), ma.nth(i))) + return false; + } + } + else + { + if(!(obj instanceof Sequential)) + return false; + ISeq ms = ((IPersistentCollection) obj).seq(); + for(int i = 0; i < count(); i++, ms = ms.rest()) + { + if(ms == null || !RT.equal(nth(i), ms.first())) + return false; + } + if(ms != null) + return false; + } + + return true; +} + +public int hashCode(){ + if(_hash == -1) + { + int hash = 0; + for(int i = 0; i < count(); i++) + { + hash = RT.hashCombine(hash, RT.hash(nth(i))); + } + this._hash = hash; + } + return _hash; +} + +public Object invoke(Object arg1) throws Exception{ + return nth(((Number) arg1).intValue()); +} + +public Iterator iterator(){ + //todo - something more efficient + return new Iterator(){ + int i = 0; + + public boolean hasNext(){ + return i < count(); + } + + public Object next(){ + return nth(i++); + } + + public void remove(){ + throw new UnsupportedOperationException(); + } + }; +} + +public Object peek(){ + if(count() > 0) + return nth(count() - 1); + return null; +} + +public boolean containsKey(Object key){ + if(!(key instanceof Number)) + return false; + int i = ((Number) key).intValue(); + return i >= 0 && i < count(); +} + +public IMapEntry entryAt(Object key){ + if(key instanceof Number) + { + int i = ((Number) key).intValue(); + if(i >= 0 && i < count()) + return new MapEntry(key, nth(i)); + } + return null; +} + +public IPersistentVector assoc(Object key, Object val){ + if(key instanceof Number) + { + int i = ((Number) key).intValue(); + return assocN(i, val); + } + throw new IllegalAccessError("Key must be integer"); +} + +public Object valAt(Object key, Object notFound){ + if(key instanceof Number) + { + int i = ((Number) key).intValue(); + if(i >= 0 && i < count()) + return nth(i); + } + return notFound; +} + +public Object valAt(Object key){ + return valAt(key, null); +} + +// java.util.Collection implementation + +public Object[] toArray(){ + return RT.seqToArray(seq()); +} + +public boolean add(Object o){ + throw new UnsupportedOperationException(); +} + +public boolean remove(Object o){ + throw new UnsupportedOperationException(); +} + +public boolean addAll(Collection c){ + throw new UnsupportedOperationException(); +} + +public void clear(){ + throw new UnsupportedOperationException(); +} + +public boolean retainAll(Collection c){ + throw new UnsupportedOperationException(); +} + +public boolean removeAll(Collection c){ + throw new UnsupportedOperationException(); +} + +public boolean containsAll(Collection c){ + for(Object o : c) + { + if(contains(o)) + return true; + } + return false; +} + +public Object[] toArray(Object[] a){ + if(a.length >= count()) + { + ISeq s = seq(); + for(int i = 0; s != null; ++i, s = s.rest()) + { + a[i] = s.first(); + } + if(a.length >= count()) + a[count()] = null; + return a; + } + else + return toArray(); +} + +public int size(){ + return count(); +} + +public boolean isEmpty(){ + return count() == 0; +} + +public boolean contains(Object o){ + for(ISeq s = seq(); s != null; s = s.rest()) + { + if(RT.equal(s.first(), o)) + return true; + } + return false; +} + +public int length(){ + return count(); +} + +static class Seq extends ASeq implements IndexedSeq{ + //todo - something more efficient + final IPersistentVector v; + final int i; + + + public Seq(IPersistentVector v, int i){ + this.v = v; + this.i = i; + } + + Seq(IPersistentMap meta, IPersistentVector v, int i){ + super(meta); + this.v = v; + this.i = i; + } + + public Object first(){ + return v.nth(i); + } + + public ISeq rest(){ + if(i + 1 < v.count()) + return new PersistentVector.Seq(v, i + 1); + return null; + } + + public int index(){ + return i; + } + + public int count(){ + return v.count() - i; + } + + public PersistentVector.Seq withMeta(IPersistentMap meta){ + return new PersistentVector.Seq(meta, v, i); + } +} + +static class RSeq extends ASeq implements IndexedSeq{ + final IPersistentVector v; + final int i; + + RSeq(IPersistentVector vector, int i){ + this.v = vector; + this.i = i; + } + + RSeq(IPersistentMap meta, IPersistentVector v, int i){ + super(meta); + this.v = v; + this.i = i; + } + + public Object first(){ + return v.nth(i); + } + + public ISeq rest(){ + if(i > 0) + return new PersistentVector.RSeq(v, i - 1); + return null; + } + + public int index(){ + return i; + } + + public int count(){ + return i + 1; + } + + public PersistentVector.RSeq withMeta(IPersistentMap meta){ + return new PersistentVector.RSeq(meta, v, i); + } +} + +static class SubVector extends APersistentVector{ + final IPersistentVector v; + final int start; + final int end; + + + public SubVector(IPersistentMap meta, IPersistentVector v, int start, int end){ + super(meta); + this.v = v; + this.start = start; + this.end = end; + } + + public Object nth(int i){ + if(start + i >= end) + throw new IndexOutOfBoundsException(); + return v.nth(start + i); + } + + public IPersistentVector assocN(int i, Object val){ + if(start + i >= end) + throw new IndexOutOfBoundsException(); + return new SubVector(_meta, v.assocN(start + i, val), start, end); + } + + public int count(){ + return end - start; + } + + public IPersistentVector cons(Object o){ + return new SubVector(_meta, v.assocN(end, o), start, end + 1); + } + + public IPersistentStack pop(){ + if(end - 1 == start) + { + return PersistentVector.EMPTY; + } + return new SubVector(_meta, v, start, end - 1); + } + + public SubVector withMeta(IPersistentMap meta){ + if(meta == _meta) + return this; + return new SubVector(meta, v, start, end); + } +} +} diff --git a/src/jvm/clojure/lang/IPersistentVector.java b/src/jvm/clojure/lang/IPersistentVector.java index 143039d6..7dafa553 100644 --- a/src/jvm/clojure/lang/IPersistentVector.java +++ b/src/jvm/clojure/lang/IPersistentVector.java @@ -16,4 +16,7 @@ int length(); Object nth(int i);
IPersistentVector assocN(int i, Object val);
+
+IPersistentVector cons(Object o);
+
}
diff --git a/src/jvm/clojure/lang/PersistentVector.java b/src/jvm/clojure/lang/PersistentVector.java index 3910d118..68d71bfd 100644 --- a/src/jvm/clojure/lang/PersistentVector.java +++ b/src/jvm/clojure/lang/PersistentVector.java @@ -16,11 +16,10 @@ import java.util.Collection; import java.util.List; import java.util.Iterator; -public class PersistentVector extends AFn implements IPersistentVector, Iterable, Collection{ +public class PersistentVector extends APersistentVector{ final int cnt; final int shift; final Object[] root; -int _hash = -1; public final static PersistentVector EMPTY = new PersistentVector(0, 0, RT.EMPTY_ARRAY); @@ -52,6 +51,7 @@ static public PersistentVector create(Object... items){ } PersistentVector(int cnt, int shift, Object[] root){ + super(null); this.cnt = cnt; this.shift = shift; this.root = root; @@ -65,9 +65,6 @@ PersistentVector(IPersistentMap meta, int cnt, int shift, Object[] root){ this.root = root; } -public int length(){ - return cnt; -} public Object nth(int i){ if(i >= 0 && i < cnt) @@ -106,165 +103,10 @@ public int count(){ return cnt; } -public ISeq seq(){ - if(cnt > 0) - return new Seq(this, 0); - return null; -} - -public ISeq rseq(){ - if(cnt > 0) - return new RSeq(this, count() - 1); - return null; -} - -public boolean equals(Object obj){ - if(obj instanceof IPersistentVector) - { - IPersistentVector ma = (IPersistentVector) obj; - if(ma.count() != count() || ma.hashCode() != hashCode()) - return false; - for(int i = 0; i < count(); i++) - { - if(!RT.equal(nth(i), ma.nth(i))) - return false; - } - } - else - { - if(!(obj instanceof Sequential)) - return false; - ISeq ms = ((IPersistentCollection) obj).seq(); - for(int i = 0; i < count(); i++, ms = ms.rest()) - { - if(ms == null || !RT.equal(nth(i), ms.first())) - return false; - } - if(ms != null) - return false; - } - - return true; -} - -public int hashCode(){ - if(_hash == -1) - { - int hash = 0; - for(int i = 0; i < cnt; i++) - { - hash = RT.hashCombine(hash, RT.hash(nth(i))); - } - this._hash = hash; - } - return _hash; -} - public PersistentVector withMeta(IPersistentMap meta){ return new PersistentVector(meta, cnt, shift, root); } -public Object invoke(Object arg1) throws Exception{ - return nth(((Number) arg1).intValue()); -} - -public Iterator iterator(){ - //todo - something more efficient - return new Iterator(){ - int i = 0; - - public boolean hasNext(){ - return i < cnt; - } - - public Object next(){ - return nth(i++); - } - - public void remove(){ - throw new UnsupportedOperationException(); - } - }; -} - - -static class Seq extends ASeq implements IndexedSeq{ - //todo - something more efficient - final PersistentVector v; - final int i; - - - public Seq(PersistentVector v, int i){ - this.v = v; - this.i = i; - } - - Seq(IPersistentMap meta, PersistentVector v, int i){ - super(meta); - this.v = v; - this.i = i; - } - - public Object first(){ - return v.nth(i); - } - - public ISeq rest(){ - if(i + 1 < v.cnt) - return new Seq(v, i + 1); - return null; - } - - public int index(){ - return i; - } - - public int count(){ - return v.cnt - i; - } - - public Seq withMeta(IPersistentMap meta){ - return new Seq(meta, v, i); - } -} - -static class RSeq extends ASeq implements IndexedSeq{ - final PersistentVector v; - final int i; - - RSeq(PersistentVector vector, int i){ - this.v = vector; - this.i = i; - } - - RSeq(IPersistentMap meta, PersistentVector v, int i){ - super(meta); - this.v = v; - this.i = i; - } - - public Object first(){ - return v.nth(i); - } - - public ISeq rest(){ - if(i > 0) - return new RSeq(v, i - 1); - return null; - } - - public int index(){ - return i; - } - - public int count(){ - return i + 1; - } - - public RSeq withMeta(IPersistentMap meta){ - return new RSeq(meta, v, i); - } -} public PersistentVector cons(Object val){ Box expansion = new Box(null); @@ -309,12 +151,6 @@ private Object[] doCons(int level, Object[] arr, Object val, Box expansion){ return ret; } -public Object peek(){ - if(cnt > 0) - return nth(cnt - 1); - return null; -} - public PersistentVector pop(){ if(cnt == 0) throw new IllegalAccessError("Can't pop empty vector"); @@ -351,118 +187,6 @@ private Object[] doPop(int shift, Object[] arr){ return ret; } - -public boolean containsKey(Object key){ - if(!(key instanceof Number)) - return false; - int i = ((Number) key).intValue(); - return i >= 0 && i < count(); -} - -public IMapEntry entryAt(Object key){ - if(key instanceof Number) - { - int i = ((Number) key).intValue(); - if(i >= 0 && i < count()) - return new MapEntry(key, nth(i)); - } - return null; -} - -public PersistentVector assoc(Object key, Object val){ - if(key instanceof Number) - { - int i = ((Number) key).intValue(); - return assocN(i, val); - } - throw new IllegalAccessError("Key must be integer"); -} - -public Object valAt(Object key, Object notFound){ - if(key instanceof Number) - { - int i = ((Number) key).intValue(); - if(i >= 0 && i < count()) - return nth(i); - } - return notFound; -} - -public Object valAt(Object key){ - return valAt(key, null); -} -// java.util.Collection implementation - -public Object[] toArray(){ - return RT.seqToArray(seq()); -} - -public boolean add(Object o){ - throw new UnsupportedOperationException(); -} - -public boolean remove(Object o){ - throw new UnsupportedOperationException(); -} - -public boolean addAll(Collection c){ - throw new UnsupportedOperationException(); -} - -public void clear(){ - throw new UnsupportedOperationException(); -} - -public boolean retainAll(Collection c){ - throw new UnsupportedOperationException(); -} - -public boolean removeAll(Collection c){ - throw new UnsupportedOperationException(); -} - -public boolean containsAll(Collection c){ - for(Object o : c) - { - if(contains(o)) - return true; - } - return false; -} - -public Object[] toArray(Object[] a){ - if(a.length >= count()) - { - ISeq s = seq(); - for(int i = 0; s != null; ++i, s = s.rest()) - { - a[i] = s.first(); - } - if(a.length >= count()) - a[count()] = null; - return a; - } - else - return toArray(); -} - -public int size(){ - return count(); -} - -public boolean isEmpty(){ - return count() == 0; -} - -public boolean contains(Object o){ - for(ISeq s = seq(); s != null; s = s.rest()) - { - if(RT.equal(s.first(), o)) - return true; - } - return false; -} - /* static public void main(String[] args){ if(args.length != 3) diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java index e3e6564e..cbb8c823 100644 --- a/src/jvm/clojure/lang/RT.java +++ b/src/jvm/clojure/lang/RT.java @@ -519,6 +519,14 @@ static public IPersistentVector vector(Object... init){ return PersistentVector.create(init); } +static public IPersistentVector subvec(IPersistentVector v, int start, int end){ + if(end < start || start < 0 || end > v.count()) + throw new IndexOutOfBoundsException(); + if(start == end) + return PersistentVector.EMPTY; + return new APersistentVector.SubVector(null, v, start, end); +} + /** * **************************************** list support ******************************* */ |