diff options
author | Rich Hickey <richhickey@gmail.com> | 2006-04-02 16:34:00 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2006-04-02 16:34:00 +0000 |
commit | ab3658c3f102d470c146260c87d7ea34b365126f (patch) | |
tree | 25af35169d4be51c310372e6788ef4e05ea865c7 | |
parent | ad76fd174341a19ec4b311c17d3c760637d81724 (diff) |
Initial commit of CLI runtime
-rw-r--r-- | src/cli/runtime/AFn.cs | 103 | ||||
-rw-r--r-- | src/cli/runtime/AMap.cs | 40 | ||||
-rw-r--r-- | src/cli/runtime/BigNum.cs | 225 | ||||
-rw-r--r-- | src/cli/runtime/Box.cs | 28 | ||||
-rw-r--r-- | src/cli/runtime/Cons.cs | 32 | ||||
-rw-r--r-- | src/cli/runtime/DoubleNum.cs | 242 | ||||
-rw-r--r-- | src/cli/runtime/FixNum.cs | 243 | ||||
-rw-r--r-- | src/cli/runtime/FloatNum.cs | 21 | ||||
-rw-r--r-- | src/cli/runtime/IFn.cs | 37 | ||||
-rw-r--r-- | src/cli/runtime/IntegerNum.cs | 21 | ||||
-rw-r--r-- | src/cli/runtime/Keyword.cs | 49 | ||||
-rw-r--r-- | src/cli/runtime/Namespace.cs | 83 | ||||
-rw-r--r-- | src/cli/runtime/Num.cs | 252 | ||||
-rw-r--r-- | src/cli/runtime/RT.cs | 212 | ||||
-rw-r--r-- | src/cli/runtime/RatioNum.cs | 229 | ||||
-rw-r--r-- | src/cli/runtime/RationalNum.cs | 21 | ||||
-rw-r--r-- | src/cli/runtime/RealNum.cs | 21 | ||||
-rw-r--r-- | src/cli/runtime/RestFn0.cs | 65 | ||||
-rw-r--r-- | src/cli/runtime/RestFn1.cs | 63 | ||||
-rw-r--r-- | src/cli/runtime/RestFn2.cs | 59 | ||||
-rw-r--r-- | src/cli/runtime/RestFn3.cs | 56 | ||||
-rw-r--r-- | src/cli/runtime/RestFn4.cs | 53 | ||||
-rw-r--r-- | src/cli/runtime/RestFn5.cs | 49 | ||||
-rw-r--r-- | src/cli/runtime/Symbol.cs | 96 | ||||
-rw-r--r-- | src/cli/runtime/ThreadLocalData.cs | 86 |
25 files changed, 2386 insertions, 0 deletions
diff --git a/src/cli/runtime/AFn.cs b/src/cli/runtime/AFn.cs new file mode 100644 index 00000000..9b1cb05b --- /dev/null +++ b/src/cli/runtime/AFn.cs @@ -0,0 +1,103 @@ +/** + * 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 */ + +using System;
+ +namespace org.clojure.runtime
+{ + +public class AFn : AMap , IFn
+ { + +virtual public Object invoke(ThreadLocalData tld) /*throws Exception*/ + { + return throwArity(); + } + +virtual public Object invoke(ThreadLocalData tld, Object arg1) /*throws Exception*/ + { + return throwArity(); + } + +virtual public Object invoke(ThreadLocalData tld, Object arg1, Object arg2) /*throws Exception*/ + { + return throwArity(); + } + +virtual public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3) /*throws Exception*/ + { + return throwArity(); + } + +virtual public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4) /*throws Exception*/ + { + return throwArity(); + } + +virtual public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) + /*throws Exception*/ + { + return throwArity(); + } + +virtual public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Cons args) + /*throws Exception*/ + { + return throwArity(); + } + +virtual public Object applyTo(ThreadLocalData tld, Cons arglist) /*throws Exception*/ + { + switch(RT.boundedLength(arglist, 5)) + { + case 0: + return invoke(tld); + case 1: + return invoke(tld, arglist.first); + case 2: + return invoke(tld, arglist.first + , (arglist = arglist.rest).first + ); + case 3: + return invoke(tld, arglist.first + , (arglist = arglist.rest).first + , (arglist = arglist.rest).first + ); + case 4: + return invoke(tld, arglist.first + , (arglist = arglist.rest).first + , (arglist = arglist.rest).first + , (arglist = arglist.rest).first + ); + case 5: + return invoke(tld, arglist.first + , (arglist = arglist.rest).first + , (arglist = arglist.rest).first + , (arglist = arglist.rest).first + , (arglist = arglist.rest).first + ); + default: + return invoke(tld, arglist.first + , (arglist = arglist.rest).first + , (arglist = arglist.rest).first + , (arglist = arglist.rest).first + , (arglist = arglist.rest).first + , arglist.rest); + } + } + +protected Object throwArity() + { + throw new Exception("Wrong number of args passed"); + } +} +}
\ No newline at end of file diff --git a/src/cli/runtime/AMap.cs b/src/cli/runtime/AMap.cs new file mode 100644 index 00000000..76850122 --- /dev/null +++ b/src/cli/runtime/AMap.cs @@ -0,0 +1,40 @@ +/** + * 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 3:44:58 PM */ + +using System;
+using System.Collections.Specialized;
+ +namespace org.clojure.runtime
+{ + +public class AMap
+{ + +HybridDictionary attrs; +public static int INITIAL_SIZE = 7; + +public Object put(Symbol key, Object val) + { + if(attrs == null) + attrs = new HybridDictionary(INITIAL_SIZE); + attrs[key] = val; + return val; + } + +public Object get(Symbol key) + { + if(attrs == null) + return null; + return attrs[key]; + } +} +}
\ No newline at end of file diff --git a/src/cli/runtime/BigNum.cs b/src/cli/runtime/BigNum.cs new file mode 100644 index 00000000..629f09de --- /dev/null +++ b/src/cli/runtime/BigNum.cs @@ -0,0 +1,225 @@ +/** + * 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 */ + +using System;
+using java.math; + +namespace org.clojure.runtime
+{ + + +public class BigNum : IntegerNum{ +public BigInteger val; + +override public Boolean Equals(Object arg0) + { + return arg0 != null + && arg0 is BigNum + && ((BigNum) arg0).val == val; + } + +override public int GetHashCode() + { + return val.GetHashCode(); + } + +override public String ToString() + { + return val.ToString(); + } + +public BigNum(long val) + { + this.val = BigInteger.valueOf(val); + } + +public BigNum(BigInteger val) + { + this.val = val; + } + +override public double doubleValue() + { + return val.doubleValue(); + } + +override public float floatValue() + { + return val.floatValue(); + } + +override public int intValue() + { + return val.intValue(); + } + +override public long longValue() + { + return val.longValue(); + } + +override public Boolean equiv(Num rhs) + { + return rhs.equivTo(val); + } + +override public Boolean equivTo(BigInteger x) + { + return x.Equals(val); + } + +override public Boolean equivTo(int x) + { + //must be outside of range of int or would be one itself + return false; + } + +override public Boolean equivTo(RatioNum x) + { + //wouldn't still be a RatioNum if it was an integer + return false; + } + +override public Boolean lt(Num rhs) + { + return rhs.gt(val); + } + +override public Boolean gt(BigInteger x) + { + return x.compareTo(val) < 0; + } + +override public Boolean gt(int x) + { + return BigInteger.valueOf(x).compareTo(val) < 0; + } + +override public Boolean gt(RatioNum x) + { + return x.numerator.lt(x.denominator.multiply(val)); + } + +override public Num add(Num rhs) + { + return rhs.addTo(val); + } + +override public Num addTo(BigInteger x) + { + return Num.from(x.add(val)); + } + +override public Num addTo(int x) + { + return Num.from(val.add(BigInteger.valueOf(x))); + } + +override public Num addTo(RatioNum x) + { + return x.addTo(val); + } + +override public Num subtractFrom(Num x) + { + return x.addTo(val.negate()); + } + +override public Num multiplyBy(Num rhs) + { + return rhs.multiply(val); + } + +override public Num multiply(BigInteger x) + { + return Num.from(x.multiply(val)); + } + +override public Num multiply(int x) + { + return Num.from(val.multiply(BigInteger.valueOf(x))); + } + +override public Num multiply(RatioNum x) + { + return x.multiply(val); + } + +override public Num divideBy(Num rhs) + { + return rhs.divide(val); + } + +override public Num divide(BigInteger n) + { + return Num.divide(n, val); + } + +override public Num divide(int n) + { + return Num.divide(BigInteger.valueOf(n), val); + } + +override public Num divide(RatioNum x) + { + return Num.divide(x.numerator, x.denominator.multiply(val)); + } + +override public Object truncateDivide(ThreadLocalData tld, Num num) + { + return num.truncateBy(tld, val); + } + +override public Object truncateBy(ThreadLocalData tld, int div) + { + return Num.truncateBigints(tld, val, BigInteger.valueOf(div)); + } + +override public Object truncateBy(ThreadLocalData tld, BigInteger div) + { + return Num.truncateBigints(tld, val, div); + } + +override 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)); + } + +override public Num negate() + { + return Num.from(val.negate()); + } + +override public Boolean minusp() + { + return val.signum() < 0; + } + +override public Boolean plusp() + { + return val.signum() > 0; + } + + +override public Num oneMinus() + { + return Num.from(val.subtract(BIG_ONE)); + } + +override public Num onePlus() + { + return Num.from(val.add(BIG_ONE)); + } +} +} + diff --git a/src/cli/runtime/Box.cs b/src/cli/runtime/Box.cs new file mode 100644 index 00000000..37915bd9 --- /dev/null +++ b/src/cli/runtime/Box.cs @@ -0,0 +1,28 @@ +/** + * 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 */ + +using System;
+
+namespace org.clojure.runtime
+{ + +public class Box
+{ + +public Object val; + +public Box(Object val) + { + this.val = val; + } +} +} diff --git a/src/cli/runtime/Cons.cs b/src/cli/runtime/Cons.cs new file mode 100644 index 00000000..eec4e475 --- /dev/null +++ b/src/cli/runtime/Cons.cs @@ -0,0 +1,32 @@ +/** + * 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 */ + +using System;
+ +namespace org.clojure.runtime
+{ + +public class Cons : AMap
+ { + +public Object first; +public Cons rest; + +public Cons(Object first, Cons rest) + { + this.first = first; + this.rest = rest; + } + +} + +} diff --git a/src/cli/runtime/DoubleNum.cs b/src/cli/runtime/DoubleNum.cs new file mode 100644 index 00000000..f3fcc278 --- /dev/null +++ b/src/cli/runtime/DoubleNum.cs @@ -0,0 +1,242 @@ +/** + * 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 */ + +using System;
+using java.math;
+
+namespace org.clojure.runtime
+{ + +public class DoubleNum : FloatNum{ +double val; + +public DoubleNum(double val) + { + this.val = val; + } + +override public double doubleValue() + { + return val; + } + +override public float floatValue() + { + return (float) val; + } + +override public int intValue() + { + return (int) val; + } + +override public long longValue() + { + return (long) val; + } + + +public Num toRational() + { + BigDecimal d = new BigDecimal(val); + return Num.divide(d.movePointRight(d.scale()).toBigInteger(), BIGTEN.pow(d.scale())); + } + +override public Boolean equiv(Num rhs) + { + if(rhs is RatioNum) + return equivTo((RatioNum) rhs); + return val == rhs.doubleValue(); + } + +override public Boolean equivTo(BigInteger x) + { + return val == x.doubleValue(); + } + +override public Boolean equivTo(int x) + { + return x == val; + } + +override public Boolean equivTo(RatioNum x) + { + return toRational().equivTo(x); + } + +override public Boolean lt(Num rhs) + { + if(rhs is RatioNum) + return toRational().lt(rhs); + return val < rhs.doubleValue(); + } + +override public Boolean gt(BigInteger x) + { + return val > x.doubleValue(); + } + +override public Boolean gt(int x) + { + return val > x; + } + +override public Boolean gt(RatioNum x) + { + return toRational().gt(x); + } + +override public Num add(Num rhs) + { + return Num.from(val + rhs.doubleValue()); + } + +override public Num addTo(int x) + { + return Num.from(val + x); + } + +override public Num addTo(BigInteger x) + { + return Num.from(val + x.doubleValue()); + } + +override public Num addTo(RatioNum x) + { + return Num.from(val + x.doubleValue()); + } + +override public Num subtractFrom(Num x) + { + return Num.from(x.doubleValue() - val); + } + +override public Num multiplyBy(Num rhs) + { + return Num.from(val * rhs.doubleValue()); + } + +override public Num multiply(int x) + { + return Num.from(val * x); + } + +override public Num multiply(BigInteger x) + { + return Num.from(val * x.doubleValue()); + } + +override public Num multiply(RatioNum x) + { + return Num.from(val * x.doubleValue()); + } + +override public Num divideBy(Num rhs) + { + return Num.from(val / rhs.doubleValue()); + } + +override public Num divide(int x) + { + return Num.from(x / val); + } + +override public Num divide(BigInteger x) + { + return Num.from(x.doubleValue() / val); + } + +override public Num divide(RatioNum x) + { + return Num.from(x.doubleValue() / val); + } + +static Object truncate(ThreadLocalData tld, double n, double d) + { + double q = n / d; + if(q <= Int32.MaxValue && q >= Int32.MinValue) + { + return RT.setValues(tld, Num.from((int) q), + Num.from(n - ((int) q) * d)); + } + else + { //bigint quotient + Num bq = Num.from(new BigDecimal(q).toBigInteger()); + return RT.setValues(tld, bq, + Num.from(n - bq.doubleValue() * d)); + } + } + +override public Object truncateBy(ThreadLocalData tld, BigInteger x) + { + return truncate(tld, val, x.doubleValue()); + } + +override public Object truncateBy(ThreadLocalData tld, int x) + { + return truncate(tld, val, x); + } + +override public Object truncateBy(ThreadLocalData tld, RatioNum x) + { + return truncate(tld, val, x.doubleValue()); + } + +override public Object truncateDivide(ThreadLocalData tld, Num num) + { + return truncate(tld, num.doubleValue(), val); + } + +override public Num negate() + { + return Num.from(-val); + } + +override public Boolean Equals(Object arg0) + { + return arg0 != null + && arg0 is DoubleNum + &&((DoubleNum) arg0).val.Equals(val); + } + +override public int GetHashCode() + { + return val.GetHashCode(); + } + +override public String ToString() + { + return val.ToString(); + } + +override public Boolean minusp() + { + return val < 0; + } + +override public Boolean plusp() + { + return val > 0; + } + +override public Num oneMinus() + { + return Num.from(val - 1); + } + +override public Num onePlus() + { + return Num.from(val + 1); + } + +} +} diff --git a/src/cli/runtime/FixNum.cs b/src/cli/runtime/FixNum.cs new file mode 100644 index 00000000..99750aa7 --- /dev/null +++ b/src/cli/runtime/FixNum.cs @@ -0,0 +1,243 @@ +/** + * 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:09:27 AM */ + +using System;
+using java.math;
+ +namespace org.clojure.runtime
+{ + + +public class FixNum : IntegerNum{ +public int val; + +override public Boolean Equals(Object arg0) + { + return arg0 != null + && arg0 is FixNum + && ((FixNum) arg0).val == val; + } + +override public int GetHashCode() + { + return val; + } + +override public String ToString() + { + return val.ToString(); + } + +public FixNum(int val) + { + this.val = val; + } + +override public double doubleValue() + { + return (double) val; + } + +override public float floatValue() + { + return (float) val; + } + +override public int intValue() + { + return val; + } + +override public long longValue() + { + return (long) val; + } + +override public Boolean equiv(Num rhs) + { + return rhs.equivTo(val); + } + +override public Boolean equivTo(BigInteger x) + { + //wouldn't still be a BigInteger if it fit in int + return false; + } + +override public Boolean equivTo(int x) + { + return x == val; + } + +override public Boolean equivTo(RatioNum x) + { + //wouldn't still be a RatioNum if it was an integer + return false; + } + +override public Boolean lt(Num rhs) + { + return rhs.gt(val); + } + +override public Boolean gt(BigInteger x) + { + return x.compareTo(BigInteger.valueOf(val)) < 0; + } + +override public Boolean gt(int x) + { + return x < val; + } + +override public Boolean gt(RatioNum x) + { + return x.numerator.lt(x.denominator.multiply(val)); + } + +override public Num add(Num rhs) + { + return rhs.addTo(val); + } + +override public Num addTo(BigInteger x) + { + return Num.from(x.add(BigInteger.valueOf(val))); + } + +override public Num addTo(int x) + { + return Num.from((long) x + val); + } + +override public Num addTo(RatioNum x) + { + return x.addTo(val); + } + +override public Num subtractFrom(Num x) + { + return x.addTo(-val); + } + +override public Num multiplyBy(Num rhs) + { + return rhs.multiply(val); + } + +override public Num multiply(BigInteger x) + { + return Num.from(x.multiply(BigInteger.valueOf(val))); + } + +override public Num multiply(int x) + { + return Num.from((long) x * val); + } + +override public Num multiply(RatioNum x) + { + return x.multiply(val); + } + +override public Object truncateDivide(ThreadLocalData tld, Num num) + { + return num.truncateBy(tld, val); + } + +override public Object truncateBy(ThreadLocalData tld, int div) + { + return RT.setValues(tld, Num.from(val / div), Num.from(val % div)); + } + +override public Object truncateBy(ThreadLocalData tld, BigInteger div) + { + return Num.truncateBigints(tld, BigInteger.valueOf(val), div); + } + +override 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)); + } + +override public Num divideBy(Num rhs) + { + return rhs.divide(val); + } + +override public Num divide(BigInteger n) + { + return Num.divide(n, BigInteger.valueOf(val)); + } + +static int gcdf(int u, int v) + { + while(v != 0) + { + int r = u % v; + u = v; + v = r; + } + return u; + } + +override public Num divide(int n) + { + int gcd = gcdf(n, val); + if(gcd == 0) + return Num.ZERO; + + n = n / gcd; + int d = val / gcd; + if(d == 1) + return Num.from(n); + if(d < 0) + { + n = -n; + d = -d; + } + return new RatioNum((IntegerNum) Num.from(n), (IntegerNum) Num.from(d)); + } + +override public Num divide(RatioNum x) + { + return Num.divide(x.numerator, x.denominator.multiply(val)); + } + +override public Num negate() + { + return Num.from(-val); + } + +override public Boolean minusp() + { + return val < 0; + } + +override public Boolean plusp() + { + return val > 0; + } + +override public Num oneMinus() + { + return Num.from(val - 1); + } + +override public Num onePlus() + { + return Num.from(val + 1); + } + +} +} diff --git a/src/cli/runtime/FloatNum.cs b/src/cli/runtime/FloatNum.cs new file mode 100644 index 00000000..3031e4f6 --- /dev/null +++ b/src/cli/runtime/FloatNum.cs @@ -0,0 +1,21 @@ +/** + * 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:17:21 AM */ + +using System;
+
+namespace org.clojure.runtime
+{ + +public abstract class FloatNum : RealNum { + +} +} diff --git a/src/cli/runtime/IFn.cs b/src/cli/runtime/IFn.cs new file mode 100644 index 00000000..e96fd902 --- /dev/null +++ b/src/cli/runtime/IFn.cs @@ -0,0 +1,37 @@ +/** + * 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 3:54:03 PM */ + +using System;
+
+namespace org.clojure.runtime
+{ +public interface IFn{ + +Object invoke(ThreadLocalData tld) /*throws Exception*/; + +Object invoke(ThreadLocalData tld, Object arg1) /*throws Exception*/; + +Object invoke(ThreadLocalData tld, Object arg1, Object arg2) /*throws Exception*/; + +Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3) /*throws Exception*/; + +Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4) /*throws Exception*/; + +Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) + /*throws Exception*/; + +Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, + Cons args) /*throws Exception*/; + +Object applyTo(ThreadLocalData tld, Cons arglist) /*throws Exception*/; +} +} diff --git a/src/cli/runtime/IntegerNum.cs b/src/cli/runtime/IntegerNum.cs new file mode 100644 index 00000000..7e24b1e6 --- /dev/null +++ b/src/cli/runtime/IntegerNum.cs @@ -0,0 +1,21 @@ +/** + * 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:11:55 AM */ + +using System;
+ +namespace org.clojure.runtime
+{ + +public abstract class IntegerNum : RationalNum { + +} +}
\ No newline at end of file diff --git a/src/cli/runtime/Keyword.cs b/src/cli/runtime/Keyword.cs new file mode 100644 index 00000000..8748cdf1 --- /dev/null +++ b/src/cli/runtime/Keyword.cs @@ -0,0 +1,49 @@ +/** + * 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 29, 2006 10:39:05 AM */ + +using System;
+ +namespace org.clojure.runtime
+{ + +public class Keyword : Symbol
+ { +/** + * Used by Namespace.intern() + * + * @param name + * @param ns + */ +internal Keyword(String name, Namespace ns): + base(name, ns) + + { + this.val = this; + this.fn = this; + } + +override public Object getValue(ThreadLocalData tld) + { + return this; + } + +override public Object setValue(ThreadLocalData tld, Object val) + { + throw new InvalidOperationException("Cannot set the value of a keyword"); + } + +override public String ToString() + { + return ":" + name; + } +} +}
\ No newline at end of file diff --git a/src/cli/runtime/Namespace.cs b/src/cli/runtime/Namespace.cs new file mode 100644 index 00000000..0a4acdf6 --- /dev/null +++ b/src/cli/runtime/Namespace.cs @@ -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 Mar 27, 2006 1:29:39 PM */ + +using System;
+using System.Collections.Specialized;
+ +namespace org.clojure.runtime
+{ + +public class Namespace
+{ + +/** + * String->Namespace + */ +static public HybridDictionary table = new HybridDictionary(); + +/** + * String->Symbol + */ +public HybridDictionary symbols = new HybridDictionary(); +public String name; + +static public Namespace globalNS = new Namespace(""); +static public Namespace keywordNS = new KeywordNamespace("keyword"); + +class KeywordNamespace : Namespace{ + public KeywordNamespace(String name) : base(name) + { + + } + override public Symbol intern(String name) + { + Symbol sym = (Symbol) symbols[name]; + if(sym == null) + symbols.Add(name, sym = new Keyword(name, this)); + return sym; + } +}; + +Namespace(String name) + { + this.name = name; + table.Add(name, this); + } + +static public Namespace find(String name) + { + return (Namespace) table[name]; + } + +static public Namespace findOrCreate(String name) + { + lock(table) + { + Namespace ns = find(name); + if(ns == null) + ns = new Namespace(name); + return ns; + } + } + +virtual public Symbol intern(String name) + { + lock(symbols) + { + Symbol sym = (Symbol) symbols[name]; + if(sym == null) + symbols.Add(name, sym = new Symbol(name, this)); + return sym; + } + } +} +} diff --git a/src/cli/runtime/Num.cs b/src/cli/runtime/Num.cs new file mode 100644 index 00000000..86120be1 --- /dev/null +++ b/src/cli/runtime/Num.cs @@ -0,0 +1,252 @@ +/** + * 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:07:33 AM */ + +using System;
+using java.math;
+
+namespace org.clojure.runtime
+{ + +public abstract class Num : IComparable /* TODO: , IConvertible*/
+ { + +public static Num ZERO = from(0); +public static Num ONE = from(1); + +static public Num from(int val) + { + //todo - cache a bunch of small fixnums + return new FixNum(val); + } + +static public Num from(double val) + { + return new DoubleNum(val); + } + +static public Num from(long val) + { + if(val <= Int32.MaxValue && val >= Int32.MinValue) + return from((int) val); + else + return new BigNum(val); + } + +static public Num from(BigInteger val) + { + if(val.bitLength() < 32) + return from(val.intValue()); + else + return new BigNum(val); + } + + internal static BigInteger BIGTEN = BigInteger.valueOf(10); + +static public Num from(Object x) + { + if(x is Num) + return (Num) x; + else + { + IConvertible c = x as IConvertible; + if(c != null) + { + switch(c.GetTypeCode()) + { + case TypeCode.Int32: + return Num.from((Int32) x); + case TypeCode.Double: + case TypeCode.Single: + return Num.from(Convert.ToDouble(x)); + case TypeCode.Int64: + return Num.from((Int64) x); + //TODO: Decimal w/o string conversion + case TypeCode.Decimal: + BigDecimal d = new BigDecimal(x.ToString()); + return Num.divide(d.movePointRight(d.scale()).toBigInteger(), + BIGTEN.pow(d.scale())); + default: + return Num.from(Convert.ToInt32(x)); + } + } + else if(x is BigInteger) + return Num.from((BigInteger) x); + else + throw new ArgumentException("Cannot convert argument: " + x + " to Num"); + } + } + + + abstract public double doubleValue(); + + abstract public float floatValue(); + + abstract public int intValue(); + + abstract public long longValue(); + +static public Num add(Object x, Object y) + { + //if(x instanceof Num && y instanceof Num) + //return ((Num)x).add((Num) y); + return Num.from(x).add(Num.from(y)); + } + +abstract public Num add(Num rhs); + +abstract public Num addTo(int x); + +abstract public Num addTo(BigInteger x); + +abstract public Num addTo(RatioNum x); + +static public Num subtract(Object x, Object y) + { + return Num.from(y).subtractFrom(Num.from(x)); + } + +//this double-dispatches to addTo(-self) +abstract public Num subtractFrom(Num rhs); + +static public Num multiply(Object x, Object y) + { + return Num.from(x).multiplyBy(Num.from(y)); + } + +abstract public Num multiplyBy(Num rhs); + +abstract public Num multiply(int x); + +abstract public Num multiply(BigInteger x); + +abstract public Num multiply(RatioNum x); + +static public Num divide(Object x, Object y) + { + return Num.from(x).divideBy(Num.from(y)); + } + +abstract public Num divideBy(Num rhs); + +abstract public Num divide(int x); + +abstract public Num divide(BigInteger x); + +abstract public Num divide(RatioNum x); + +static public Object truncate(ThreadLocalData tld, Object num, Object div) + { + return Num.from(div).truncateDivide(tld, Num.from(num)); + } + +abstract public Object truncateDivide(ThreadLocalData tld, Num rhs); + +abstract public Object truncateBy(ThreadLocalData tld, int x); + +abstract public Object truncateBy(ThreadLocalData tld, BigInteger x); + +abstract public Object truncateBy(ThreadLocalData tld, RatioNum x); + +static public Object truncateBigints(ThreadLocalData tld, BigInteger n, BigInteger d) + { + BigInteger[] result = n.divideAndRemainder(d); + return RT.setValues(tld, Num.from(result[0]), Num.from(result[1])); + } + + internal static BigInteger BIG_ONE = BigInteger.valueOf(1); + internal static BigInteger BIG_ZERO = BigInteger.valueOf(0); + +static public Num divide(BigInteger n, BigInteger d) + { + BigInteger gcd = n.gcd(d); + if(gcd.Equals(BIG_ZERO)) + return Num.ZERO; + n = n.divide(gcd); + d = d.divide(gcd); + if(d.Equals(BIG_ONE)) + return Num.from(n); + return new RatioNum((IntegerNum) Num.from(d.signum() < 0 ? n.negate() : n), + (IntegerNum) Num.from(d.signum() < 0 ? d.negate() : d)); + } + +static public Boolean equiv(Object x, Object y) + { + return Num.from(x).equiv(Num.from(y)); + } + +abstract public Boolean equiv(Num rhs); + +abstract public Boolean equivTo(int x); + +abstract public Boolean equivTo(BigInteger x); + +abstract public Boolean equivTo(RatioNum x); + +static public Boolean lt(Object x, Object y) + { + return Num.from(x).lt(Num.from(y)); + } + +static public Boolean lte(Object x, Object y) + { + Num lx = Num.from(x); + Num ly = Num.from(y); + return lx.lt(ly) || lx.equiv(ly); + } + +static public Boolean gt(Object x, Object y) + { + return Num.from(y).lt(Num.from(x)); + } + +static public Boolean gte(Object x, Object y) + { + Num lx = Num.from(x); + Num ly = Num.from(y); + return ly.lt(lx) || lx.equiv(ly); + } + +abstract public Boolean lt(Num rhs); + +abstract public Boolean gt(int x); + +abstract public Boolean gt(BigInteger x); + +abstract public Boolean gt(RatioNum x); + +static public Num negate(Object x) + { + return Num.from(x).negate(); + } + +abstract public Num negate(); + +abstract public Boolean minusp(); + +abstract public Boolean plusp(); + +abstract public Num oneMinus(); + +abstract public Num onePlus(); + +public int CompareTo(Object obj) + { + Num other = Num.from(obj); + if(this.equiv(other)) + return 0; + else if(this.lt(other)) + return -1; + else + return 1; + } +} +} diff --git a/src/cli/runtime/RT.cs b/src/cli/runtime/RT.cs new file mode 100644 index 00000000..777c1299 --- /dev/null +++ b/src/cli/runtime/RT.cs @@ -0,0 +1,212 @@ +/** + * 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:28:27 PM */ + +using System;
+ +namespace org.clojure.runtime
+{ + +public class RT
+{ + + static Object TRUE = true; + static public Object eq(Object arg1, Object arg2) { + return (arg1 == arg2)?TRUE:null; + } + + static public Object eql(Object arg1, Object arg2) { + if(arg1 == arg2) + return TRUE; + if(arg1 == null || arg2 == null) + return null; + if(arg1 is Num + && arg1.GetType() == arg2.GetType() + && arg1.Equals(arg2)) + return TRUE; + if(arg1 is Char + && arg2 is Char + && arg1.Equals(arg2)) + return TRUE; + return null; + } + + static public Object equal(Object arg1, Object arg2) { + if(arg1 == null) + return arg2 == null ? TRUE : null; + else if(arg2 == null) + return null; + return (eql(arg1,arg2) != null + || (arg1 is Cons + && arg2 is Cons + && equal(((Cons)arg1).first,((Cons)arg2).first)!=null + && equal(((Cons)arg1).rest,((Cons)arg2).rest)!=null)) + ?TRUE:null; + } + +static public Cons cons(Object x, Cons y) + { + return new Cons(x, y); + } + +static public Cons list() + { + return null; + } + +static public Cons list(Object arg1) + { + return cons(arg1, null); + } + +static public Cons list(Object arg1, Object arg2) + { + return listStar(arg1, arg2, null); + } + +static public Cons list(Object arg1, Object arg2, Object arg3) + { + return listStar(arg1, arg2, arg3, null); + } + +static public Cons list(Object arg1, Object arg2, Object arg3, Object arg4) + { + return listStar(arg1, arg2, arg3, arg4, null); + } + +static public Cons list(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) + { + return listStar(arg1, arg2, arg3, arg4, arg5, null); + } + +static public Cons listStar(Object arg1, Cons rest) + { + return cons(arg1, rest); + } + +static public Cons listStar(Object arg1, Object arg2, Cons rest) + { + return cons(arg1, cons(arg2, rest)); + } + +static public Cons listStar(Object arg1, Object arg2, Object arg3, Cons rest) + { + return cons(arg1, cons(arg2, cons(arg3, rest))); + } + +static public Cons listStar(Object arg1, Object arg2, Object arg3, Object arg4, Cons rest) + { + return cons(arg1, cons(arg2, cons(arg3, cons(arg4, rest)))); + } + +static public Cons listStar(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Cons rest) + { + return cons(arg1, cons(arg2, cons(arg3, cons(arg4, cons(arg5, rest))))); + } + +static public int length(Cons list) + { + int i = 0; + for(Cons c = list; c != null; c = c.rest) + { + i++; + } + return i; + } + +static public int boundedLength(Cons list, int limit) + { + int i = 0; + for(Cons c = list; c != null && i <= limit; c = c.rest) + { + i++; + } + return i; + } + +static public Object setValues(ThreadLocalData tld, Object arg1) + { + if(tld == null) + tld = ThreadLocalData.get(); + tld.mvCount = 1; + tld.mvArray[0] = arg1; + return arg1; + } + +static public Object setValues(ThreadLocalData tld, Object arg1, Object arg2) + { + if(tld == null) + tld = ThreadLocalData.get(); + tld.mvCount = 2; + tld.mvArray[0] = arg1; + tld.mvArray[1] = arg2; + return arg1; + } + +static public Object setValues(ThreadLocalData tld, Object arg1, Object arg2, Object arg3) + { + if(tld == null) + tld = ThreadLocalData.get(); + tld.mvCount = 3; + tld.mvArray[0] = arg1; + tld.mvArray[1] = arg2; + tld.mvArray[2] = arg3; + return arg1; + } + +static public Object setValues(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4) + { + if(tld == null) + tld = ThreadLocalData.get(); + tld.mvCount = 4; + tld.mvArray[0] = arg1; + tld.mvArray[1] = arg2; + tld.mvArray[2] = arg3; + tld.mvArray[3] = arg4; + return arg1; + } + +static public Object setValues(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4, + Object arg5) + { + if(tld == null) + tld = ThreadLocalData.get(); + tld.mvCount = 5; + tld.mvArray[0] = arg1; + tld.mvArray[1] = arg2; + tld.mvArray[2] = arg3; + tld.mvArray[3] = arg4; + tld.mvArray[4] = arg5; + return arg1; + } + +static public Object setValues(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4, + Object arg5, Cons args) /*throws Exception*/ + { + if(tld == null) + tld = ThreadLocalData.get(); + tld.mvCount = 5; + tld.mvArray[0] = arg1; + tld.mvArray[1] = arg2; + tld.mvArray[2] = arg3; + tld.mvArray[3] = arg4; + tld.mvArray[4] = arg5; + for(int i = 5; args != null && i < ThreadLocalData.MULTIPLE_VALUES_LIMIT; i++, args = args.rest) + { + tld.mvArray[i] = args.first; + } + if(args != null) + throw new ArgumentException("Too many arguments to values (> ThreadLocalData.MULTIPLE_VALUES_LIMIT)"); + return arg1; + } + +} +}
\ No newline at end of file diff --git a/src/cli/runtime/RatioNum.cs b/src/cli/runtime/RatioNum.cs new file mode 100644 index 00000000..945a233f --- /dev/null +++ b/src/cli/runtime/RatioNum.cs @@ -0,0 +1,229 @@ +/** + * 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:14:44 AM */ + +using System;
+using java.math;
+ +namespace org.clojure.runtime
+{ + +public class RatioNum : RationalNum{ +override public Boolean Equals(Object arg0) + { + return arg0 != null + && arg0 is RatioNum + && ((RatioNum) arg0).numerator.Equals(numerator) + && ((RatioNum) arg0).denominator.Equals(denominator); + } + +override public int GetHashCode() + { + return numerator.GetHashCode() ^ denominator.GetHashCode(); + } + +override public String ToString() + { + return numerator.ToString() + "/" + denominator.ToString(); + } + +public IntegerNum numerator; +public IntegerNum denominator; + +public RatioNum(IntegerNum n, IntegerNum d) + { + this.numerator = n; + this.denominator = d; + } + +override public double doubleValue() + { + return numerator.doubleValue() / denominator.doubleValue(); + } + +override public float floatValue() + { + return (float) doubleValue(); + } + +override public int intValue() + { + return (int) doubleValue(); + } + +override public long longValue() + { + return (long) doubleValue(); + } + +override public Boolean equiv(Num rhs) + { + return rhs.equivTo(this); + } + +override public Boolean equivTo(BigInteger x) + { + return false; + } + +override public Boolean equivTo(int x) + { + return false; + } + +override public Boolean equivTo(RatioNum x) + { + return numerator.equiv(x.numerator) && denominator.equiv(x.denominator); + } + +override public Boolean lt(Num rhs) + { + return rhs.gt(this); + } + +override public Boolean gt(BigInteger x) + { + return denominator.multiply(x).lt(numerator); + } + +override public Boolean gt(int x) + { + return denominator.multiply(x).lt(numerator); + } + +override public Boolean gt(RatioNum x) + { + return x.numerator.multiplyBy(denominator).lt(numerator.multiplyBy(x.denominator)); + } + +override public Num add(Num rhs) + { + return rhs.addTo(this); + } + +override public Num addTo(BigInteger x) + { + return Num.divide(numerator.add(denominator.multiply(x)), denominator); + } + +override public Num addTo(int x) + { + return Num.divide(numerator.add(denominator.multiply(x)), denominator); + } + +override public Num addTo(RatioNum x) + { + return Num.divide(numerator.multiplyBy(x.denominator) + .add(x.numerator.multiplyBy(denominator)) + , denominator.multiplyBy(x.denominator)); + } + +override public Num subtractFrom(Num x) + { + return x.add(this.multiply(-1)); + } + +override public Num multiplyBy(Num rhs) + { + return rhs.multiply(this); + } + +override public Num multiply(BigInteger x) + { + return Num.divide(numerator.multiply(x), denominator); + } + +override public Num multiply(int x) + { + return Num.divide(numerator.multiply(x), denominator); + } + +override public Num multiply(RatioNum x) + { + return Num.divide(numerator.multiplyBy(x.numerator) + , denominator.multiplyBy(x.denominator)); + } + +override public Num divideBy(Num rhs) + { + return rhs.divide(this); + } + +override public Num divide(BigInteger n) + { + return Num.divide(denominator.multiply(n), numerator); + } + +override public Num divide(int n) + { + return Num.divide(denominator.multiply(n), numerator); + } + +override public Num divide(RatioNum n) + { + return Num.divide(denominator.multiplyBy(n.numerator) + , numerator.multiplyBy(n.denominator)); + } + + +override public Object truncateDivide(ThreadLocalData tld, Num num) + { + return num.truncateBy(tld, this); + } + +override public Object truncateBy(ThreadLocalData tld, int div) + { + Num q = (Num) Num.truncate(tld, numerator, denominator.multiply(div)); + return RT.setValues(tld, q, q.multiply(div).subtractFrom(this)); + } + +override public Object truncateBy(ThreadLocalData tld, BigInteger div) + { + Num q = (Num) Num.truncate(tld, numerator, denominator.multiply(div)); + return RT.setValues(tld, q, q.multiply(div).subtractFrom(this)); + } + +override public Object truncateBy(ThreadLocalData tld, RatioNum div) + { + Num q = (Num) Num.truncate(tld, numerator.multiplyBy(div.denominator), + denominator.multiplyBy(div.numerator)); + return RT.setValues(tld, q, q.multiplyBy(div).subtractFrom(this)); + } + + +override public Num negate() + { + return Num.divide(numerator.negate(), denominator); + } + +override public Boolean minusp() + { + return numerator.minusp(); + } + +override public Boolean plusp() + { + return numerator.plusp(); + } + +override public Num oneMinus() + { + return addTo(-1); + } + +override public Num onePlus() + { + return addTo(1); + } + +} +} + diff --git a/src/cli/runtime/RationalNum.cs b/src/cli/runtime/RationalNum.cs new file mode 100644 index 00000000..0dc810ae --- /dev/null +++ b/src/cli/runtime/RationalNum.cs @@ -0,0 +1,21 @@ +/** + * 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:12:30 AM */ + +using System;
+ +namespace org.clojure.runtime
+{ + +public abstract class RationalNum : RealNum { + +} +} diff --git a/src/cli/runtime/RealNum.cs b/src/cli/runtime/RealNum.cs new file mode 100644 index 00000000..2172199a --- /dev/null +++ b/src/cli/runtime/RealNum.cs @@ -0,0 +1,21 @@ +/** + * 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:00 AM */ + +using System;
+ +namespace org.clojure.runtime
+{ + +public abstract class RealNum : Num { + +} +}
\ No newline at end of file diff --git a/src/cli/runtime/RestFn0.cs b/src/cli/runtime/RestFn0.cs new file mode 100644 index 00000000..fbd83e46 --- /dev/null +++ b/src/cli/runtime/RestFn0.cs @@ -0,0 +1,65 @@ +/** + * 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 7:34:25 PM */ + +using System;
+
+namespace org.clojure.runtime
+{ + +public abstract class RestFn0 : AFn
+ { + +protected abstract Object doInvoke(ThreadLocalData tld, Cons rest) /*throws Exception*/; + +override public Object applyTo(ThreadLocalData tld, Cons arglist) /*throws Exception*/ + { + return doInvoke(tld, arglist); + } + +override public Object invoke(ThreadLocalData tld) /*throws Exception*/ + { + return doInvoke(tld, null); + } + +override public Object invoke(ThreadLocalData tld, Object arg1) /*throws Exception*/ + { + return doInvoke(tld, RT.list(arg1)); + } + +override public Object invoke(ThreadLocalData tld, Object arg1, Object arg2) /*throws Exception*/ + { + return doInvoke(tld, RT.list(arg1, arg2)); + } + +override public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3) /*throws Exception*/ + { + return doInvoke(tld, RT.list(arg1, arg2, arg3)); + } + +override public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4) /*throws Exception*/ + { + return doInvoke(tld, RT.list(arg1, arg2, arg3, arg4)); + } + +override public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) + /*throws Exception*/ + { + return doInvoke(tld, RT.list(arg1, arg2, arg3, arg4, arg5)); + } + +override public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Cons args) + /*throws Exception*/ + { + return doInvoke(tld, RT.listStar(arg1, arg2, arg3, arg4, arg5, args)); + } +} +}
\ No newline at end of file diff --git a/src/cli/runtime/RestFn1.cs b/src/cli/runtime/RestFn1.cs new file mode 100644 index 00000000..f59fa0d4 --- /dev/null +++ b/src/cli/runtime/RestFn1.cs @@ -0,0 +1,63 @@ +/** + * 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:00:28 PM */ + +using System;
+
+namespace org.clojure.runtime
+{ + +public abstract class RestFn1 : AFn{ + +protected abstract Object doInvoke(ThreadLocalData tld, Object arg1, Cons rest) /*throws Exception*/; + +override public Object applyTo(ThreadLocalData tld, Cons arglist) /*throws Exception*/ + { + if(arglist == null) + throwArity(); + return doInvoke(tld, arglist.first + , arglist.rest); + } + +override public Object invoke(ThreadLocalData tld, Object arg1) /*throws Exception*/ + { + return doInvoke(tld, arg1, null); + } + +override public Object invoke(ThreadLocalData tld, Object arg1, Object arg2) /*throws Exception*/ + { + return doInvoke(tld, arg1, RT.list(arg2)); + } + +override public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3) /*throws Exception*/ + { + return doInvoke(tld, arg1, RT.list(arg2, arg3)); + } + +override public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4) /*throws Exception*/ + { + return doInvoke(tld, arg1, RT.list(arg2, arg3, arg4)); + } + +override public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) + /*throws Exception*/ + { + return doInvoke(tld, arg1, RT.list(arg2, arg3, arg4, arg5)); + } + +override public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Cons args) + /*throws Exception*/ + { + return doInvoke(tld, arg1, RT.listStar(arg2, arg3, arg4, arg5, args)); + } +} + +}
\ No newline at end of file diff --git a/src/cli/runtime/RestFn2.cs b/src/cli/runtime/RestFn2.cs new file mode 100644 index 00000000..c0cdfe55 --- /dev/null +++ b/src/cli/runtime/RestFn2.cs @@ -0,0 +1,59 @@ +/** + * 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:05:10 PM */ + +using System;
+
+namespace org.clojure.runtime
+{ + +public abstract class RestFn2 : AFn{ + +protected abstract Object doInvoke(ThreadLocalData tld, Object arg1, Object arg2, Cons rest) /*throws Exception*/; + +override public Object applyTo(ThreadLocalData tld, Cons arglist) /*throws Exception*/ + { + if(RT.boundedLength(arglist, 2) < 2) + throwArity(); + return doInvoke(tld, arglist.first + , (arglist = arglist.rest).first + , arglist.rest); + + } + +override public Object invoke(ThreadLocalData tld, Object arg1, Object arg2) /*throws Exception*/ + { + return doInvoke(tld, arg1, arg2, null); + } + +override public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3) /*throws Exception*/ + { + return doInvoke(tld, arg1, arg2, RT.list(arg3)); + } + +override public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4) /*throws Exception*/ + { + return doInvoke(tld, arg1, arg2, RT.list(arg3, arg4)); + } + +override public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) + /*throws Exception*/ + { + return doInvoke(tld, arg1, arg2, RT.list(arg3, arg4, arg5)); + } + +override public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Cons args) + /*throws Exception*/ + { + return doInvoke(tld, arg1, arg2, RT.listStar(arg3, arg4, arg5, args)); + } +} +} diff --git a/src/cli/runtime/RestFn3.cs b/src/cli/runtime/RestFn3.cs new file mode 100644 index 00000000..689ee565 --- /dev/null +++ b/src/cli/runtime/RestFn3.cs @@ -0,0 +1,56 @@ +/** + * 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:19:54 PM */ + +using System;
+
+namespace org.clojure.runtime
+{ + +public abstract class RestFn3 : AFn{ + +protected abstract Object doInvoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Cons rest) /*throws Exception*/; + +override public Object applyTo(ThreadLocalData tld, Cons arglist) /*throws Exception*/ + { + if(RT.boundedLength(arglist, 3) < 3) + throwArity(); + return doInvoke(tld, arglist.first + , (arglist = arglist.rest).first + , (arglist = arglist.rest).first + , arglist.rest); + + } + + +override public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3) /*throws Exception*/ + { + return doInvoke(tld, arg1, arg2, arg3,null); + } + +override public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4) /*throws Exception*/ + { + return doInvoke(tld, arg1, arg2, arg3, RT.list(arg4)); + } + +override public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) + /*throws Exception*/ + { + return doInvoke(tld, arg1, arg2, arg3, RT.list(arg4, arg5)); + } + +override public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Cons args) + /*throws Exception*/ + { + return doInvoke(tld, arg1, arg2, arg3, RT.listStar(arg4, arg5, args)); + } +} +}
\ No newline at end of file diff --git a/src/cli/runtime/RestFn4.cs b/src/cli/runtime/RestFn4.cs new file mode 100644 index 00000000..9ab6aa93 --- /dev/null +++ b/src/cli/runtime/RestFn4.cs @@ -0,0 +1,53 @@ +/** + * 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:21:51 PM */ + +using System;
+
+namespace org.clojure.runtime
+{ + +public abstract class RestFn4 : AFn{ + +protected abstract Object doInvoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4, Cons rest) + /*throws Exception*/; + +override public Object applyTo(ThreadLocalData tld, Cons arglist) /*throws Exception*/ + { + if(RT.boundedLength(arglist, 4) < 4) + throwArity(); + return doInvoke(tld, arglist.first + , (arglist = arglist.rest).first + , (arglist = arglist.rest).first + , (arglist = arglist.rest).first + , arglist.rest); + + } + +override public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4) /*throws Exception*/ + { + return doInvoke(tld, arg1, arg2, arg3, arg4, null); + } + +override public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) + /*throws Exception*/ + { + return doInvoke(tld, arg1, arg2, arg3, arg4, RT.list(arg5)); + } + +override public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Cons args) + /*throws Exception*/ + { + return doInvoke(tld, arg1, arg2, arg3, arg4, RT.listStar(arg5, args)); + } +} +} + diff --git a/src/cli/runtime/RestFn5.cs b/src/cli/runtime/RestFn5.cs new file mode 100644 index 00000000..b50aeade --- /dev/null +++ b/src/cli/runtime/RestFn5.cs @@ -0,0 +1,49 @@ +/** + * 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:24:31 PM */ + +using System;
+
+namespace org.clojure.runtime
+{ + +public abstract class RestFn5 : AFn{ + +protected abstract Object doInvoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, + Cons rest) + /*throws Exception*/; + +override public Object applyTo(ThreadLocalData tld, Cons arglist) /*throws Exception*/ + { + if(RT.boundedLength(arglist, 5) < 5) + throwArity(); + return doInvoke(tld, arglist.first + , (arglist = arglist.rest).first + , (arglist = arglist.rest).first + , (arglist = arglist.rest).first + , (arglist = arglist.rest).first + , arglist.rest); + + } + +override public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) + /*throws Exception*/ + { + return doInvoke(tld, arg1, arg2, arg3, arg4, arg5, null); + } + +override public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Cons args) + /*throws Exception*/ + { + return doInvoke(tld, arg1, arg2, arg3, arg4, arg5, args); + } +} +} diff --git a/src/cli/runtime/Symbol.cs b/src/cli/runtime/Symbol.cs new file mode 100644 index 00000000..6994114b --- /dev/null +++ b/src/cli/runtime/Symbol.cs @@ -0,0 +1,96 @@ +/** + * 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:42:47 AM */ + +using System;
+ +namespace org.clojure.runtime
+{ +public class Symbol : AFn{ + +public static Object UNBOUND = new Object(); + +public String name; //const is not equivalent to Java final with init elsewhere +public Namespace ns; +public Object val = UNBOUND; +public IFn fn; //todo, bind to throw stub? + +public String toString() + { + if(ns == Namespace.globalNS) + return name; + if(ns == null) + return "#:" + name; + return ns.name + ":" + name; + } + +/** + * Used by Namespace.intern() + * @param name + * @param ns + */ +internal Symbol(String name, Namespace ns) + { + this.ns = ns; + this.name = name; + } + +virtual public Object getValue(ThreadLocalData tld) + { + Cons binding = tld.getDynamicBinding(this); + if(binding != null) + return binding.first; + if(val == UNBOUND) + throw new InvalidOperationException(name + " is unbound."); + return val; + } + +virtual public Object setValue(ThreadLocalData tld, Object val) + { + Cons binding = tld.getDynamicBinding(this); + if(binding != null) + return binding.first = val; + //allow global set to create binding like this? + if(val is IFn) + this.fn = (IFn) val; + else + this.fn = null; //todo, bind to throw stub? + return this.val = val; + } + +/** + * Symbol implements IFn for attr access + * This single arg version is the getter + * @param tld + * @param obj - must be AMap + * @return the value of the attr or nil if not found + * @throws Exception + */ +override public Object invoke(ThreadLocalData tld, Object obj) /*throws Exception*/ + { + return ((AMap)obj).get(this); + } + +/** + * Symbol implements IFn for attr access + * This two arg version is the setter + * @param tld + * @param obj - must be AMap + * @param val + * @return val + * @throws Exception + */ +override public Object invoke(ThreadLocalData tld, Object obj, Object val) /*throws Exception*/ + { + return ((AMap)obj).put(this,val); + } +} +} diff --git a/src/cli/runtime/ThreadLocalData.cs b/src/cli/runtime/ThreadLocalData.cs new file mode 100644 index 00000000..0f41ecf8 --- /dev/null +++ b/src/cli/runtime/ThreadLocalData.cs @@ -0,0 +1,86 @@ +/** + * 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:45:22 AM */ + +using System;
+using System.Collections.Specialized;
+
+namespace org.clojure.runtime
+{ +public class ThreadLocalData{ + +public const int MULTIPLE_VALUES_LIMIT = 20; +public int mvCount = 0; +public Object[] mvArray = new Object[MULTIPLE_VALUES_LIMIT]; + +HybridDictionary dynamicBindings = new HybridDictionary(); + +public Cons getDynamicBinding(Symbol sym) + { + return (Cons) dynamicBindings[sym]; + } + +public Cons pushDynamicBinding(Symbol sym, Object val) + { + Cons ret = new Cons(val, getDynamicBinding(sym)); + dynamicBindings[sym] = ret; + return ret; + } + + +public Cons popDynamicBinding(Symbol sym) + { + Cons ret = (Cons) getDynamicBinding(sym).rest; + dynamicBindings[sym] = ret; + return ret; + } + +public ThreadLocalData(HybridDictionary dynamicBindings) + { + this.mvCount = 0; + this.mvArray = new Object[MULTIPLE_VALUES_LIMIT]; + this.dynamicBindings = dynamicBindings; + } + +public ThreadLocalData(): + this(new HybridDictionary()) + { + } + +public static ThreadLocalData get() + { + if(tld == null) + tld = new ThreadLocalData(); + return tld; + } + +/* +note this is not the same semantics as InheritableThreadLocal - aargh +might need to make Java side non-inheritable +*/ +[ThreadStatic] + static ThreadLocalData tld; + /* was this in Java +static InheritableThreadLocal tld = new InheritableThreadLocal(){ + protected Object childValue(Object object) + { + return new ThreadLocalData((HybridDictionary) ((ThreadLocalData) object).dynamicBindings.clone()); + } + + protected Object initialValue() + { + return new ThreadLocalData(); + } +}; +*/ + +} +} |