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 /src/cli | |
parent | a8ba1dbdec6976596e005b7ffe2d06355280a10f (diff) |
made arrays associative, added MapEntry
Diffstat (limited to 'src/cli')
-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 |
6 files changed, 247 insertions, 2 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;
}
|