summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2006-07-28 20:50:09 +0000
committerRich Hickey <richhickey@gmail.com>2006-07-28 20:50:09 +0000
commit0c422d65c6dc16d9e2887695ee5f6fa3e07fe617 (patch)
tree3c18d16e2a02b9083f0e184fd6fd7826200bb71e
parent709e897e44e353f2bda74d1f5b4bcaf413bf5a54 (diff)
derived from Obj, removed Exception declaration on withMeta
-rw-r--r--src/cli/runtime/PersistentListIdentityMap.cs47
-rw-r--r--src/cli/runtime/PersistentListMap.cs49
-rw-r--r--src/cli/runtime/PersistentTreeMap.cs32
-rw-r--r--src/jvm/clojure/lang/AFn.java8
-rw-r--r--src/jvm/clojure/lang/Obj.java2
-rw-r--r--src/jvm/clojure/lang/PersistentArray.java8
-rw-r--r--src/jvm/clojure/lang/PersistentArrayMap.java8
-rw-r--r--src/jvm/clojure/lang/PersistentHashtableMap.java8
-rw-r--r--src/jvm/clojure/lang/PersistentListIdentityMap.java59
-rw-r--r--src/jvm/clojure/lang/PersistentListMap.java103
-rw-r--r--src/jvm/clojure/lang/PersistentTreeMap.java31
-rw-r--r--src/jvm/clojure/lang/Symbol.java2
12 files changed, 241 insertions, 116 deletions
diff --git a/src/cli/runtime/PersistentListIdentityMap.cs b/src/cli/runtime/PersistentListIdentityMap.cs
index 0a60ebc6..b00fd620 100644
--- a/src/cli/runtime/PersistentListIdentityMap.cs
+++ b/src/cli/runtime/PersistentListIdentityMap.cs
@@ -31,16 +31,23 @@ namespace clojure.lang
* code duplication here is kind of gross, but most efficient
*/
- public class PersistentListIdentityMap : IPersistentMap, IMapEntry, ISeq, ISequential
+ public class PersistentListIdentityMap : Obj, IPersistentMap, IMapEntry, ISeq, ISequential
{
static public PersistentListIdentityMap EMPTY = new PersistentListIdentityMap();
static public PersistentListIdentityMap create(Object key, Object val)
{
- return new Tail(key, val);
+ return new Tail(key, val,null);
}
+ public override Obj withMeta(IPersistentMap meta)
+ {
+ Obj ret = (Obj)MemberwiseClone();
+ ret._meta = meta;
+ return ret;
+ }
+
public virtual Object key()
{
return null;
@@ -78,7 +85,7 @@ namespace clojure.lang
public virtual IPersistentMap put(Object key, Object val)
{
- return new Tail(key, val);
+ return new Tail(key, val, _meta);
}
public virtual IPersistentMap remove(Object key)
@@ -134,7 +141,7 @@ namespace clojure.lang
first = false;
else
e = e.next();
- return e != EMPTY;
+ return e.count() > 0;
}
public void Reset()
@@ -155,10 +162,11 @@ namespace clojure.lang
readonly Object _key;
readonly Object _val;
- internal Tail(Object key, Object val)
+ internal Tail(Object key, Object val, IPersistentMap meta)
{
this._key = key;
this._val = val;
+ this._meta = meta;
}
override internal PersistentListIdentityMap next()
@@ -211,7 +219,7 @@ namespace clojure.lang
{
throw new Exception("Key already present");
}
- return new Link(key, val, this);
+ return new Link(key, val, this, _meta);
}
override public IPersistentMap put(Object key, Object val)
@@ -220,15 +228,19 @@ namespace clojure.lang
{
if (val == _val)
return this;
- return new Tail(key, val);
+ return new Tail(key, val, _meta);
}
- return new Link(key, val, this);
+ return new Link(key, val, this, _meta);
}
override public IPersistentMap remove(Object key)
{
if ((key == _key))
- return EMPTY;
+ {
+ if (_meta == null)
+ return EMPTY;
+ return (IPersistentMap)EMPTY.withMeta(_meta);
+ }
return this;
}
@@ -254,11 +266,12 @@ namespace clojure.lang
readonly Object _val;
readonly PersistentListIdentityMap _rest;
- internal Link(Object key, Object val, PersistentListIdentityMap next)
+ internal Link(Object key, Object val, PersistentListIdentityMap next, IPersistentMap meta)
{
this._key = key;
this._val = val;
this._rest = next;
+ this._meta = meta;
}
override public Object key()
@@ -300,7 +313,7 @@ namespace clojure.lang
{
throw new Exception("Key already present");
}
- return new Link(key, val, this);
+ return new Link(key, val, this, _meta);
}
override public IPersistentMap put(Object key, Object val)
@@ -312,13 +325,17 @@ namespace clojure.lang
return this;
return create(_key, _val, remove(key));
}
- return new Link(key, val, this);
+ return new Link(key, val, this, _meta);
}
override public IPersistentMap remove(Object key)
{
if ((key == _key))
- return _rest;
+ {
+ if (_rest._meta == _meta)
+ return _rest;
+ return (IPersistentMap)_rest.withMeta(_meta);
+ }
PersistentListIdentityMap r = (PersistentListIdentityMap)_rest.remove(key);
if (r == _rest) //not there
return this;
@@ -356,8 +373,8 @@ namespace clojure.lang
PersistentListIdentityMap create(Object k, Object v, IPersistentMap r)
{
if (r == EMPTY)
- return new Tail(k, v);
- return new Link(k, v, (PersistentListIdentityMap)r);
+ return new Tail(k, v, _meta);
+ return new Link(k, v, (PersistentListIdentityMap)r, _meta);
}
}
diff --git a/src/cli/runtime/PersistentListMap.cs b/src/cli/runtime/PersistentListMap.cs
index 04065097..a3896c97 100644
--- a/src/cli/runtime/PersistentListMap.cs
+++ b/src/cli/runtime/PersistentListMap.cs
@@ -27,15 +27,22 @@ namespace clojure.lang
*
* null keys and values are ok, but you won't be able to distinguish a null value via get - use contains/find
*/
-public class PersistentListMap : IPersistentMap, IMapEntry, ISeq, ISequential
+public class PersistentListMap : Obj, IPersistentMap, IMapEntry, ISeq, ISequential
{
static public PersistentListMap EMPTY = new PersistentListMap();
static public PersistentListMap create(Object key, Object val){
- return new Tail(key, val);
+ return new Tail(key, val,null);
}
+public override Obj withMeta(IPersistentMap meta)
+ {
+ Obj ret = (Obj)MemberwiseClone();
+ ret._meta = meta;
+ return ret;
+ }
+
public virtual Object key(){
return null;
}
@@ -65,7 +72,7 @@ public virtual IPersistentMap add(Object key, Object val){
}
public virtual IPersistentMap put(Object key, Object val){
- return new Tail(key, val);
+ return new Tail(key, val, _meta);
}
public virtual IPersistentMap remove(Object key){
@@ -118,7 +125,7 @@ public bool MoveNext()
first = false;
else
e = e.next();
- return e != EMPTY;
+ return e.count() > 0;
}
public void Reset()
@@ -137,9 +144,10 @@ internal class Tail : PersistentListMap {
readonly Object _key;
readonly Object _val;
- internal Tail(Object key,Object val){
+ internal Tail(Object key,Object val,IPersistentMap meta){
this._key = key;
this._val = val;
+ this._meta = meta;
}
override internal PersistentListMap next(){
@@ -191,7 +199,7 @@ internal class Tail : PersistentListMap {
{
throw new Exception("Key already present");
}
- return new Link(key, val, this);
+ return new Link(key, val, this,_meta);
}
override public IPersistentMap put(Object key, Object val)
@@ -200,14 +208,18 @@ internal class Tail : PersistentListMap {
{
if(val == _val)
return this;
- return new Tail(key,val);
+ return new Tail(key,val,_meta);
}
- return new Link(key,val,this);
+ return new Link(key,val,this,_meta);
}
override public IPersistentMap remove(Object key){
if(equalKey(key,_key))
- return EMPTY;
+ {
+ if(_meta == null)
+ return EMPTY;
+ return (IPersistentMap)EMPTY.withMeta(_meta);
+ }
return this;
}
@@ -232,10 +244,11 @@ internal class Link : PersistentListMap {
readonly Object _val;
readonly PersistentListMap _rest;
- internal Link(Object key,Object val,PersistentListMap next){
+ internal Link(Object key,Object val,PersistentListMap next,IPersistentMap meta){
this._key = key;
this._val = val;
this._rest = next;
+ this._meta = meta;
}
override public Object key(){
@@ -271,7 +284,7 @@ internal class Link : PersistentListMap {
{
throw new Exception("Key already present");
}
- return new Link(key,val,this);
+ return new Link(key,val,this,_meta);
}
override public IPersistentMap put(Object key, Object val)
@@ -283,13 +296,17 @@ internal class Link : PersistentListMap {
return this;
return create(_key,_val,remove(key));
}
- return new Link(key,val,this);
+ return new Link(key,val,this,_meta);
}
override public IPersistentMap remove(Object key)
{
if(equalKey(key,_key))
- return _rest;
+ {
+ if(_rest._meta == _meta)
+ return _rest;
+ return (IPersistentMap)_rest.withMeta(_meta);
+ }
PersistentListMap r = (PersistentListMap)_rest.remove(key);
if(r == _rest) //not there
return this;
@@ -324,9 +341,9 @@ internal class Link : PersistentListMap {
PersistentListMap create(Object k, Object v, IPersistentMap r)
{
- if(r == EMPTY)
- return new Tail(k,v);
- return new Link(k, v, (PersistentListMap)r);
+ if(r.count() == 0)
+ return new Tail(k,v,_meta);
+ return new Link(k, v, (PersistentListMap)r,_meta);
}
}
diff --git a/src/cli/runtime/PersistentTreeMap.cs b/src/cli/runtime/PersistentTreeMap.cs
index 93335bf9..79831fe1 100644
--- a/src/cli/runtime/PersistentTreeMap.cs
+++ b/src/cli/runtime/PersistentTreeMap.cs
@@ -25,7 +25,7 @@ namespace clojure.lang
* See Okasaki, Kahrs, Larsen et al
*/
-public class PersistentTreeMap : IPersistentMap, ISequential{
+public class PersistentTreeMap : Obj, IPersistentMap, ISequential{
public readonly IComparer comp;
public readonly Node tree;
@@ -40,6 +40,13 @@ public PersistentTreeMap(IComparer comp){
_count = 0;
}
+public override Obj withMeta(IPersistentMap meta)
+ {
+ Obj ret = (Obj)MemberwiseClone();
+ ret._meta = meta;
+ return ret;
+ }
+
public int count(){
return _count;
}
@@ -59,7 +66,7 @@ public IPersistentMap add(Object key,Object val){
{
throw new Exception("Key already present");
}
- return new PersistentTreeMap(comp, t.blacken(), _count + 1);
+ return new PersistentTreeMap(comp, t.blacken(), _count + 1, _meta);
}
public IPersistentMap put(Object key, Object val){
@@ -69,10 +76,10 @@ public IPersistentMap put(Object key, Object val){
{
Node foundNode = (Node) found.val;
if(foundNode.val() == val) //note only get same collection on identity of val, not equals()
- return this;
- return new PersistentTreeMap(comp, replace(tree, key, val), _count);
- }
- return new PersistentTreeMap(comp, t.blacken(), _count + 1);
+ return this;
+ return new PersistentTreeMap(comp, replace(tree, key, val), _count, _meta);
+ }
+ return new PersistentTreeMap(comp, t.blacken(), _count + 1, _meta);
}
@@ -83,10 +90,12 @@ public IPersistentMap remove(Object key){
{
if(found.val == null)//null == doesn't contain key
return this;
- //empty
- return new PersistentTreeMap(comp);
- }
- return new PersistentTreeMap(comp, t.blacken(), _count - 1);
+ //empty
+ PersistentTreeMap ret = new PersistentTreeMap(comp);
+ ret._meta = _meta;
+ return ret;
+ }
+ return new PersistentTreeMap(comp, t.blacken(), _count - 1, _meta);
}
public ISeq seq() {
@@ -329,10 +338,11 @@ Node replace(Node t, Object key, Object val){
c > 0 ? replace(t.right(), key, val) : t.right());
}
-PersistentTreeMap(IComparer comp, Node tree, int count){
+PersistentTreeMap(IComparer comp, Node tree, int count,IPersistentMap meta){
this.comp = comp;
this.tree = tree;
this._count = count;
+ this._meta = meta;
}
static Red red(Object key, Object val, Node left, Node right){
diff --git a/src/jvm/clojure/lang/AFn.java b/src/jvm/clojure/lang/AFn.java
index ec54cc67..ae27e48b 100644
--- a/src/jvm/clojure/lang/AFn.java
+++ b/src/jvm/clojure/lang/AFn.java
@@ -99,9 +99,15 @@ public static Object throwArity()
throw new IllegalArgumentException("Wrong number of args passed");
}
-public Obj withMeta(IPersistentMap meta) throws Exception {
+public Obj withMeta(IPersistentMap meta) {
+ try{
Obj ret = (Obj) clone();
ret._meta = meta;
return ret;
+ }
+ catch(CloneNotSupportedException ignore)
+ {
+ return null;
+ }
}
}
diff --git a/src/jvm/clojure/lang/Obj.java b/src/jvm/clojure/lang/Obj.java
index 37af46be..3e3fe570 100644
--- a/src/jvm/clojure/lang/Obj.java
+++ b/src/jvm/clojure/lang/Obj.java
@@ -21,6 +21,6 @@ public IPersistentMap meta() {
return _meta;
}
-abstract public Obj withMeta(IPersistentMap meta) throws Exception;
+abstract public Obj withMeta(IPersistentMap meta);
}
diff --git a/src/jvm/clojure/lang/PersistentArray.java b/src/jvm/clojure/lang/PersistentArray.java
index 9a51c526..2f5a5813 100644
--- a/src/jvm/clojure/lang/PersistentArray.java
+++ b/src/jvm/clojure/lang/PersistentArray.java
@@ -58,10 +58,16 @@ public ISeq seq() {
return null;
}
-public Obj withMeta(IPersistentMap meta) throws Exception {
+public Obj withMeta(IPersistentMap meta) {
+ try{
Obj ret = (Obj) clone();
ret._meta = meta;
return ret;
+ }
+ catch(CloneNotSupportedException ignore)
+ {
+ return null;
+ }
}
static class Master{
diff --git a/src/jvm/clojure/lang/PersistentArrayMap.java b/src/jvm/clojure/lang/PersistentArrayMap.java
index 19a1b255..c4bae5e7 100644
--- a/src/jvm/clojure/lang/PersistentArrayMap.java
+++ b/src/jvm/clojure/lang/PersistentArrayMap.java
@@ -46,10 +46,16 @@ IPersistentMap createHT(Object[] init){
return ret;
}
-public Obj withMeta(IPersistentMap meta) throws Exception {
+public Obj withMeta(IPersistentMap meta) {
+ try{
Obj ret = (Obj) clone();
ret._meta = meta;
return ret;
+ }
+ catch(CloneNotSupportedException ignore)
+ {
+ return null;
+ }
}
/**
diff --git a/src/jvm/clojure/lang/PersistentHashtableMap.java b/src/jvm/clojure/lang/PersistentHashtableMap.java
index d60d15ba..c5e75a32 100644
--- a/src/jvm/clojure/lang/PersistentHashtableMap.java
+++ b/src/jvm/clojure/lang/PersistentHashtableMap.java
@@ -54,10 +54,16 @@ PersistentHashtableMap(int count,PersistentArray array,int growAt) {
this.growAtCount = growAt;
}
-public Obj withMeta(IPersistentMap meta) throws Exception {
+public Obj withMeta(IPersistentMap meta) {
+ try{
Obj ret = (Obj) clone();
ret._meta = meta;
return ret;
+ }
+ catch(CloneNotSupportedException ignore)
+ {
+ return null;
+ }
}
int calcPrimeCapacity(int capacity) {
diff --git a/src/jvm/clojure/lang/PersistentListIdentityMap.java b/src/jvm/clojure/lang/PersistentListIdentityMap.java
index 1eea34f3..0fd86339 100644
--- a/src/jvm/clojure/lang/PersistentListIdentityMap.java
+++ b/src/jvm/clojure/lang/PersistentListIdentityMap.java
@@ -28,13 +28,25 @@ import java.util.Iterator;
* code duplication here is kind of gross, but most efficient
*/
-public class PersistentListIdentityMap implements IPersistentMap, IMapEntry, ISeq, ISequential
+public class PersistentListIdentityMap extends Obj implements IPersistentMap, IMapEntry, ISeq, ISequential,Cloneable
{
static public PersistentListIdentityMap EMPTY = new PersistentListIdentityMap();
static public PersistentListIdentityMap create(Object key, Object val){
- return new Tail(key, val);
+ return new Tail(key, val,null);
+}
+
+public Obj withMeta(IPersistentMap meta) {
+ try{
+ Obj ret = (Obj) clone();
+ ret._meta = meta;
+ return ret;
+ }
+ catch(CloneNotSupportedException ignore)
+ {
+ return null;
+ }
}
public Object key(){
@@ -66,7 +78,7 @@ public IPersistentMap add(Object key, Object val) throws Exception {
}
public PersistentListIdentityMap put(Object key, Object val){
- return new Tail(key, val);
+ return new Tail(key, val,_meta);
}
public PersistentListIdentityMap remove(Object key){
@@ -103,7 +115,7 @@ static class Iter implements Iterator{
}
public boolean hasNext(){
- return e != EMPTY;
+ return e.count() > 0;
}
public Object next(){
@@ -125,10 +137,11 @@ static class Tail extends PersistentListIdentityMap {
final Object _key;
final Object _val;
- Tail(Object key,Object val){
+ Tail(Object key,Object val,IPersistentMap meta){
this._key = key;
this._val = val;
- }
+ this._meta = meta;
+ }
PersistentListIdentityMap next(){
return EMPTY;
@@ -171,7 +184,7 @@ static class Tail extends PersistentListIdentityMap {
{
throw new Exception("Key already present");
}
- return new Link(key,val,this);
+ return new Link(key,val,this,_meta);
}
public PersistentListIdentityMap put(Object key, Object val){
@@ -179,15 +192,18 @@ static class Tail extends PersistentListIdentityMap {
{
if(val == _val)
return this;
- return new Tail(key,val);
+ return new Tail(key,val,_meta);
}
- return new Link(key,val,this);
+ return new Link(key,val,this,_meta);
}
public PersistentListIdentityMap remove(Object key){
if(key == _key)
- return EMPTY;
- return this;
+ {
+ if(_meta == null)
+ return EMPTY;
+ return (PersistentListIdentityMap) EMPTY.withMeta(_meta);
+ } return this;
}
public Object first() {
@@ -208,11 +224,12 @@ static class Link extends PersistentListIdentityMap {
final Object _val;
final PersistentListIdentityMap _rest;
- Link(Object key,Object val,PersistentListIdentityMap next){
+ Link(Object key,Object val,PersistentListIdentityMap next,IPersistentMap meta){
this._key = key;
this._val = val;
this._rest = next;
- }
+ this._meta = meta;
+ }
public Object key(){
return _key;
@@ -246,7 +263,7 @@ static class Link extends PersistentListIdentityMap {
{
throw new Exception("Key already present");
}
- return new Link(key,val,this);
+ return new Link(key,val,this,_meta);
}
public PersistentListIdentityMap put(Object key, Object val){
@@ -257,12 +274,16 @@ static class Link extends PersistentListIdentityMap {
return this;
return create(_key,_val,remove(key));
}
- return new Link(key,val,this);
+ return new Link(key,val,this,_meta);
}
public PersistentListIdentityMap remove(Object key){
if(key == _key)
- return _rest;
+ {
+ if(_rest._meta == _meta)
+ return _rest;
+ return (PersistentListIdentityMap) _rest.withMeta(_meta);
+ }
PersistentListIdentityMap r = _rest.remove(key);
if(r == _rest) //not there
return this;
@@ -293,9 +314,9 @@ static class Link extends PersistentListIdentityMap {
}
PersistentListIdentityMap create(Object k,Object v,PersistentListIdentityMap r){
- if(r == EMPTY)
- return new Tail(k,v);
- return new Link(k, v, r);
+ if(r.count() == 0)
+ return new Tail(k,v,_meta);
+ return new Link(k, v, r,_meta);
}
}
diff --git a/src/jvm/clojure/lang/PersistentListMap.java b/src/jvm/clojure/lang/PersistentListMap.java
index 53777019..c2881363 100644
--- a/src/jvm/clojure/lang/PersistentListMap.java
+++ b/src/jvm/clojure/lang/PersistentListMap.java
@@ -26,15 +26,26 @@ import java.util.Iterator;
*
* null keys and values are ok, but you won't be able to distinguish a null value via get - use contains/find
*/
-public class PersistentListMap implements IPersistentMap, IMapEntry, ISeq, ISequential
+public class PersistentListMap extends Obj implements IPersistentMap, IMapEntry, ISeq, ISequential, Cloneable
{
static public PersistentListMap EMPTY = new PersistentListMap();
static public PersistentListMap create(Object key, Object val){
- return new Tail(key, val);
+ return new Tail(key, val,null);
}
+public Obj withMeta(IPersistentMap meta) {
+ try{
+ Obj ret = (Obj) clone();
+ ret._meta = meta;
+ return ret;
+ }
+ catch(CloneNotSupportedException ignore)
+ {
+ return null;
+ }
+}
public Object key(){
return null;
@@ -64,12 +75,12 @@ public IPersistentMap add(Object key, Object val) throws Exception {
return put(key, val);
}
-public PersistentListMap put(Object key, Object val){
- return new Tail(key, val);
+public PersistentListMap put(Object key, Object val) {
+ return new Tail(key, val,_meta);
}
-public PersistentListMap remove(Object key){
- return this;
+public PersistentListMap remove(Object key) {
+ return this;
}
public Object get(Object key){
@@ -101,7 +112,7 @@ static class Iter implements Iterator{
}
public boolean hasNext(){
- return e != EMPTY;
+ return e.count() != 0;
}
public Object next(){
@@ -123,10 +134,11 @@ static class Tail extends PersistentListMap {
final Object _key;
final Object _val;
- Tail(Object key,Object val){
+ Tail(Object key,Object val, IPersistentMap meta){
this._key = key;
this._val = val;
- }
+ this._meta = meta;
+ }
PersistentListMap next(){
return EMPTY;
@@ -169,7 +181,7 @@ static class Tail extends PersistentListMap {
{
throw new Exception("Key already present");
}
- return new Link(key,val,this);
+ return new Link(key,val,this,_meta);
}
public PersistentListMap put(Object key, Object val){
@@ -177,16 +189,20 @@ static class Tail extends PersistentListMap {
{
if(val == _val)
return this;
- return new Tail(key,val);
+ return new Tail(key,val,_meta);
}
- return new Link(key,val,this);
+ return new Link(key,val,this,_meta);
}
- public PersistentListMap remove(Object key){
- if(equalKey(key,_key))
- return EMPTY;
- return this;
- }
+ public PersistentListMap remove(Object key) {
+ if(equalKey(key,_key))
+ {
+ if(_meta == null)
+ return EMPTY;
+ return (PersistentListMap) EMPTY.withMeta(_meta);
+ }
+ return this;
+ }
public Object first() {
return this;
@@ -207,11 +223,12 @@ static class Link extends PersistentListMap {
final Object _val;
final PersistentListMap _rest;
- Link(Object key,Object val,PersistentListMap next){
+ Link(Object key,Object val,PersistentListMap next,IPersistentMap meta){
this._key = key;
this._val = val;
this._rest = next;
- }
+ this._meta = meta;
+ }
public Object key(){
return _key;
@@ -245,28 +262,32 @@ static class Link extends PersistentListMap {
{
throw new Exception("Key already present");
}
- return new Link(key,val,this);
+ return new Link(key,val,this,_meta);
}
- public PersistentListMap put(Object key, Object val){
- IMapEntry e = find(key);
- if(e != null)
- {
- if(e.val() == val)
- return this;
- return create(_key,_val,remove(key));
- }
- return new Link(key,val,this);
- }
+ public PersistentListMap put(Object key, Object val) {
+ IMapEntry e = find(key);
+ if(e != null)
+ {
+ if(e.val() == val)
+ return this;
+ return create(_key,_val,remove(key));
+ }
+ return new Link(key,val,this,_meta);
+ }
- public PersistentListMap remove(Object key){
- if(equalKey(key,_key))
- return _rest;
- PersistentListMap r = _rest.remove(key);
- if(r == _rest) //not there
- return this;
- return create(_key,_val,r);
- }
+ public PersistentListMap remove(Object key) {
+ if(equalKey(key,_key))
+ {
+ if(_rest._meta == _meta)
+ return _rest;
+ return (PersistentListMap) _rest.withMeta(_meta);
+ }
+ PersistentListMap r = _rest.remove(key);
+ if(r == _rest) //not there
+ return this;
+ return create(_key,_val,r);
+ }
public Object get(Object key){
IMapEntry e = find(key);
@@ -292,9 +313,9 @@ static class Link extends PersistentListMap {
}
PersistentListMap create(Object k,Object v,PersistentListMap r){
- if(r == EMPTY)
- return new Tail(k,v);
- return new Link(k, v, r);
+ if(r.count() == 0)
+ return new Tail(k,v,_meta);
+ return new Link(k, v, r,_meta);
}
}
diff --git a/src/jvm/clojure/lang/PersistentTreeMap.java b/src/jvm/clojure/lang/PersistentTreeMap.java
index 5b978215..c83378c6 100644
--- a/src/jvm/clojure/lang/PersistentTreeMap.java
+++ b/src/jvm/clojure/lang/PersistentTreeMap.java
@@ -22,7 +22,7 @@ import java.util.*;
* See Okasaki, Kahrs, Larsen et al
*/
-public class PersistentTreeMap implements IPersistentMap, ISequential {
+public class PersistentTreeMap extends Obj implements IPersistentMap, ISequential, Cloneable {
public final Comparator comp;
public final Node tree;
@@ -38,6 +38,18 @@ public PersistentTreeMap(Comparator comp){
_count = 0;
}
+public Obj withMeta(IPersistentMap meta) {
+ try{
+ Obj ret = (Obj) clone();
+ ret._meta = meta;
+ return ret;
+ }
+ catch(CloneNotSupportedException ignore)
+ {
+ return null;
+ }
+}
+
public boolean contains(Object key){
return find(key) != null;
}
@@ -49,7 +61,7 @@ public PersistentTreeMap add(Object key, Object val) throws Exception {
{
throw new Exception("Key already present");
}
- return new PersistentTreeMap(comp, t.blacken(), _count + 1);
+ return new PersistentTreeMap(comp, t.blacken(), _count + 1, _meta);
}
public PersistentTreeMap put(Object key, Object val){
@@ -60,9 +72,9 @@ public PersistentTreeMap put(Object key, Object val){
Node foundNode = (Node) found.val;
if(foundNode.val() == val) //note only get same collection on identity of val, not equals()
return this;
- return new PersistentTreeMap(comp, replace(tree, key, val), _count);
+ return new PersistentTreeMap(comp, replace(tree, key, val), _count,_meta);
}
- return new PersistentTreeMap(comp, t.blacken(), _count + 1);
+ return new PersistentTreeMap(comp, t.blacken(), _count + 1,_meta);
}
@@ -74,9 +86,11 @@ public PersistentTreeMap remove(Object key){
if(found.val == null)//null == doesn't contain key
return this;
//empty
- return new PersistentTreeMap(comp);
- }
- return new PersistentTreeMap(comp, t.blacken(), _count - 1);
+ PersistentTreeMap ret = new PersistentTreeMap(comp);
+ ret._meta = _meta;
+ return ret;
+ }
+ return new PersistentTreeMap(comp, t.blacken(), _count - 1,_meta);
}
public ISeq seq() throws Exception {
@@ -328,10 +342,11 @@ Node replace(Node t, Object key, Object val){
c > 0 ? replace(t.right(), key, val) : t.right());
}
-PersistentTreeMap(Comparator comp, Node tree, int count){
+PersistentTreeMap(Comparator comp, Node tree, int count, IPersistentMap meta){
this.comp = comp;
this.tree = tree;
this._count = count;
+ this._meta = meta;
}
static Red red(Object key, Object val, Node left, Node right){
diff --git a/src/jvm/clojure/lang/Symbol.java b/src/jvm/clojure/lang/Symbol.java
index 4351d5bb..fc97543c 100644
--- a/src/jvm/clojure/lang/Symbol.java
+++ b/src/jvm/clojure/lang/Symbol.java
@@ -84,7 +84,7 @@ public int compareTo(Object o) {
return hashCode() - ((Symbol)o).hashCode();
}
-public Obj withMeta(IPersistentMap meta) throws Exception {
+public Obj withMeta(IPersistentMap meta) {
this._meta = meta;
return this;
}