diff options
Diffstat (limited to 'src/jvm')
-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 |
6 files changed, 189 insertions, 4 deletions
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; } |