summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2007-12-18 18:14:30 +0000
committerRich Hickey <richhickey@gmail.com>2007-12-18 18:14:30 +0000
commitb876bc01060191c4fecef062bdddd190c79fd83f (patch)
tree80a02e9b2a2db062fddebbddf73f81ca8c362f29 /src
parent563ce9095b9b2610a845123dec1d8e2884177aa0 (diff)
added subvec
Diffstat (limited to 'src')
-rw-r--r--src/boot.clj8
-rw-r--r--src/jvm/clojure/lang/APersistentVector.java349
-rw-r--r--src/jvm/clojure/lang/IPersistentVector.java3
-rw-r--r--src/jvm/clojure/lang/PersistentVector.java280
-rw-r--r--src/jvm/clojure/lang/RT.java8
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 *******************************
*/