summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cli/runtime/ArraySeq.cs48
-rw-r--r--src/cli/runtime/IArray.cs24
-rw-r--r--src/cli/runtime/IndexedSeq.cs21
-rw-r--r--src/cli/runtime/PersistentArray.cs77
-rw-r--r--src/cli/runtime/PersistentArrayIdentityMap.cs2
-rw-r--r--src/cli/runtime/PersistentArrayMap.cs2
-rw-r--r--src/cli/runtime/PersistentHashtableMap.cs4
-rw-r--r--src/cli/runtime/RT.cs11
-rw-r--r--src/cli/runtime/Tuple.cs90
-rw-r--r--src/jvm/clojure/lang/ArraySeq.java2
-rw-r--r--src/jvm/clojure/lang/IArray.java19
-rw-r--r--src/jvm/clojure/lang/IndexedSeq.java16
-rw-r--r--src/jvm/clojure/lang/PersistentArray.java68
-rw-r--r--src/jvm/clojure/lang/PersistentArrayIdentityMap.java2
-rw-r--r--src/jvm/clojure/lang/PersistentArrayMap.java2
-rw-r--r--src/jvm/clojure/lang/RT.java11
-rw-r--r--src/jvm/clojure/lang/Tuple.java43
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(){