diff options
-rw-r--r-- | src/cli/runtime/ArraySeq.cs | 48 | ||||
-rw-r--r-- | src/cli/runtime/IArray.cs | 24 | ||||
-rw-r--r-- | src/cli/runtime/IndexedSeq.cs | 21 | ||||
-rw-r--r-- | src/cli/runtime/PersistentArray.cs | 77 | ||||
-rw-r--r-- | src/cli/runtime/PersistentArrayIdentityMap.cs | 2 | ||||
-rw-r--r-- | src/cli/runtime/PersistentArrayMap.cs | 2 | ||||
-rw-r--r-- | src/cli/runtime/PersistentHashtableMap.cs | 4 | ||||
-rw-r--r-- | src/cli/runtime/RT.cs | 11 | ||||
-rw-r--r-- | src/cli/runtime/Tuple.cs | 90 | ||||
-rw-r--r-- | src/jvm/clojure/lang/ArraySeq.java | 2 | ||||
-rw-r--r-- | src/jvm/clojure/lang/IArray.java | 19 | ||||
-rw-r--r-- | src/jvm/clojure/lang/IndexedSeq.java | 16 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentArray.java | 68 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentArrayIdentityMap.java | 2 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentArrayMap.java | 2 | ||||
-rw-r--r-- | src/jvm/clojure/lang/RT.java | 11 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Tuple.java | 43 |
17 files changed, 411 insertions, 31 deletions
diff --git a/src/cli/runtime/ArraySeq.cs b/src/cli/runtime/ArraySeq.cs new file mode 100644 index 00000000..c0e450b4 --- /dev/null +++ b/src/cli/runtime/ArraySeq.cs @@ -0,0 +1,48 @@ +/**
+ * 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 Jun 19, 2006 */
+
+using System;
+ +namespace clojure.lang
+{ +
+public class ArraySeq : IndexedSeq{
+readonly Object[] array;
+readonly int i;
+
+static public ArraySeq create(Object[] array){
+ if(array.Length == 0)
+ return null;
+ return new ArraySeq(array, 0);
+}
+
+ArraySeq(Object[] array, int i){
+ this.array = array;
+ this.i = i;
+}
+
+public Object first() {
+ return array[i];
+}
+
+public ISeq rest() {
+ if(i+1 < array.Length)
+ return new ArraySeq(array, i + 1);
+ return null;
+}
+
+public int index(){
+ return i;
+}
+}
+
+}
diff --git a/src/cli/runtime/IArray.cs b/src/cli/runtime/IArray.cs new file mode 100644 index 00000000..b5bcb4b9 --- /dev/null +++ b/src/cli/runtime/IArray.cs @@ -0,0 +1,24 @@ +/**
+ * 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.
+ */
+
+using System;
+ +namespace clojure.lang
+{ +
+public interface IArray : ISequential {
+int length();
+
+Object get(int i);
+
+IArray set(int i,Object val);
+}
+
+}
diff --git a/src/cli/runtime/IndexedSeq.cs b/src/cli/runtime/IndexedSeq.cs new file mode 100644 index 00000000..49b5a297 --- /dev/null +++ b/src/cli/runtime/IndexedSeq.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.
+ */
+
+using System;
+ +namespace clojure.lang
+{ +
+public interface IndexedSeq : ISeq{
+
+int index();
+}
+
+}
\ No newline at end of file diff --git a/src/cli/runtime/PersistentArray.cs b/src/cli/runtime/PersistentArray.cs index 6167b67e..2c0e2191 100644 --- a/src/cli/runtime/PersistentArray.cs +++ b/src/cli/runtime/PersistentArray.cs @@ -44,7 +44,7 @@ namespace clojure.lang * Java implementation is lock-free
*/
-public class PersistentArray : IEnumerable, ISequential{
+public class PersistentArray : IEnumerable, IArray{
#region IEnumerable Members
@@ -118,7 +118,7 @@ internal class EntryLink : Entry }
}
-internal class Seq : ISeq{
+internal class Seq : IndexedSeq{
readonly PersistentArray p;
readonly int i;
@@ -136,7 +136,16 @@ internal class Seq : ISeq{ return new Seq(p, i + 1);
return null;
}
-}
+
+#region IndexedSeq Members
+
+public int index()
+ {
+ return i;
+ }
+
+#endregion
+ }
internal class ValIter : IEnumerator
{
@@ -176,7 +185,7 @@ public void Reset() internal readonly BitArray history;
public PersistentArray(int size)
- : this(size, null)
+ : this(size, (Object)null)
{
}
@@ -200,7 +209,27 @@ public PersistentArray(int size, Object defaultVal, float loadFactor){ this.history = history;
}
+public PersistentArray(int size, ISeq seq) : this(size){
+ int load = 0;
+ for(int i=0;seq != null && i < size;i++, seq=seq.rest())
+ {
+ master.array[i] = new Entry(0,seq.first());
+ ++load;
+ }
+
+ master.load = load;
+}
+public PersistentArray(IArray init) :this(init.length()) {
+ int load = 0;
+ for(int i=0;i < init.length();i++)
+ {
+ master.array[i] = new Entry(0,init.get(i));
+ ++load;
+ }
+
+ master.load = load;
+}
public int length(){
return master.array.Length;
@@ -254,7 +283,7 @@ Entry getEntry(int i){ return null;
}
-public PersistentArray set(int i,Object val) {
+public IArray set(int i,Object val) {
if(master.load >= master.maxLoad)
return isolate().set(i,val);
lock(master){
@@ -264,6 +293,44 @@ public PersistentArray set(int i,Object val) { }
}
+
+override public bool Equals(Object key){
+ if(this == key) return true;
+ if(key == null || !(key is IArray)) return false;
+
+ IArray a = (IArray) key;
+
+ if(a.length() != length())
+ return false;
+
+ for(int i = 0; i < length(); i++)
+ {
+ if(!equalKey(get(i),a.get(i)))
+ return false;
+ }
+
+ return true;
+}
+
+override public int GetHashCode()
+ {
+ int ret = 0;
+ for (int i = 0; i < length(); i++)
+ {
+ Object o = get(i);
+ if (o != null)
+ ret ^= o.GetHashCode();
+ }
+ return ret;
+ }
+
+private bool equalKey(Object k1, Object k2)
+ {
+ if (k1 == null)
+ return k2 == null;
+ return k1.Equals(k2);
+ }
+
void doSet(int i, Object val){
//must now be called inside lock of master
master.array[i] = Entry.create(rev, val, master.array[i]);
diff --git a/src/cli/runtime/PersistentArrayIdentityMap.cs b/src/cli/runtime/PersistentArrayIdentityMap.cs index 78e3ec04..adef034e 100644 --- a/src/cli/runtime/PersistentArrayIdentityMap.cs +++ b/src/cli/runtime/PersistentArrayIdentityMap.cs @@ -26,7 +26,7 @@ override public IPersistentMap empty() { PersistentArrayIdentityMap() {
}
-public PersistentArrayIdentityMap(Object[] init) :base(init) {
+public PersistentArrayIdentityMap(params Object[] init) :base(init) {
}
internal override bool equalKey(Object k1, Object k2) {
diff --git a/src/cli/runtime/PersistentArrayMap.cs b/src/cli/runtime/PersistentArrayMap.cs index 7d789af5..02e35275 100644 --- a/src/cli/runtime/PersistentArrayMap.cs +++ b/src/cli/runtime/PersistentArrayMap.cs @@ -39,7 +39,7 @@ protected PersistentArrayMap(){ * This ctor captures/aliases the passed array, so do not modify later
* @param init {key1,val1,key2,val2,...}
*/
-public PersistentArrayMap(Object[] init){
+public PersistentArrayMap(params Object[] init){
this.array = init;
}
diff --git a/src/cli/runtime/PersistentHashtableMap.cs b/src/cli/runtime/PersistentHashtableMap.cs index efe95d9e..d0fd4cc0 100644 --- a/src/cli/runtime/PersistentHashtableMap.cs +++ b/src/cli/runtime/PersistentHashtableMap.cs @@ -112,7 +112,7 @@ PersistentArray doPut(int i,Object key,Object val,PersistentArray array){ newEntries = createListMap(key, val);
//newEntries = createArrayMap(new Object[]{key, val});
- return array.set(i, newEntries);
+ return (PersistentArray)array.set(i, newEntries);
}
public IPersistentMap remove(Object key) {
@@ -122,7 +122,7 @@ public IPersistentMap remove(Object key) { {
IPersistentMap newEntries = entries.remove(key);
if (newEntries != entries)
- return create(_count - 1, array.set(i, newEntries));
+ return create(_count - 1, (PersistentArray)array.set(i, newEntries));
}
//not there, no op
return this;
diff --git a/src/cli/runtime/RT.cs b/src/cli/runtime/RT.cs index 36387c55..be8e85cb 100644 --- a/src/cli/runtime/RT.cs +++ b/src/cli/runtime/RT.cs @@ -65,6 +65,17 @@ public class RT // ?T:null;
// }
+static public ISeq seq(Object coll) {
+ if(coll == null || coll is ISeq)
+ return (ISeq) coll;
+ else if(coll is ISequential)
+ return ((ISequential) coll).seq();
+ else if(coll is Object[])
+ return ArraySeq.create((Object[]) coll);
+ else
+ throw new ArgumentException("Don't know how to create ISeq from arg");
+}
+
static public Iter iter(Object coll)
{
if (coll == null || coll is Iter)
diff --git a/src/cli/runtime/Tuple.cs b/src/cli/runtime/Tuple.cs new file mode 100644 index 00000000..1ee8de4f --- /dev/null +++ b/src/cli/runtime/Tuple.cs @@ -0,0 +1,90 @@ +/**
+ * 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 Jun 19, 2006 */
+
+using System;
+ +namespace clojure.lang
+{ +
+public class Tuple : IArray{
+
+readonly Object[] array;
+
+readonly public static Tuple EMPTY = new Tuple();
+
+/**
+ * This ctor captures/aliases the passed array, so do not modify later !
+ * @param init {key1,val1,key2,val2,...}
+ */
+public Tuple(params Object[] init){
+ this.array = init;
+}
+
+public int length() {
+ return array.Length;
+}
+
+public Object get(int i){
+ return array[i];
+}
+
+/**
+ *
+ * @param i
+ * @param val
+ * @return a PersistentArray
+ */
+public IArray set(int i, Object val) {
+ return (new PersistentArray(this)).set(i, val);
+}
+
+override public bool Equals(Object key){
+ if(this == key) return true;
+ if(key == null || !(key is IArray)) return false;
+
+ IArray a = (IArray) key;
+
+ if(a.length() != array.Length)
+ return false;
+
+ for(int i = 0; i < array.Length; i++)
+ {
+ if(!equalKey(array[i],a.get(i)))
+ return false;
+ }
+
+ return true;
+}
+
+override public int GetHashCode(){
+ int ret = 0;
+ for(int i = 0; i < array.Length; i++)
+ {
+ Object o = array[i];
+ if(o != null)
+ ret ^= o.GetHashCode();
+ }
+ return ret;
+}
+
+private bool equalKey(Object k1,Object k2){
+ if(k1 == null)
+ return k2 == null;
+ return k1.Equals(k2);
+}
+
+public ISeq seq() {
+ return ArraySeq.create(array);
+}
+}
+
+}
diff --git a/src/jvm/clojure/lang/ArraySeq.java b/src/jvm/clojure/lang/ArraySeq.java index 01e48529..e01459a4 100644 --- a/src/jvm/clojure/lang/ArraySeq.java +++ b/src/jvm/clojure/lang/ArraySeq.java @@ -12,7 +12,7 @@ package clojure.lang; -public class ArraySeq implements ISeq{ +public class ArraySeq implements IndexedSeq{ final Object[] array; final int i; diff --git a/src/jvm/clojure/lang/IArray.java b/src/jvm/clojure/lang/IArray.java new file mode 100644 index 00000000..f8546c15 --- /dev/null +++ b/src/jvm/clojure/lang/IArray.java @@ -0,0 +1,19 @@ +package clojure.lang;
+
+/**
+ * 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.
+ */
+
+public interface IArray extends ISequential {
+int length();
+
+Object get(int i);
+
+IArray set(int i,Object val) throws Exception;
+}
diff --git a/src/jvm/clojure/lang/IndexedSeq.java b/src/jvm/clojure/lang/IndexedSeq.java new file mode 100644 index 00000000..a4c37641 --- /dev/null +++ b/src/jvm/clojure/lang/IndexedSeq.java @@ -0,0 +1,16 @@ +/**
+ * 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 clojure.lang;
+
+public interface IndexedSeq extends ISeq{
+
+public int index();
+}
diff --git a/src/jvm/clojure/lang/PersistentArray.java b/src/jvm/clojure/lang/PersistentArray.java index 45a91740..4f8c16bf 100644 --- a/src/jvm/clojure/lang/PersistentArray.java +++ b/src/jvm/clojure/lang/PersistentArray.java @@ -46,7 +46,7 @@ import java.util.Random; * I added hybrid most-recent-sequential-range + shared-bitset idea, multi-thread-safety */ -public class PersistentArray implements Iterable, ISequential{ +public class PersistentArray implements Iterable, IArray { public Iterator iterator(){ return new ValIter(this); @@ -109,7 +109,7 @@ static class EntryLink extends Entry{ } } -static class Seq implements ISeq{ +static class Seq implements IndexedSeq{ final PersistentArray p; final int i; @@ -127,6 +127,10 @@ static class Seq implements ISeq{ return new Seq(p, i + 1); return null; } + + public int index() { + return i; + } } static class ValIter implements Iterator{ @@ -157,7 +161,7 @@ final int baseline; final BitSet history; public PersistentArray(int size){ - this(size, null); + this(size, (Object)null); } public PersistentArray(int size, Object defaultVal){ @@ -178,7 +182,29 @@ PersistentArray(Master master,int rev,int baseline, BitSet history){ this.history = history; } +public PersistentArray(int size, ISeq seq) throws Exception { + this(size); + int load = 0; + for(int i=0;seq != null && i < size;i++, seq=seq.rest()) + { + master.array[i] = new Entry(0,seq.first()); + ++load; + } + + master.load = load; +} + +public PersistentArray(IArray init) { + this(init.length()); + int load = 0; + for(int i=0;i < init.length();i++) + { + master.array[i] = new Entry(0,init.get(i)); + ++load; + } + master.load = load; +} final public int length(){ return master.array.length; @@ -254,6 +280,42 @@ final public PersistentArray set(int i,Object val) { } } + +public boolean equals(Object key){ + if(this == key) return true; + if(key == null || !(key instanceof IArray)) return false; + + final IArray a = (IArray) key; + + if(a.length() != length()) + return false; + + for(int i = 0; i < length(); i++) + { + if(!equalKey(get(i),a.get(i))) + return false; + } + + return true; +} + +public int hashCode(){ + int ret = 0; + for(int i = 0; i < length(); i++) + { + Object o = get(i); + if(o != null) + ret ^= o.hashCode(); + } + return ret; +} + +private boolean equalKey(Object k1,Object k2){ + if(k1 == null) + return k2 == null; + return k1.equals(k2); +} + final void doSet(int i, Object val){ // Entry oldEntry, newEntry; // do diff --git a/src/jvm/clojure/lang/PersistentArrayIdentityMap.java b/src/jvm/clojure/lang/PersistentArrayIdentityMap.java index 3bc8c56f..57a1bf59 100644 --- a/src/jvm/clojure/lang/PersistentArrayIdentityMap.java +++ b/src/jvm/clojure/lang/PersistentArrayIdentityMap.java @@ -25,7 +25,7 @@ IPersistentMap empty() { return EMPTY;
}
-public PersistentArrayIdentityMap(Object[] init) {
+public PersistentArrayIdentityMap(Object... init) {
super(init);
}
diff --git a/src/jvm/clojure/lang/PersistentArrayMap.java b/src/jvm/clojure/lang/PersistentArrayMap.java index 920b0bf1..b5c0e39a 100644 --- a/src/jvm/clojure/lang/PersistentArrayMap.java +++ b/src/jvm/clojure/lang/PersistentArrayMap.java @@ -37,7 +37,7 @@ protected PersistentArrayMap(){ * This ctor captures/aliases the passed array, so do not modify later
* @param init {key1,val1,key2,val2,...}
*/
-public PersistentArrayMap(Object[] init){
+public PersistentArrayMap(Object... init){
this.array = init;
}
diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java index 645da926..9347d3a6 100644 --- a/src/jvm/clojure/lang/RT.java +++ b/src/jvm/clojure/lang/RT.java @@ -64,6 +64,17 @@ public class RT{ // ?Boolean.TRUE:null; // } +static public ISeq seq(Object coll) throws Exception { + if(coll == null || coll instanceof ISeq) + return (ISeq) coll; + else if(coll instanceof ISequential) + return ((ISequential) coll).seq(); + else if(coll instanceof Object[]) + return ArraySeq.create((Object[]) coll); + else + throw new IllegalArgumentException("Don't know how to create ISeq from arg"); +} + static public Iter iter(Object coll) { if(coll == null || coll instanceof Iter) diff --git a/src/jvm/clojure/lang/Tuple.java b/src/jvm/clojure/lang/Tuple.java index 2f7c8e97..b105479f 100644 --- a/src/jvm/clojure/lang/Tuple.java +++ b/src/jvm/clojure/lang/Tuple.java @@ -12,15 +12,12 @@ package clojure.lang; -public class Tuple implements ISequential{ +public class Tuple implements IArray{ final Object[] array; final public static Tuple EMPTY = new Tuple(); -static public Tuple create(Object... init){ - return new Tuple(init); -} /** * This ctor captures/aliases the passed array, so do not modify later ! * @param init {key1,val1,key2,val2,...} @@ -29,26 +26,40 @@ public Tuple(Object... init){ this.array = init; } +public int length() { + return array.length; +} + public Object get(int i){ - return array[i]; + return array[i]; +} + +/** + * + * @param i + * @param val + * @return a PersistentArray + */ +public IArray set(int i, Object val) { + return (new PersistentArray(this)).set(i, val); } public boolean equals(Object key){ - if(this == key) return true; - if(key == null || getClass() != key.getClass()) return false; + if(this == key) return true; + if(key == null || !(key instanceof IArray)) return false; - final Tuple tuple = (Tuple) key; + final IArray a = (IArray) key; - if(tuple.array.length != array.length) - return false; + if(a.length() != array.length) + return false; - for(int i = 0; i < array.length; i++) - { - if(!equalKey(array[i],tuple.array[i])) - return false; - } + for(int i = 0; i < array.length; i++) + { + if(!equalKey(array[i],a.get(i))) + return false; + } - return true; + return true; } public int hashCode(){ |