diff src/clojure/lang/APersistentVector.java @ 10:ef7dbbd6452c

added clojure source goodness
author Robert McIntyre <rlm@mit.edu>
date Sat, 21 Aug 2010 06:25:44 -0400
parents
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/clojure/lang/APersistentVector.java	Sat Aug 21 06:25:44 2010 -0400
     1.3 @@ -0,0 +1,568 @@
     1.4 +/**
     1.5 + *   Copyright (c) Rich Hickey. All rights reserved.
     1.6 + *   The use and distribution terms for this software are covered by the
     1.7 + *   Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
     1.8 + *   which can be found in the file epl-v10.html at the root of this distribution.
     1.9 + *   By using this software in any fashion, you are agreeing to be bound by
    1.10 + * 	 the terms of this license.
    1.11 + *   You must not remove this notice, or any other, from this software.
    1.12 + **/
    1.13 +
    1.14 +/* rich Dec 18, 2007 */
    1.15 +
    1.16 +package clojure.lang;
    1.17 +
    1.18 +import java.io.Serializable;
    1.19 +import java.util.*;
    1.20 +
    1.21 +public abstract class APersistentVector extends AFn implements IPersistentVector, Iterable,
    1.22 +                                                               List,
    1.23 +                                                               RandomAccess, Comparable,
    1.24 +                                                               Serializable {
    1.25 +int _hash = -1;
    1.26 +
    1.27 +public String toString(){
    1.28 +	return RT.printString(this);
    1.29 +}
    1.30 +
    1.31 +public ISeq seq(){
    1.32 +	if(count() > 0)
    1.33 +		return new Seq(this, 0);
    1.34 +	return null;
    1.35 +}
    1.36 +
    1.37 +public ISeq rseq(){
    1.38 +	if(count() > 0)
    1.39 +		return new RSeq(this, count() - 1);
    1.40 +	return null;
    1.41 +}
    1.42 +
    1.43 +static boolean doEquals(IPersistentVector v, Object obj){
    1.44 +	if(v == obj) return true;
    1.45 +	if(obj instanceof List || obj instanceof IPersistentVector)
    1.46 +		{
    1.47 +		Collection ma = (Collection) obj;
    1.48 +		if(ma.size() != v.count() || ma.hashCode() != v.hashCode())
    1.49 +			return false;
    1.50 +		for(Iterator i1 = ((List) v).iterator(), i2 = ma.iterator();
    1.51 +		    i1.hasNext();)
    1.52 +			{
    1.53 +			if(!Util.equals(i1.next(), i2.next()))
    1.54 +				return false;
    1.55 +			}
    1.56 +		return true;
    1.57 +		}
    1.58 +//	if(obj instanceof IPersistentVector)
    1.59 +//		{
    1.60 +//		IPersistentVector ma = (IPersistentVector) obj;
    1.61 +//		if(ma.count() != v.count() || ma.hashCode() != v.hashCode())
    1.62 +//			return false;
    1.63 +//		for(int i = 0; i < v.count(); i++)
    1.64 +//			{
    1.65 +//			if(!Util.equal(v.nth(i), ma.nth(i)))
    1.66 +//				return false;
    1.67 +//			}
    1.68 +//		}
    1.69 +	else
    1.70 +		{
    1.71 +		if(!(obj instanceof Sequential))
    1.72 +			return false;
    1.73 +		ISeq ms = RT.seq(obj);
    1.74 +		for(int i = 0; i < v.count(); i++, ms = ms.next())
    1.75 +			{
    1.76 +			if(ms == null || !Util.equals(v.nth(i), ms.first()))
    1.77 +				return false;
    1.78 +			}
    1.79 +		if(ms != null)
    1.80 +			return false;
    1.81 +		}
    1.82 +
    1.83 +	return true;
    1.84 +
    1.85 +}
    1.86 +
    1.87 +static boolean doEquiv(IPersistentVector v, Object obj){
    1.88 +	if(obj instanceof List || obj instanceof IPersistentVector)
    1.89 +		{
    1.90 +		Collection ma = (Collection) obj;
    1.91 +		if(ma.size() != v.count())
    1.92 +			return false;
    1.93 +		for(Iterator i1 = ((List) v).iterator(), i2 = ma.iterator();
    1.94 +		    i1.hasNext();)
    1.95 +			{
    1.96 +			if(!Util.equiv(i1.next(), i2.next()))
    1.97 +				return false;
    1.98 +			}
    1.99 +		return true;
   1.100 +		}
   1.101 +//	if(obj instanceof IPersistentVector)
   1.102 +//		{
   1.103 +//		IPersistentVector ma = (IPersistentVector) obj;
   1.104 +//		if(ma.count() != v.count() || ma.hashCode() != v.hashCode())
   1.105 +//			return false;
   1.106 +//		for(int i = 0; i < v.count(); i++)
   1.107 +//			{
   1.108 +//			if(!Util.equal(v.nth(i), ma.nth(i)))
   1.109 +//				return false;
   1.110 +//			}
   1.111 +//		}
   1.112 +	else
   1.113 +		{
   1.114 +		if(!(obj instanceof Sequential))
   1.115 +			return false;
   1.116 +		ISeq ms = RT.seq(obj);
   1.117 +		for(int i = 0; i < v.count(); i++, ms = ms.next())
   1.118 +			{
   1.119 +			if(ms == null || !Util.equiv(v.nth(i), ms.first()))
   1.120 +				return false;
   1.121 +			}
   1.122 +		if(ms != null)
   1.123 +			return false;
   1.124 +		}
   1.125 +
   1.126 +	return true;
   1.127 +
   1.128 +}
   1.129 +
   1.130 +public boolean equals(Object obj){
   1.131 +	return doEquals(this, obj);
   1.132 +}
   1.133 +
   1.134 +public boolean equiv(Object obj){
   1.135 +	return doEquiv(this, obj);
   1.136 +}
   1.137 +
   1.138 +public int hashCode(){
   1.139 +	if(_hash == -1)
   1.140 +		{
   1.141 +		int hash = 1;
   1.142 +		Iterator i = iterator();
   1.143 +		while(i.hasNext())
   1.144 +			{
   1.145 +			Object obj = i.next();
   1.146 +			hash = 31 * hash + (obj == null ? 0 : obj.hashCode());
   1.147 +			}
   1.148 +//		int hash = 0;
   1.149 +//		for(int i = 0; i < count(); i++)
   1.150 +//			{
   1.151 +//			hash = Util.hashCombine(hash, Util.hash(nth(i)));
   1.152 +//			}
   1.153 +		this._hash = hash;
   1.154 +		}
   1.155 +	return _hash;
   1.156 +}
   1.157 +
   1.158 +public Object get(int index){
   1.159 +	return nth(index);
   1.160 +}
   1.161 +
   1.162 +public Object nth(int i, Object notFound){
   1.163 +	if(i >= 0 && i < count())
   1.164 +		return nth(i);
   1.165 +	return notFound;
   1.166 +}
   1.167 +
   1.168 +public Object remove(int i){
   1.169 +	throw new UnsupportedOperationException();
   1.170 +}
   1.171 +
   1.172 +public int indexOf(Object o){
   1.173 +	for(int i = 0; i < count(); i++)
   1.174 +		if(Util.equiv(nth(i), o))
   1.175 +			return i;
   1.176 +	return -1;
   1.177 +}
   1.178 +
   1.179 +public int lastIndexOf(Object o){
   1.180 +	for(int i = count() - 1; i >= 0; i--)
   1.181 +		if(Util.equiv(nth(i), o))
   1.182 +			return i;
   1.183 +	return -1;
   1.184 +}
   1.185 +
   1.186 +public ListIterator listIterator(){
   1.187 +	return listIterator(0);
   1.188 +}
   1.189 +
   1.190 +public ListIterator listIterator(final int index){
   1.191 +	return new ListIterator(){
   1.192 +		int nexti = index;
   1.193 +
   1.194 +		public boolean hasNext(){
   1.195 +			return nexti < count();
   1.196 +		}
   1.197 +
   1.198 +		public Object next(){
   1.199 +			return nth(nexti++);
   1.200 +		}
   1.201 +
   1.202 +		public boolean hasPrevious(){
   1.203 +			return nexti > 0;
   1.204 +		}
   1.205 +
   1.206 +		public Object previous(){
   1.207 +			return nth(--nexti);
   1.208 +		}
   1.209 +
   1.210 +		public int nextIndex(){
   1.211 +			return nexti;
   1.212 +		}
   1.213 +
   1.214 +		public int previousIndex(){
   1.215 +			return nexti - 1;
   1.216 +		}
   1.217 +
   1.218 +		public void remove(){
   1.219 +			throw new UnsupportedOperationException();
   1.220 +		}
   1.221 +
   1.222 +		public void set(Object o){
   1.223 +			throw new UnsupportedOperationException();
   1.224 +		}
   1.225 +
   1.226 +		public void add(Object o){
   1.227 +			throw new UnsupportedOperationException();
   1.228 +		}
   1.229 +	};
   1.230 +}
   1.231 +
   1.232 +public List subList(int fromIndex, int toIndex){
   1.233 +	return (List) RT.subvec(this, fromIndex, toIndex);
   1.234 +}
   1.235 +
   1.236 +
   1.237 +public Object set(int i, Object o){
   1.238 +	throw new UnsupportedOperationException();
   1.239 +}
   1.240 +
   1.241 +public void add(int i, Object o){
   1.242 +	throw new UnsupportedOperationException();
   1.243 +}
   1.244 +
   1.245 +public boolean addAll(int i, Collection c){
   1.246 +	throw new UnsupportedOperationException();
   1.247 +}
   1.248 +
   1.249 +
   1.250 +public Object invoke(Object arg1) throws Exception{
   1.251 +	if(Util.isInteger(arg1))
   1.252 +		return nth(((Number) arg1).intValue());
   1.253 +	throw new IllegalArgumentException("Key must be integer");
   1.254 +}
   1.255 +
   1.256 +public Iterator iterator(){
   1.257 +	//todo - something more efficient
   1.258 +	return new Iterator(){
   1.259 +		int i = 0;
   1.260 +
   1.261 +		public boolean hasNext(){
   1.262 +			return i < count();
   1.263 +		}
   1.264 +
   1.265 +		public Object next(){
   1.266 +			return nth(i++);
   1.267 +		}
   1.268 +
   1.269 +		public void remove(){
   1.270 +			throw new UnsupportedOperationException();
   1.271 +		}
   1.272 +	};
   1.273 +}
   1.274 +
   1.275 +public Object peek(){
   1.276 +	if(count() > 0)
   1.277 +		return nth(count() - 1);
   1.278 +	return null;
   1.279 +}
   1.280 +
   1.281 +public boolean containsKey(Object key){
   1.282 +	if(!(Util.isInteger(key)))
   1.283 +		return false;
   1.284 +	int i = ((Number) key).intValue();
   1.285 +	return i >= 0 && i < count();
   1.286 +}
   1.287 +
   1.288 +public IMapEntry entryAt(Object key){
   1.289 +	if(Util.isInteger(key))
   1.290 +		{
   1.291 +		int i = ((Number) key).intValue();
   1.292 +		if(i >= 0 && i < count())
   1.293 +			return new MapEntry(key, nth(i));
   1.294 +		}
   1.295 +	return null;
   1.296 +}
   1.297 +
   1.298 +public IPersistentVector assoc(Object key, Object val){
   1.299 +	if(Util.isInteger(key))
   1.300 +		{
   1.301 +		int i = ((Number) key).intValue();
   1.302 +		return assocN(i, val);
   1.303 +		}
   1.304 +	throw new IllegalArgumentException("Key must be integer");
   1.305 +}
   1.306 +
   1.307 +public Object valAt(Object key, Object notFound){
   1.308 +	if(Util.isInteger(key))
   1.309 +		{
   1.310 +		int i = ((Number) key).intValue();
   1.311 +		if(i >= 0 && i < count())
   1.312 +			return nth(i);
   1.313 +		}
   1.314 +	return notFound;
   1.315 +}
   1.316 +
   1.317 +public Object valAt(Object key){
   1.318 +	return valAt(key, null);
   1.319 +}
   1.320 +
   1.321 +// java.util.Collection implementation
   1.322 +
   1.323 +public Object[] toArray(){
   1.324 +	return RT.seqToArray(seq());
   1.325 +}
   1.326 +
   1.327 +public boolean add(Object o){
   1.328 +	throw new UnsupportedOperationException();
   1.329 +}
   1.330 +
   1.331 +public boolean remove(Object o){
   1.332 +	throw new UnsupportedOperationException();
   1.333 +}
   1.334 +
   1.335 +public boolean addAll(Collection c){
   1.336 +	throw new UnsupportedOperationException();
   1.337 +}
   1.338 +
   1.339 +public void clear(){
   1.340 +	throw new UnsupportedOperationException();
   1.341 +}
   1.342 +
   1.343 +public boolean retainAll(Collection c){
   1.344 +	throw new UnsupportedOperationException();
   1.345 +}
   1.346 +
   1.347 +public boolean removeAll(Collection c){
   1.348 +	throw new UnsupportedOperationException();
   1.349 +}
   1.350 +
   1.351 +public boolean containsAll(Collection c){
   1.352 +	for(Object o : c)
   1.353 +		{
   1.354 +		if(!contains(o))
   1.355 +			return false;
   1.356 +		}
   1.357 +	return true;
   1.358 +}
   1.359 +
   1.360 +public Object[] toArray(Object[] a){
   1.361 +	if(a.length >= count())
   1.362 +		{
   1.363 +		ISeq s = seq();
   1.364 +		for(int i = 0; s != null; ++i, s = s.next())
   1.365 +			{
   1.366 +			a[i] = s.first();
   1.367 +			}
   1.368 +		if(a.length > count())
   1.369 +			a[count()] = null;
   1.370 +		return a;
   1.371 +		}
   1.372 +	else
   1.373 +		return toArray();
   1.374 +}
   1.375 +
   1.376 +public int size(){
   1.377 +	return count();
   1.378 +}
   1.379 +
   1.380 +public boolean isEmpty(){
   1.381 +	return count() == 0;
   1.382 +}
   1.383 +
   1.384 +public boolean contains(Object o){
   1.385 +	for(ISeq s = seq(); s != null; s = s.next())
   1.386 +		{
   1.387 +		if(Util.equiv(s.first(), o))
   1.388 +			return true;
   1.389 +		}
   1.390 +	return false;
   1.391 +}
   1.392 +
   1.393 +public int length(){
   1.394 +	return count();
   1.395 +}
   1.396 +
   1.397 +public int compareTo(Object o){
   1.398 +	IPersistentVector v = (IPersistentVector) o;
   1.399 +	if(count() < v.count())
   1.400 +		return -1;
   1.401 +	else if(count() > v.count())
   1.402 +		return 1;
   1.403 +	for(int i = 0; i < count(); i++)
   1.404 +		{
   1.405 +		int c = Util.compare(nth(i),v.nth(i));
   1.406 +		if(c != 0)
   1.407 +			return c;
   1.408 +		}
   1.409 +	return 0;
   1.410 +}
   1.411 +
   1.412 +    static class Seq extends ASeq implements IndexedSeq, IReduce{
   1.413 +	//todo - something more efficient
   1.414 +	final IPersistentVector v;
   1.415 +	final int i;
   1.416 +
   1.417 +
   1.418 +	public Seq(IPersistentVector v, int i){
   1.419 +		this.v = v;
   1.420 +		this.i = i;
   1.421 +	}
   1.422 +
   1.423 +	Seq(IPersistentMap meta, IPersistentVector v, int i){
   1.424 +		super(meta);
   1.425 +		this.v = v;
   1.426 +		this.i = i;
   1.427 +	}
   1.428 +
   1.429 +	public Object first(){
   1.430 +		return v.nth(i);
   1.431 +	}
   1.432 +
   1.433 +	public ISeq next(){
   1.434 +		if(i + 1 < v.count())
   1.435 +			return new APersistentVector.Seq(v, i + 1);
   1.436 +		return null;
   1.437 +	}
   1.438 +
   1.439 +	public int index(){
   1.440 +		return i;
   1.441 +	}
   1.442 +
   1.443 +	public int count(){
   1.444 +		return v.count() - i;
   1.445 +	}
   1.446 +
   1.447 +	public APersistentVector.Seq withMeta(IPersistentMap meta){
   1.448 +		return new APersistentVector.Seq(meta, v, i);
   1.449 +	}
   1.450 +
   1.451 +	public Object reduce(IFn f) throws Exception{
   1.452 +		Object ret = v.nth(i);
   1.453 +		for(int x = i + 1; x < v.count(); x++)
   1.454 +			ret = f.invoke(ret, v.nth(x));
   1.455 +		return ret;
   1.456 +	}
   1.457 +
   1.458 +	public Object reduce(IFn f, Object start) throws Exception{
   1.459 +		Object ret = f.invoke(start, v.nth(i));
   1.460 +		for(int x = i + 1; x < v.count(); x++)
   1.461 +			ret = f.invoke(ret, v.nth(x));
   1.462 +		return ret;
   1.463 +	}
   1.464 +    }
   1.465 +
   1.466 +public static class RSeq extends ASeq implements IndexedSeq, Counted{
   1.467 +	final IPersistentVector v;
   1.468 +	final int i;
   1.469 +
   1.470 +	public RSeq(IPersistentVector vector, int i){
   1.471 +		this.v = vector;
   1.472 +		this.i = i;
   1.473 +	}
   1.474 +
   1.475 +	RSeq(IPersistentMap meta, IPersistentVector v, int i){
   1.476 +		super(meta);
   1.477 +		this.v = v;
   1.478 +		this.i = i;
   1.479 +	}
   1.480 +
   1.481 +	public Object first(){
   1.482 +		return v.nth(i);
   1.483 +	}
   1.484 +
   1.485 +	public ISeq next(){
   1.486 +		if(i > 0)
   1.487 +			return new APersistentVector.RSeq(v, i - 1);
   1.488 +		return null;
   1.489 +	}
   1.490 +
   1.491 +	public int index(){
   1.492 +		return i;
   1.493 +	}
   1.494 +
   1.495 +	public int count(){
   1.496 +		return i + 1;
   1.497 +	}
   1.498 +
   1.499 +	public APersistentVector.RSeq withMeta(IPersistentMap meta){
   1.500 +		return new APersistentVector.RSeq(meta, v, i);
   1.501 +	}
   1.502 +}
   1.503 +
   1.504 +static class SubVector extends APersistentVector implements IObj{
   1.505 +	final IPersistentVector v;
   1.506 +	final int start;
   1.507 +	final int end;
   1.508 +	final IPersistentMap _meta;
   1.509 +
   1.510 +
   1.511 +
   1.512 +	public SubVector(IPersistentMap meta, IPersistentVector v, int start, int end){
   1.513 +		this._meta = meta;
   1.514 +
   1.515 +		if(v instanceof APersistentVector.SubVector)
   1.516 +			{
   1.517 +			APersistentVector.SubVector sv = (APersistentVector.SubVector) v;
   1.518 +			start += sv.start;
   1.519 +			end += sv.start;
   1.520 +			v = sv.v;
   1.521 +			}
   1.522 +		this.v = v;
   1.523 +		this.start = start;
   1.524 +		this.end = end;
   1.525 +	}
   1.526 +
   1.527 +	public Object nth(int i){
   1.528 +		if(start + i >= end)
   1.529 +			throw new IndexOutOfBoundsException();
   1.530 +		return v.nth(start + i);
   1.531 +	}
   1.532 +
   1.533 +	public IPersistentVector assocN(int i, Object val){
   1.534 +		if(start + i > end)
   1.535 +			throw new IndexOutOfBoundsException();
   1.536 +		else if(start + i == end)
   1.537 +			return cons(val);
   1.538 +		return new SubVector(_meta, v.assocN(start + i, val), start, end);
   1.539 +	}
   1.540 +
   1.541 +	public int count(){
   1.542 +		return end - start;
   1.543 +	}
   1.544 +
   1.545 +	public IPersistentVector cons(Object o){
   1.546 +		return new SubVector(_meta, v.assocN(end, o), start, end + 1);
   1.547 +	}
   1.548 +
   1.549 +	public IPersistentCollection empty(){
   1.550 +		return PersistentVector.EMPTY.withMeta(meta());
   1.551 +	}
   1.552 +
   1.553 +	public IPersistentStack pop(){
   1.554 +		if(end - 1 == start)
   1.555 +			{
   1.556 +			return PersistentVector.EMPTY;
   1.557 +			}
   1.558 +		return new SubVector(_meta, v, start, end - 1);
   1.559 +	}
   1.560 +
   1.561 +	public SubVector withMeta(IPersistentMap meta){
   1.562 +		if(meta == _meta)
   1.563 +			return this;
   1.564 +		return new SubVector(meta, v, start, end);
   1.565 +	}
   1.566 +
   1.567 +	public IPersistentMap meta(){
   1.568 +		return _meta;
   1.569 +	}
   1.570 +}
   1.571 +}