diff options
author | Rich Hickey <richhickey@gmail.com> | 2006-08-05 15:06:30 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2006-08-05 15:06:30 +0000 |
commit | cfbe0fe8a1adaf7b16f37d92545c89230256221d (patch) | |
tree | 03e34f1e6cf73f09b902b3444bd068e282f0a86b | |
parent | a8ba1dbdec6976596e005b7ffe2d06355280a10f (diff) |
made arrays associative, added MapEntry
-rw-r--r-- | src/cli/runtime/APersistentMap.cs | 67 | ||||
-rw-r--r-- | src/cli/runtime/AnArray.cs | 45 | ||||
-rw-r--r-- | src/cli/runtime/IArray.cs | 2 | ||||
-rw-r--r-- | src/cli/runtime/IPersistentMap.cs | 1 | ||||
-rw-r--r-- | src/cli/runtime/MapEntry.cs | 130 | ||||
-rw-r--r-- | src/cli/runtime/RT.cs | 4 | ||||
-rw-r--r-- | src/jvm/clojure/lang/APersistentMap.java | 29 | ||||
-rw-r--r-- | src/jvm/clojure/lang/AnArray.java | 37 | ||||
-rw-r--r-- | src/jvm/clojure/lang/IArray.java | 4 | ||||
-rw-r--r-- | src/jvm/clojure/lang/IPersistentMap.java | 2 | ||||
-rw-r--r-- | src/jvm/clojure/lang/MapEntry.java | 116 | ||||
-rw-r--r-- | src/jvm/clojure/lang/RT.java | 5 |
12 files changed, 436 insertions, 6 deletions
diff --git a/src/cli/runtime/APersistentMap.cs b/src/cli/runtime/APersistentMap.cs new file mode 100644 index 00000000..9a9170d5 --- /dev/null +++ b/src/cli/runtime/APersistentMap.cs @@ -0,0 +1,67 @@ +/**
+ * 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;
+using System.Threading;
+using System.Collections;
+
+namespace clojure.lang
+{
+public abstract class APersistentMap : Obj, IPersistentMap{
+
+ public override Obj withMeta(IPersistentMap meta)
+ {
+ if(_meta == meta)
+ return this;
+ Obj ret = (Obj)MemberwiseClone();
+ ret._meta = meta;
+ return ret;
+ }
+
+
+ #region IPersistentMap Members
+
+ abstract public IPersistentMap add(object key, object val);
+
+
+ abstract public IPersistentMap remove(object key);
+
+
+
+ #endregion
+
+ #region Associative Members
+
+ abstract public bool contains(object key);
+
+ abstract public IMapEntry find(object key);
+
+ abstract public object get(object key);
+
+ abstract public IPersistentMap assoc(object key, object val);
+
+ #endregion
+
+ #region IEnumerable Members
+
+ abstract public IEnumerator GetEnumerator();
+
+ #endregion
+
+ #region IPersistentCollection Members
+
+ abstract public int count();
+
+ abstract public ISeq seq();
+
+ #endregion
+ }
+
+}
diff --git a/src/cli/runtime/AnArray.cs b/src/cli/runtime/AnArray.cs index 6bdb9d29..76640631 100644 --- a/src/cli/runtime/AnArray.cs +++ b/src/cli/runtime/AnArray.cs @@ -17,6 +17,8 @@ public abstract class AnArray : Obj, IArray { public override Obj withMeta(IPersistentMap meta)
{
+ if(_meta == meta)
+ return this;
Obj ret = (Obj)MemberwiseClone();
ret._meta = meta;
return ret;
@@ -40,6 +42,49 @@ public abstract class AnArray : Obj, IArray { abstract public ISeq seq();
#endregion
+
+public bool contains(Object key) {
+ try{
+ int i = Convert.ToInt32(key);
+ return i >= 0 && i < count();
+ }
+ catch(Exception)
+ {
+ return false;
+ }
+}
+
+public IMapEntry find(Object key) {
+ try
+ {
+ int i = Convert.ToInt32(key);
+ if(i >= 0 && i < count())
+ return new MapEntry(key,nth(i));
+ }
+ catch(Exception)
+ {
+ }
+ return null;
+}
+
+public IPersistentMap assoc(Object key, Object val) {
+ int i = Convert.ToInt32(key);
+ return (IPersistentMap) assocN(i,val);
+}
+
+public Object get(Object key) {
+ try
+ {
+ int i = Convert.ToInt32(key);
+ if(i >= 0 && i < count())
+ return nth(i);
+ }
+ catch (Exception)
+ {
+ }
+ return null;
}
}
+
+}
diff --git a/src/cli/runtime/IArray.cs b/src/cli/runtime/IArray.cs index 7171740b..736d1679 100644 --- a/src/cli/runtime/IArray.cs +++ b/src/cli/runtime/IArray.cs @@ -13,7 +13,7 @@ using System; namespace clojure.lang
{ -public interface IArray : IPersistentCollection {
+public interface IArray : IPersistentCollection, Associative {
int length();
Object nth(int i);
diff --git a/src/cli/runtime/IPersistentMap.cs b/src/cli/runtime/IPersistentMap.cs index df91a08a..d9d3991a 100644 --- a/src/cli/runtime/IPersistentMap.cs +++ b/src/cli/runtime/IPersistentMap.cs @@ -21,7 +21,6 @@ IPersistentMap add(Object key, Object val); IPersistentMap remove(Object key);
-int capacity();
}
}
diff --git a/src/cli/runtime/MapEntry.cs b/src/cli/runtime/MapEntry.cs new file mode 100644 index 00000000..0e86f56a --- /dev/null +++ b/src/cli/runtime/MapEntry.cs @@ -0,0 +1,130 @@ +/**
+ * 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;
+using System.Collections;
+
+namespace clojure.lang
+{
+public class MapEntry : APersistentMap , IMapEntry{
+readonly Object _key;
+readonly Object _val;
+
+public MapEntry(Object key, Object val) {
+ this._key = key;
+ this._val = val;
+}
+
+public Object key() {
+ return _key;
+}
+
+public Object val() {
+ return _val;
+}
+
+override public bool contains(Object key) {
+ return RT.equal(_key, key);
+}
+
+override public IMapEntry find(Object key) {
+ return RT.equal(_key, key)?this:null;
+}
+
+override public IPersistentMap assoc(Object key, Object val) {
+ if(RT.equal(_key, key))
+ {
+ if(_val == val)
+ return this;
+ return (MapEntry) new MapEntry(key, val).withMeta(_meta);
+ }
+ return (IPersistentMap) new PersistentArrayMap(_key,_val,key,val).withMeta(_meta);
+}
+
+override public Object get(Object key) {
+ return RT.equal(_key, key)?_val:null;
+}
+
+override public IPersistentMap add(Object key, Object val) {
+ if(RT.equal(_key, key))
+ throw new Exception("Key already present");
+ return assoc(key, val);
+}
+
+override public IPersistentMap remove(Object key) {
+ if(RT.equal(_key, key))
+ return (IPersistentMap) PersistentArrayMap.EMPTY.withMeta(_meta);
+ return this;
+}
+
+override public int count() {
+ return 1;
+}
+
+override public IEnumerator GetEnumerator() {
+ return new Iter(this);
+}
+
+class Iter : IEnumerator{
+ MapEntry e;
+ bool first = true;
+
+ public Iter(MapEntry e) {
+ this.e = e;
+ }
+
+#region IEnumerator Members
+
+public object Current
+ {
+ get {return e;}
+ }
+
+public bool MoveNext()
+ {
+ if(first)
+ {
+ first = false;
+ return true;
+ }
+ return false;
+ }
+
+public void Reset()
+ {
+ throw new Exception("The method or operation is not implemented.");
+ }
+
+#endregion
+ }
+
+
+override public ISeq seq() {
+ return new Seq(this);
+}
+
+class Seq : ISeq{
+ MapEntry e;
+
+ public Seq(MapEntry e) {
+ this.e = e;
+ }
+
+ public Object first() {
+ return e;
+ }
+
+ public ISeq rest() {
+ return null;
+ }
+}
+}
+
+}
diff --git a/src/cli/runtime/RT.cs b/src/cli/runtime/RT.cs index ed6bfffe..75d581f2 100644 --- a/src/cli/runtime/RT.cs +++ b/src/cli/runtime/RT.cs @@ -32,6 +32,10 @@ public class RT chars[i] = (char)i;
}
+static public bool equal(Object k1,Object k2){
+ return k1 == k2 ||
+ (k1 != null && k1.Equals(k2));
+}
static public Object eq(Object arg1, Object arg2) {
return (arg1 == arg2)?T:null;
}
diff --git a/src/jvm/clojure/lang/APersistentMap.java b/src/jvm/clojure/lang/APersistentMap.java new file mode 100644 index 00000000..3eb9e5ef --- /dev/null +++ b/src/jvm/clojure/lang/APersistentMap.java @@ -0,0 +1,29 @@ +/**
+ * 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 abstract class APersistentMap extends Obj implements IPersistentMap, Cloneable{
+
+public Obj withMeta(IPersistentMap meta) {
+ if(_meta == meta)
+ return this;
+ try{
+ Obj ret = (Obj) clone();
+ ret._meta = meta;
+ return ret;
+ }
+ catch(CloneNotSupportedException ignore)
+ {
+ return null;
+ }
+}
+
+}
diff --git a/src/jvm/clojure/lang/AnArray.java b/src/jvm/clojure/lang/AnArray.java index 0afe7c79..93ead181 100644 --- a/src/jvm/clojure/lang/AnArray.java +++ b/src/jvm/clojure/lang/AnArray.java @@ -13,6 +13,8 @@ package clojure.lang; public abstract class AnArray extends Obj implements IArray, Cloneable {
public Obj withMeta(IPersistentMap meta) {
+ if(_meta == meta)
+ return this;
try{
Obj ret = (Obj) clone();
ret._meta = meta;
@@ -24,4 +26,39 @@ public Obj withMeta(IPersistentMap meta) { }
}
+public boolean contains(Object key) {
+ if(!(key instanceof Number))
+ return false;
+ int i = ((Number)key).intValue();
+ return i >= 0 && i < count();
+}
+
+public IMapEntry find(Object key) {
+ if(key instanceof Number)
+ {
+ int i = ((Number)key).intValue();
+ if(i >= 0 && i < count())
+ return new MapEntry(key,nth(i));
+ }
+ return null;
+}
+
+public IPersistentMap assoc(Object key, Object val) {
+ if(key instanceof Number)
+ {
+ int i = ((Number)key).intValue();
+ return (IPersistentMap) assocN(i,val);
+ }
+ throw new IllegalAccessError("Key must be integer");
+}
+
+public Object get(Object key) {
+ if(key instanceof Number)
+ {
+ int i = ((Number)key).intValue();
+ if(i >= 0 && i < count())
+ return nth(i);
+ }
+ return null;
+}
}
diff --git a/src/jvm/clojure/lang/IArray.java b/src/jvm/clojure/lang/IArray.java index c0bf4838..b2520a4a 100644 --- a/src/jvm/clojure/lang/IArray.java +++ b/src/jvm/clojure/lang/IArray.java @@ -10,10 +10,10 @@ package clojure.lang; * You must not remove this notice, or any other, from this software.
*/
-public interface IArray extends IPersistentCollection {
+public interface IArray extends IPersistentCollection, Associative {
int length();
Object nth(int i);
-IArray assocN(int i,Object val) throws Exception;
+IArray assocN(int i,Object val);
}
diff --git a/src/jvm/clojure/lang/IPersistentMap.java b/src/jvm/clojure/lang/IPersistentMap.java index 21158133..3670817f 100644 --- a/src/jvm/clojure/lang/IPersistentMap.java +++ b/src/jvm/clojure/lang/IPersistentMap.java @@ -17,6 +17,4 @@ public interface IPersistentMap extends Iterable, IPersistentCollection, Associa IPersistentMap add(Object key, Object val) throws Exception;
IPersistentMap remove(Object key);
-
-int capacity();
}
diff --git a/src/jvm/clojure/lang/MapEntry.java b/src/jvm/clojure/lang/MapEntry.java new file mode 100644 index 00000000..4a2f1a29 --- /dev/null +++ b/src/jvm/clojure/lang/MapEntry.java @@ -0,0 +1,116 @@ +/**
+ * 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;
+
+import java.util.Iterator;
+
+public class MapEntry extends APersistentMap implements IMapEntry{
+final Object _key;
+final Object _val;
+
+public MapEntry(Object key, Object val) {
+ this._key = key;
+ this._val = val;
+}
+
+public Object key() {
+ return _key;
+}
+
+public Object val() {
+ return _val;
+}
+
+public boolean contains(Object key) {
+ return RT.equal(_key, key);
+}
+
+public IMapEntry find(Object key) {
+ return RT.equal(_key, key)?this:null;
+}
+
+public IPersistentMap assoc(Object key, Object val) {
+ if(RT.equal(_key, key))
+ {
+ if(_val == val)
+ return this;
+ return (MapEntry) new MapEntry(key, val).withMeta(_meta);
+ }
+ return (IPersistentMap) new PersistentArrayMap(_key,_val,key,val).withMeta(_meta);
+}
+
+public Object get(Object key) {
+ return RT.equal(_key, key)?_val:null;
+}
+
+public IPersistentMap add(Object key, Object val) throws Exception {
+ if(RT.equal(_key, key))
+ throw new Exception("Key already present");
+ return assoc(key, val);
+}
+
+public IPersistentMap remove(Object key) {
+ if(RT.equal(_key, key))
+ return (IPersistentMap) PersistentArrayMap.EMPTY.withMeta(_meta);
+ return this;
+}
+
+public int count() {
+ return 1;
+}
+
+public Iterator iterator() {
+ return new Iter(this);
+}
+
+static class Iter implements Iterator{
+ MapEntry e;
+
+ public Iter(MapEntry e) {
+ this.e = e;
+ }
+
+ public boolean hasNext() {
+ return e != null;
+ }
+
+ public Object next() {
+ Object ret = e;
+ e = null;
+ return ret;
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+}
+
+
+public ISeq seq() throws Exception {
+ return new Seq(this);
+}
+
+static class Seq implements ISeq{
+ MapEntry e;
+
+ public Seq(MapEntry e) {
+ this.e = e;
+ }
+
+ public Object first() {
+ return e;
+ }
+
+ public ISeq rest() {
+ return null;
+ }
+}
+}
diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java index 77aa943f..08daaf15 100644 --- a/src/jvm/clojure/lang/RT.java +++ b/src/jvm/clojure/lang/RT.java @@ -30,6 +30,11 @@ public class RT{ } +static public boolean equal(Object k1,Object k2){ + return k1 == k2 || + (k1 != null && k1.equals(k2)); +} + static public Object eq(Object arg1, Object arg2) { return (arg1 == arg2)?Boolean.TRUE:null; } |