diff options
author | Rich Hickey <richhickey@gmail.com> | 2006-06-11 15:40:13 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2006-06-11 15:40:13 +0000 |
commit | b58d5badd4ed397f0f6e9be306ac12311c7049d9 (patch) | |
tree | e523068b29066fdfe14b5422af508179bbbf59b7 | |
parent | c66573864e1cdc9ba5cbef711ce70f0137c50f02 (diff) |
49 files changed, 5807 insertions, 0 deletions
diff --git a/src/jvm/clojure/runtime/AFn.java b/src/jvm/clojure/runtime/AFn.java new file mode 100644 index 00000000..323fe732 --- /dev/null +++ b/src/jvm/clojure/runtime/AFn.java @@ -0,0 +1,101 @@ +/** + * 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 Mar 25, 2006 4:05:37 PM */ + +package org.clojure.runtime; + +public class AFn extends Obj implements IFn{ + +public Object invoke(ThreadLocalData tld) throws Exception + { + return throwArity(); + } + +public Object invoke(ThreadLocalData tld, Object arg1) throws Exception + { + return throwArity(); + } + +public Object invoke(ThreadLocalData tld, Object arg1, Object arg2) throws Exception + { + return throwArity(); + } + +public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3) throws Exception + { + return throwArity(); + } + +public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4) throws Exception + { + return throwArity(); + } + +public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) + throws Exception + { + return throwArity(); + } + +public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Cons args) + throws Exception + { + return throwArity(); + } + +public Object applyTo(ThreadLocalData tld, Cons arglist) throws Exception { + return applyToHelper(this, tld, arglist); +} +static public Object applyToHelper(IFn ifn,ThreadLocalData tld, Cons arglist) throws Exception + { + switch(RT.boundedLength(arglist, 5)) + { + case 0: + return ifn.invoke(tld); + case 1: + return ifn.invoke(tld, arglist.first); + case 2: + return ifn.invoke(tld, arglist.first + , (arglist = arglist.rest).first + ); + case 3: + return ifn.invoke(tld, arglist.first + , (arglist = arglist.rest).first + , (arglist = arglist.rest).first + ); + case 4: + return ifn.invoke(tld, arglist.first + , (arglist = arglist.rest).first + , (arglist = arglist.rest).first + , (arglist = arglist.rest).first + ); + case 5: + return ifn.invoke(tld, arglist.first + , (arglist = arglist.rest).first + , (arglist = arglist.rest).first + , (arglist = arglist.rest).first + , (arglist = arglist.rest).first + ); + default: + return ifn.invoke(tld, arglist.first + , (arglist = arglist.rest).first + , (arglist = arglist.rest).first + , (arglist = arglist.rest).first + , (arglist = arglist.rest).first + , arglist.rest); + } + } + +public static Object throwArity() + { + throw new IllegalArgumentException("Wrong number of args passed"); + } +} diff --git a/src/jvm/clojure/runtime/AGenerator.java b/src/jvm/clojure/runtime/AGenerator.java new file mode 100644 index 00000000..03b35dac --- /dev/null +++ b/src/jvm/clojure/runtime/AGenerator.java @@ -0,0 +1,25 @@ +/** + * 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 3, 2006 */ + +package org.clojure.runtime; + +public abstract class AGenerator implements Iter{ + +Object __val; +int __state = 0; + +public Object get() + { + return __val; + } + +} diff --git a/src/jvm/clojure/runtime/Accessor.java b/src/jvm/clojure/runtime/Accessor.java new file mode 100644 index 00000000..b69bb0bb --- /dev/null +++ b/src/jvm/clojure/runtime/Accessor.java @@ -0,0 +1,83 @@ +/** + * 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 19, 2006 */ + +package org.clojure.runtime; + +public class Accessor extends Symbol implements IFn{ + +String memberName; +Accessor(String name) + { + super(name); + memberName = name.substring(1); + } + + +public Object invoke(ThreadLocalData tld) throws Exception { + return AFn.throwArity(); +} +/** + * Indexer implements IFn for attr access + * This single arg version is the getter + * @param tld + * @param obj - must be Obj + * @return the value of the attr or nil if not found + * @throws Exception + */ +public Object invoke(ThreadLocalData tld, Object obj) throws Exception + { + + return Reflector.invokeInstanceMember(memberName,obj); + } + +/** + * Indexer implements IFn for attr access + * This two arg version is the setter + * @param tld + * @param obj - must be Obj + * @param val + * @return val + * @throws Exception + */ +public Object invoke(ThreadLocalData tld, Object obj, Object val) throws Exception + { + + return Reflector.invokeInstanceMember(memberName,obj,val); + } + +public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3) throws Exception + { + return Reflector.invokeInstanceMember(memberName,arg1,arg2,arg3); + } + +public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4) throws Exception + { + return Reflector.invokeInstanceMember(memberName,arg1,arg2,arg3,arg4); + } + +public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) + throws Exception + { + return Reflector.invokeInstanceMember(memberName,arg1,arg2,arg3,arg4,arg5); + } + +public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Cons args) + throws Exception + { + return Reflector.invokeInstanceMember(memberName,arg1,arg2,arg3,arg4,arg5,args); + } + +public Object applyTo(ThreadLocalData tld, Cons arglist) throws Exception { + return AFn.applyToHelper(this, tld, arglist); +} + +} diff --git a/src/jvm/clojure/runtime/ArrayMap.java b/src/jvm/clojure/runtime/ArrayMap.java new file mode 100644 index 00000000..49dec167 --- /dev/null +++ b/src/jvm/clojure/runtime/ArrayMap.java @@ -0,0 +1,169 @@ +/**
+ * 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.
+ **/
+
+package org.clojure.runtime;
+
+import java.util.Iterator;
+
+/**
+ * Simple implementation of persistent map on an array
+
+ * Note that instances of this class are constant values
+ * i.e. add/remove etc return new values
+ *
+ * Copies array on every change, so only appropriate for _very_small_ maps
+ *
+ * null keys and values are ok, but you won't be able to distinguish a null value via get - use contains/find
+ */
+
+public class ArrayMap implements IMap {
+
+final Object[] array;
+
+public ArrayMap(){
+ this.array = RT.EMPTY_ARRAY;
+}
+
+/**
+ * This ctor captures/aliases the passed array, so do not modify later
+ * @param init {key1,val1,key2,val2,...}
+ */
+public ArrayMap(Object[] init){
+ this.array = init;
+}
+
+public int count() {
+ return array.length/2;
+}
+
+public boolean contains(Object key){
+ return indexOf(key) >= 0;
+}
+
+public IMapEntry find(Object key) {
+ int i = indexOf(key);
+ if(i >= 0)
+ return new Iter(array,i);
+ return null;
+}
+
+public IMap add(Object key) {
+
+ return put(key,null);
+}
+
+public IMap put(Object key, Object val) {
+ int i = indexOf(key);
+ Object[] newArray;
+ if(i >= 0) //already have key, same-sized replacement
+ {
+ if(array[i+1] == val) //no change, no op
+ return this;
+ newArray = array.clone();
+ newArray[i+1] = val;
+ }
+ else //didn't have key, grow
+ {
+ newArray = new Object[array.length + 2];
+ if(array.length > 0)
+ System.arraycopy(array,0,newArray,2,array.length);
+ newArray[0] = key;
+ newArray[1] = val;
+ }
+ return new ArrayMap(newArray);
+}
+
+public IMap remove(Object key) {
+ int i = indexOf(key);
+ if(i >= 0) //have key, will remove
+ {
+ Object[] newArray = new Object[array.length - 2];
+ for(int s=0,d=0;s<array.length;s += 2)
+ {
+ if(!equalKey(array[s],key)) //skip removal key
+ {
+ newArray[d] = array[s];
+ newArray[d+1] = array[s+1];
+ d += 2;
+ }
+ }
+ return new ArrayMap(newArray);
+ }
+ //don't have key, no op
+ return this;
+}
+
+public Object get(Object key) {
+ int i = indexOf(key);
+ if(i >= 0)
+ return array[i + 1];
+ return null;
+}
+
+public int capacity() {
+ return count();
+}
+
+int indexOf(Object key){
+ for(int i=0;i<array.length;i+=2)
+ {
+ if(equalKey(array[i],key))
+ return i;
+ }
+ return -1;
+}
+
+boolean equalKey(Object k1,Object k2){
+ if(k1 == null)
+ return k2 == null;
+ return k1.equals(k2);
+}
+
+public Iterator iterator() {
+ return new Iter(array);
+}
+
+static class Iter implements Iterator,IMapEntry{
+ Object[] array;
+ int i;
+
+ //for iterator
+ Iter(Object[] array){
+ this(array,-2);
+ }
+
+ //for find
+ Iter(Object[] array, int i){
+ this.array = array;
+ this.i = i;
+ }
+
+ public boolean hasNext() {
+ return i < array.length - 2;
+ }
+
+ public Object next() {
+ i+=2;
+ return this;
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object key() {
+ return array[i];
+ }
+
+ public Object val() {
+ return array[i+1];
+ }
+}
+}
diff --git a/src/jvm/clojure/runtime/BigNum.java b/src/jvm/clojure/runtime/BigNum.java new file mode 100644 index 00000000..3955fe6a --- /dev/null +++ b/src/jvm/clojure/runtime/BigNum.java @@ -0,0 +1,220 @@ +/** + * 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 Mar 28, 2006 10:08:33 AM */ + +package org.clojure.runtime; + +import java.math.BigInteger; + +public class BigNum extends IntegerNum{ +public BigInteger val; + +public boolean equals(Object arg0) + { + return arg0 != null + && arg0 instanceof BigNum + && ((BigNum) arg0).val == val; + } + +public int hashCode() + { + return val.hashCode(); + } + +public String toString() + { + return val.toString(); + } + +public BigNum(long val) + { + this.val = BigInteger.valueOf(val); + } + +public BigNum(BigInteger val) + { + this.val = val; + } + +public double doubleValue() + { + return val.doubleValue(); + } + +public float floatValue() + { + return val.floatValue(); + } + +public int intValue() + { + return val.intValue(); + } + +public long longValue() + { + return val.longValue(); + } + +public boolean equiv(Num rhs) + { + return rhs.equivTo(val); + } + +public boolean equivTo(BigInteger x) + { + return x.equals(val); + } + +public boolean equivTo(int x) + { + //must be outside of range of int or would be one itself + return false; + } + +public boolean equivTo(RatioNum x) + { + //wouldn't still be a RatioNum if it was an integer + return false; + } + +public boolean lt(Num rhs) + { + return rhs.gt(val); + } + +public boolean gt(BigInteger x) + { + return x.compareTo(val) < 0; + } + +public boolean gt(int x) + { + return BigInteger.valueOf(x).compareTo(val) < 0; + } + +public boolean gt(RatioNum x) + { + return x.numerator.lt(x.denominator.multiply(val)); + } + +public Num add(Num rhs) + { + return rhs.addTo(val); + } + +public Num addTo(BigInteger x) + { + return Num.from(x.add(val)); + } + +public Num addTo(int x) + { + return Num.from(val.add(BigInteger.valueOf(x))); + } + +public Num addTo(RatioNum x) + { + return x.addTo(val); + } + +public Num subtractFrom(Num x) + { + return x.addTo(val.negate()); + } + +public Num multiplyBy(Num rhs) + { + return rhs.multiply(val); + } + +public Num multiply(BigInteger x) + { + return Num.from(x.multiply(val)); + } + +public Num multiply(int x) + { + return Num.from(val.multiply(BigInteger.valueOf(x))); + } + +public Num multiply(RatioNum x) + { + return x.multiply(val); + } + +public Num divideBy(Num rhs) + { + return rhs.divide(val); + } + +public Num divide(BigInteger n) + { + return Num.divide(n, val); + } + +public Num divide(int n) + { + return Num.divide(BigInteger.valueOf(n), val); + } + +public Num divide(RatioNum x) + { + return Num.divide(x.numerator, x.denominator.multiply(val)); + } + +public Object truncateDivide(ThreadLocalData tld, Num num) + { + return num.truncateBy(tld, val); + } + +public Object truncateBy(ThreadLocalData tld, int div) + { + return Num.truncateBigints(tld, val, BigInteger.valueOf(div)); + } + +public Object truncateBy(ThreadLocalData tld, BigInteger div) + { + return Num.truncateBigints(tld, val, div); + } + +public Object truncateBy(ThreadLocalData tld, RatioNum div) + { + Num q = (Num) Num.truncate(tld, div.denominator.multiply(val), div.numerator); + return RT.setValues(tld, q, q.multiplyBy(div).subtractFrom(this)); + } + +public Num negate() + { + return Num.from(val.negate()); + } + +public boolean minusp() + { + return val.signum() < 0; + } + +public boolean plusp() + { + return val.signum() > 0; + } + +public Num oneMinus() + { + return Num.from(val.subtract(BigInteger.ONE)); + } + +public Num onePlus() + { + return Num.from(val.add(BigInteger.ONE)); + } +} + diff --git a/src/jvm/clojure/runtime/Box.java b/src/jvm/clojure/runtime/Box.java new file mode 100644 index 00000000..e1129029 --- /dev/null +++ b/src/jvm/clojure/runtime/Box.java @@ -0,0 +1,23 @@ +/** + * 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 Mar 27, 2006 8:40:19 PM */ + +package org.clojure.runtime; + +public class Box{ + +public Object val; + +public Box(Object val) + { + this.val = val; + } +} diff --git a/src/jvm/clojure/runtime/Cons.java b/src/jvm/clojure/runtime/Cons.java new file mode 100644 index 00000000..8cdd3bd9 --- /dev/null +++ b/src/jvm/clojure/runtime/Cons.java @@ -0,0 +1,36 @@ +/** + * 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 Mar 25, 2006 11:01:29 AM */ + +package org.clojure.runtime; + +public class Cons extends Obj implements Iter{ + +public final Object first; +public final Cons rest; + +public Cons(Object first, Cons rest) + { + this.first = first; + this.rest = rest; + } + +public Object get() + { + return first; + } + +public Iter iterate() + { + return rest; + } + +} diff --git a/src/jvm/clojure/runtime/DoubleNum.java b/src/jvm/clojure/runtime/DoubleNum.java new file mode 100644 index 00000000..00ec7c7a --- /dev/null +++ b/src/jvm/clojure/runtime/DoubleNum.java @@ -0,0 +1,244 @@ +/** + * 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 Mar 28, 2006 10:13:45 AM */ + +package org.clojure.runtime; + +import java.math.BigInteger; +import java.math.BigDecimal; + +public class DoubleNum extends FloatNum{ +double val; + +public DoubleNum(double val) + { + this.val = val; + } + +public double doubleValue() + { + return val; + } + +public float floatValue() + { + return (float) val; + } + +public int intValue() + { + return (int) val; + } + +public long longValue() + { + return (long) val; + } + +final static BigInteger BIGTEN = BigInteger.valueOf(10); + +public Num toRational() + { + BigDecimal d = new BigDecimal(val); + return Num.divide(d.unscaledValue(), BIGTEN.pow(d.scale())); + } + +public boolean equiv(Num rhs) + { + if(rhs instanceof RatioNum) + return equivTo((RatioNum) rhs); + return val == rhs.doubleValue(); + } + +public boolean equivTo(BigInteger x) + { + return val == x.doubleValue(); + } + +public boolean equivTo(int x) + { + return x == val; + } + +public boolean equivTo(RatioNum x) + { + return toRational().equivTo(x); + } + +public boolean lt(Num rhs) + { + if(rhs instanceof RatioNum) + return toRational().lt(rhs); + return val < rhs.doubleValue(); + } + +public boolean gt(BigInteger x) + { + return val > x.doubleValue(); + } + +public boolean gt(int x) + { + return val > x; + } + +public boolean gt(RatioNum x) + { + return toRational().gt(x); + } + +public Num add(Num rhs) + { + return Num.from(val + rhs.doubleValue()); + } + +public Num addTo(int x) + { + return Num.from(val + x); + } + +public Num addTo(BigInteger x) + { + return Num.from(val + x.doubleValue()); + } + +public Num addTo(RatioNum x) + { + return Num.from(val + |