diff options
author | Rich Hickey <richhickey@gmail.com> | 2006-08-05 16:44:23 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2006-08-05 16:44:23 +0000 |
commit | 279dd21d4b919496c8fb54c3135f2b82cc36f5c2 (patch) | |
tree | 0216faea0823626bc0b59346b542b68f0392feb3 /src | |
parent | da11eb9d0dd587e532470965b3c655b741d1fa5c (diff) |
added cons to IPersistentCollection
Diffstat (limited to 'src')
21 files changed, 113 insertions, 145 deletions
diff --git a/src/cli/runtime/APersistentMap.cs b/src/cli/runtime/APersistentMap.cs index 4e39acb7..99ca0ea4 100644 --- a/src/cli/runtime/APersistentMap.cs +++ b/src/cli/runtime/APersistentMap.cs @@ -61,6 +61,12 @@ public abstract class APersistentMap : Obj, IPersistentMap{ abstract public ISeq seq();
+ public IPersistentCollection cons(Object o)
+ {
+ IMapEntry e = (IMapEntry)o;
+ return (IPersistentCollection)assoc(e.key(), e.val());
+ }
+
#endregion
}
diff --git a/src/cli/runtime/AnArray.cs b/src/cli/runtime/AnArray.cs index b586d6f5..b02f7c65 100644 --- a/src/cli/runtime/AnArray.cs +++ b/src/cli/runtime/AnArray.cs @@ -15,6 +15,13 @@ namespace clojure.lang {
public abstract class AnArray : Obj, IArray {
+public virtual IPersistentCollection cons(Object o) {
+ PersistentArrayList ret = new PersistentArrayList(this, this.count() + 10);
+ ret = (PersistentArrayList)ret.cons(o);
+ ret._meta = _meta;
+ return ret;
+}
+
public override Obj withMeta(IPersistentMap meta)
{
if(_meta == meta)
diff --git a/src/cli/runtime/Cons.cs b/src/cli/runtime/Cons.cs index cd5291db..f4361e07 100644 --- a/src/cli/runtime/Cons.cs +++ b/src/cli/runtime/Cons.cs @@ -15,7 +15,7 @@ using System; namespace clojure.lang
{ -public class Cons : ISeq, IPersistentCollection
+public class Cons : ISeq
{ private readonly Object _first; diff --git a/src/cli/runtime/IPersistentCollection.cs b/src/cli/runtime/IPersistentCollection.cs index 6746240b..929a419e 100644 --- a/src/cli/runtime/IPersistentCollection.cs +++ b/src/cli/runtime/IPersistentCollection.cs @@ -20,5 +20,6 @@ namespace clojure.lang ISeq seq();
+ IPersistentCollection cons(Object o);
}
}
diff --git a/src/cli/runtime/PerisistentArrayList.cs b/src/cli/runtime/PerisistentArrayList.cs index 07e65f5e..6753f4f1 100644 --- a/src/cli/runtime/PerisistentArrayList.cs +++ b/src/cli/runtime/PerisistentArrayList.cs @@ -33,6 +33,10 @@ PersistentArrayList(int size, Object defaultVal, float loadFactor, int count):ba this._count = count;
}
+public PersistentArrayList(IArray init, int initialCapacity):base(init,initialCapacity){
+ _count = Math.Min(init.count(),initialCapacity);
+}
+
override public Object nth(int i) {
if(i >= _count)
throw new IndexOutOfRangeException();
@@ -55,11 +59,7 @@ override public int count(){ return _count;
}
-public int capacity(){
- return data.master.array.Length;
-}
-
-public PersistentArrayList add(Object val) {
+override public IPersistentCollection cons(Object val) {
if(_count == data.master.array.Length) //full
{
lock(data.master){
diff --git a/src/cli/runtime/PersistentArray.cs b/src/cli/runtime/PersistentArray.cs index 3235eb44..f1e3fef5 100644 --- a/src/cli/runtime/PersistentArray.cs +++ b/src/cli/runtime/PersistentArray.cs @@ -253,6 +253,17 @@ public PersistentArray(IArray init) :this(init.length()) { data.master.load = load;
}
+public PersistentArray(IArray init, int size) :this(size) {
+ int load = 0;
+ for(int i=0;i < init.length() && i < size;i++)
+ {
+ data.master.array[i] = new Entry(0,init.nth(i));
+ ++load;
+ }
+
+ data.master.load = load;
+}
+
override public int count(){
return data.master.array.Length;
}
@@ -500,7 +511,7 @@ static public void Main(String[] args){ {
v.Add(0);
//p = p.set(i, 0);
- p = ((PersistentArrayList)p).add(0);
+ p = (IArray)((PersistentArrayList)p).cons(0);
}
Random rand;
diff --git a/src/cli/runtime/PersistentArrayMap.cs b/src/cli/runtime/PersistentArrayMap.cs index 6c848685..e758c547 100644 --- a/src/cli/runtime/PersistentArrayMap.cs +++ b/src/cli/runtime/PersistentArrayMap.cs @@ -25,7 +25,7 @@ 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 PersistentArrayMap : Obj, IPersistentMap, IPersistentCollection {
+public class PersistentArrayMap : APersistentMap {
internal readonly Object[] array;
@@ -49,12 +49,6 @@ virtual internal IPersistentMap createHT(Object[] init){ return ret;
}
-public override Obj withMeta(IPersistentMap meta)
- {
- Obj ret = (Obj)MemberwiseClone();
- ret._meta = meta;
- return ret;
- }
/**
* This ctor captures/aliases the passed array, so do not modify later
* @param init {key1,val1,key2,val2,...}
@@ -63,22 +57,22 @@ public PersistentArrayMap(params Object[] init){ this.array = init;
}
-public int count() {
+override public int count() {
return array.Length/2;
}
-public bool contains(Object key){
+override public bool contains(Object key){
return indexOf(key) >= 0;
}
-public IMapEntry find(Object key) {
+override public IMapEntry find(Object key) {
int i = indexOf(key);
if(i >= 0)
return new Iter(array,i);
return null;
}
-public IPersistentMap assocEx(Object key, Object val) {
+override public IPersistentMap assocEx(Object key, Object val) {
int i = indexOf(key);
Object[] newArray;
if(i >= 0)
@@ -98,7 +92,7 @@ public IPersistentMap assocEx(Object key, Object val) { return create(newArray);
}
-public Associative assoc(Object key, Object val) {
+override public Associative assoc(Object key, Object val) {
int i = indexOf(key);
Object[] newArray;
if(i >= 0) //already have key, same-sized replacement
@@ -121,7 +115,7 @@ public Associative assoc(Object key, Object val) { return create(newArray);
}
-public IPersistentMap without(Object key) {
+override public IPersistentMap without(Object key) {
int i = indexOf(key);
if(i >= 0) //have key, will remove
{
@@ -152,7 +146,7 @@ virtual public IPersistentMap empty() { return ret;
}
-public Object get(Object key) {
+override public Object get(Object key) {
int i = indexOf(key);
if(i >= 0)
return array[i + 1];
@@ -178,11 +172,11 @@ internal virtual bool equalKey(Object k1,Object k2){ return k1.Equals(k2);
}
-public IEnumerator GetEnumerator() {
+override public IEnumerator GetEnumerator() {
return new Iter(array);
}
-public ISeq seq() {
+override public ISeq seq() {
if(array.Length > 0)
return new Seq(array,0);
return null;
diff --git a/src/cli/runtime/PersistentHashtableMap.cs b/src/cli/runtime/PersistentHashtableMap.cs index 0bf8930b..52dea0ad 100644 --- a/src/cli/runtime/PersistentHashtableMap.cs +++ b/src/cli/runtime/PersistentHashtableMap.cs @@ -16,7 +16,7 @@ namespace clojure.lang {
-public class PersistentHashtableMap : Obj, IPersistentMap {
+public class PersistentHashtableMap : APersistentMap {
static readonly float FILL_FACTOR = 0.75f;
@@ -55,14 +55,7 @@ internal PersistentHashtableMap(int count,PersistentArray array,int growAt) { this._count = count;
this.array = array;
this.growAtCount = growAt;
-}
-
-public override Obj withMeta(IPersistentMap meta)
- {
- Obj ret = (Obj)MemberwiseClone();
- ret._meta = meta;
- return ret;
- }
+}
int calcPrimeCapacity(int capacity) {
// No .Net equivalent
@@ -73,23 +66,23 @@ int calcPrimeCapacity(int capacity) { return ret;
}
-public int count() {
+override public int count() {
return _count;
}
-public bool contains(Object key) {
+override public bool contains(Object key) {
IPersistentMap entries = entriesFor(key);
return entries != null && entries.contains(key);
}
-public IMapEntry find(Object key) {
+override public IMapEntry find(Object key) {
IPersistentMap entries = entriesFor(key);
if(entries != null)
return entries.find(key);
return null;
}
-public IPersistentMap assocEx(Object key, Object val) {
+override public IPersistentMap assocEx(Object key, Object val) {
if(_count > growAtCount)
return grow().assocEx(key, val);
int i = bucketFor(key,array);
@@ -98,7 +91,7 @@ public IPersistentMap assocEx(Object key, Object val) { return create(_count + incr, newArray, growAtCount);
}
-public Associative assoc(Object key, Object val) {
+override public Associative assoc(Object key, Object val) {
if(_count > growAtCount)
return grow().assoc(key, val);
int i = bucketFor(key,array);
@@ -139,7 +132,7 @@ PersistentArray doAdd(int i,Object key,Object val,PersistentArray array) { return (PersistentArray)array.assocN(i, newEntries);
}
-public IPersistentMap without(Object key) {
+override public IPersistentMap without(Object key) {
int i = bucketFor(key,array);
IPersistentMap entries = (IPersistentMap) array.nth(i);
if (entries != null)
@@ -152,7 +145,7 @@ public IPersistentMap without(Object key) { return this;
}
-public Object get(Object key) {
+override public Object get(Object key) {
IPersistentMap entries = entriesFor(key);
if(entries != null)
return entries.get(key);
@@ -172,11 +165,11 @@ IPersistentMap grow(){ return create(_count,newArray);
}
-public virtual IEnumerator GetEnumerator() {
+override public IEnumerator GetEnumerator() {
return new Iter(array);
}
-public ISeq seq() {
+override public ISeq seq() {
return Seq.create(array);
}
diff --git a/src/cli/runtime/PersistentListMap.cs b/src/cli/runtime/PersistentListMap.cs index 714dfe38..f0c55492 100644 --- a/src/cli/runtime/PersistentListMap.cs +++ b/src/cli/runtime/PersistentListMap.cs @@ -27,7 +27,7 @@ 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 : Obj, IPersistentMap, IMapEntry, ISeq, IPersistentCollection
+public class PersistentListMap : APersistentMap, IMapEntry, ISeq
{
static public PersistentListMap EMPTY = new PersistentListMap();
@@ -35,13 +35,7 @@ static public PersistentListMap EMPTY = new PersistentListMap(); static public PersistentListMap create(Object key, Object 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;
@@ -55,38 +49,34 @@ internal virtual PersistentListMap next(){ return this;
}
-public virtual int count(){
+override public int count(){
return 0;
}
-public virtual bool contains(Object key){
+override public bool contains(Object key){
return false;
}
-public virtual IMapEntry find(Object key){
+override public IMapEntry find(Object key){
return null;
}
-public virtual IPersistentMap assocEx(Object key, Object val){
+override public IPersistentMap assocEx(Object key, Object val){
return (IPersistentMap)assoc(key, val);
}
-public virtual Associative assoc(Object key, Object val){
+override public Associative assoc(Object key, Object val){
return new Tail(key, val, _meta);
}
-public virtual IPersistentMap without(Object key){
+override public IPersistentMap without(Object key){
return this;
}
-public virtual Object get(Object key){
+override public Object get(Object key){
return null;
}
-public virtual int capacity(){
- return 0;
-}
-
virtual public Object first()
{
return null;
@@ -97,7 +87,7 @@ virtual public ISeq rest() return null;
}
-virtual public ISeq seq()
+override public ISeq seq()
{
return null;
}
@@ -136,7 +126,7 @@ public void Reset() #endregion
}
-public IEnumerator GetEnumerator(){
+override public IEnumerator GetEnumerator(){
return new Iter(this);
}
@@ -166,11 +156,6 @@ internal class Tail : PersistentListMap { return null;
}
- override public int capacity()
- {
- return 1;
- }
-
override public Object key()
{
return _key;
@@ -322,9 +307,6 @@ internal class Link : PersistentListMap { return null;
}
- override public int capacity(){
- return count();
- }
override public Object first()
{
diff --git a/src/cli/runtime/PersistentTreeMap.cs b/src/cli/runtime/PersistentTreeMap.cs index b87e3754..f43555ee 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 : Obj, IPersistentMap, IPersistentCollection{ +public class PersistentTreeMap : APersistentMap{ public readonly IComparer comp; public readonly Node tree; @@ -40,26 +40,15 @@ 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; - } - -public int capacity(){ +override public int count(){ return _count; } -public bool contains(Object key){ +override public bool contains(Object key){ return find(key) != null; }
-public IPersistentMap assocEx(Object key,Object val){ +override public IPersistentMap assocEx(Object key,Object val){ Box found = new Box(null); Node t = add(tree, key, val, found); if(t == null) //null == already contains key @@ -69,7 +58,7 @@ public IPersistentMap assocEx(Object key,Object val){ return new PersistentTreeMap(comp, t.blacken(), _count + 1, _meta); } -public Associative assoc(Object key, Object val){ +override public Associative assoc(Object key, Object val){ Box found = new Box(null); Node t = add(tree, key, val, found); if(t == null) //null == already contains key @@ -83,7 +72,7 @@ public Associative assoc(Object key, Object val){ } -public IPersistentMap without(Object key){ +override public IPersistentMap without(Object key){ Box found = new Box(null); Node t = remove(tree, key, found); if(t == null) @@ -98,7 +87,7 @@ public IPersistentMap without(Object key){ return new PersistentTreeMap(comp, t.blacken(), _count - 1, _meta); } -public ISeq seq() {
+override public ISeq seq() {
if(_count > 0)
return Seq.create(tree, true);
return null;
@@ -110,7 +99,7 @@ public ISeq rseq() { return null;
} -public IEnumerator GetEnumerator(){ +override public IEnumerator GetEnumerator(){ return new NodeIEnumerator(tree, true); } @@ -174,12 +163,12 @@ int depth(Node t){ return 1 + Math.Max(depth(t.left()), depth(t.right())); } -public Object get(Object key){ +override public Object get(Object key){ Node n = (Node)find(key); return (n != null) ? n.val() : null; } -public IMapEntry find(Object key){ +override public IMapEntry find(Object key){ Node t = tree; while(t != null) { diff --git a/src/jvm/clojure/lang/APersistentMap.java b/src/jvm/clojure/lang/APersistentMap.java index 3eb9e5ef..c9492c14 100644 --- a/src/jvm/clojure/lang/APersistentMap.java +++ b/src/jvm/clojure/lang/APersistentMap.java @@ -26,4 +26,8 @@ public Obj withMeta(IPersistentMap meta) { }
}
+public IPersistentCollection cons(Object o) {
+ IMapEntry e = (IMapEntry)o;
+ return assoc(e.key(), e.val());
+}
}
diff --git a/src/jvm/clojure/lang/AnArray.java b/src/jvm/clojure/lang/AnArray.java index f9eaa9f4..66d5e614 100644 --- a/src/jvm/clojure/lang/AnArray.java +++ b/src/jvm/clojure/lang/AnArray.java @@ -12,6 +12,13 @@ package clojure.lang; public abstract class AnArray extends Obj implements IArray, Cloneable {
+public IPersistentCollection cons(Object o) {
+ PersistentArrayList ret = new PersistentArrayList(this, this.count() + 10);
+ ret = ret.cons(o);
+ ret._meta = _meta;
+ return ret;
+}
+
public Obj withMeta(IPersistentMap meta) {
if(_meta == meta)
return this;
diff --git a/src/jvm/clojure/lang/Cons.java b/src/jvm/clojure/lang/Cons.java index aac9fe36..a69b4bcf 100644 --- a/src/jvm/clojure/lang/Cons.java +++ b/src/jvm/clojure/lang/Cons.java @@ -12,7 +12,7 @@ package clojure.lang; -public class Cons implements ISeq, IPersistentCollection { +public class Cons implements ISeq { private final Object _first; private final ISeq _rest; diff --git a/src/jvm/clojure/lang/IPersistentCollection.java b/src/jvm/clojure/lang/IPersistentCollection.java index d66901d8..cd4593df 100644 --- a/src/jvm/clojure/lang/IPersistentCollection.java +++ b/src/jvm/clojure/lang/IPersistentCollection.java @@ -14,6 +14,8 @@ package clojure.lang; public interface IPersistentCollection {
int count();
+
ISeq seq() throws Exception;
+IPersistentCollection cons(Object o);
}
diff --git a/src/jvm/clojure/lang/PersistentArray.java b/src/jvm/clojure/lang/PersistentArray.java index 2483c6bd..64130538 100644 --- a/src/jvm/clojure/lang/PersistentArray.java +++ b/src/jvm/clojure/lang/PersistentArray.java @@ -229,6 +229,18 @@ public PersistentArray(IArray init) { data.master.load = load; } +public PersistentArray(IArray init, int size) { + this(size); + int load = 0; + for(int i=0;i < init.length() && i < size;i++) + { + data.master.array[i] = new Entry(0,init.nth(i)); + ++load; + } + + data.master.load = load; +} + public int count(){ return data.master.array.length; } @@ -464,7 +476,7 @@ static public void main(String[] args){ { v.set(i, 0); //p = p.set(i, 0); - p = p.add(0); + p = p.cons(0); } Random rand; diff --git a/src/jvm/clojure/lang/PersistentArrayList.java b/src/jvm/clojure/lang/PersistentArrayList.java index a8aab7b6..eeb045b2 100644 --- a/src/jvm/clojure/lang/PersistentArrayList.java +++ b/src/jvm/clojure/lang/PersistentArrayList.java @@ -31,6 +31,11 @@ PersistentArrayList(int size, Object defaultVal, float loadFactor, int count) { this._count = count;
}
+public PersistentArrayList(IArray init, int initialCapacity){
+ super(init,initialCapacity);
+ _count = Math.min(init.count(),initialCapacity);
+}
+
public Object nth(int i) {
if(i >= _count)
throw new IndexOutOfBoundsException();
@@ -57,7 +62,7 @@ public int capacity(){ return data.master.array.length;
}
-public PersistentArrayList add(Object val) {
+public PersistentArrayList cons(Object val) {
if(_count == data.master.array.length) //full
{
synchronized(data.master){
diff --git a/src/jvm/clojure/lang/PersistentArrayMap.java b/src/jvm/clojure/lang/PersistentArrayMap.java index 8e1afb14..50343926 100644 --- a/src/jvm/clojure/lang/PersistentArrayMap.java +++ b/src/jvm/clojure/lang/PersistentArrayMap.java @@ -23,7 +23,7 @@ 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 PersistentArrayMap extends Obj implements IPersistentMap, IPersistentCollection, Cloneable {
+public class PersistentArrayMap extends APersistentMap {
final Object[] array;
static final int HASHTABLE_THRESHOLD = 42;
@@ -46,18 +46,6 @@ IPersistentMap createHT(Object[] init){ return ret;
}
-public Obj withMeta(IPersistentMap meta) {
- try{
- Obj ret = (Obj) clone();
- ret._meta = meta;
- return ret;
- }
- catch(CloneNotSupportedException ignore)
- {
- return null;
- }
-}
-
/**
* This ctor captures/aliases the passed array, so do not modify later
* @param init {key1,val1,key2,val2,...}
diff --git a/src/jvm/clojure/lang/PersistentHashtableMap.java b/src/jvm/clojure/lang/PersistentHashtableMap.java index 215f7b81..7ddf7e76 100644 --- a/src/jvm/clojure/lang/PersistentHashtableMap.java +++ b/src/jvm/clojure/lang/PersistentHashtableMap.java @@ -13,7 +13,7 @@ package clojure.lang; import java.util.Iterator;
import java.math.BigInteger;
-public class PersistentHashtableMap extends Obj implements IPersistentMap, Cloneable {
+public class PersistentHashtableMap extends APersistentMap {
static final float FILL_FACTOR = 0.75f;
@@ -54,18 +54,6 @@ PersistentHashtableMap(int count,PersistentArray array,int growAt) { this.growAtCount = growAt;
}
-public Obj withMeta(IPersistentMap meta) {
- try{
- Obj ret = (Obj) clone();
- ret._meta = meta;
- return ret;
- }
- catch(CloneNotSupportedException ignore)
- {
- return null;
- }
-}
-
int calcPrimeCapacity(int capacity) {
return BigInteger.valueOf((long) (capacity/FILL_FACTOR)).nextProbablePrime().intValue();
}
diff --git a/src/jvm/clojure/lang/PersistentListMap.java b/src/jvm/clojure/lang/PersistentListMap.java index 86ee24ca..5d00fd21 100644 --- a/src/jvm/clojure/lang/PersistentListMap.java +++ b/src/jvm/clojure/lang/PersistentListMap.java @@ -26,7 +26,7 @@ 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 extends Obj implements IPersistentMap, IMapEntry, ISeq, IPersistentCollection, Cloneable +public class PersistentListMap extends APersistentMap implements IMapEntry, ISeq { static public PersistentListMap EMPTY = new PersistentListMap(); @@ -35,18 +35,6 @@ static public PersistentListMap create(Object key, Object 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; } diff --git a/src/jvm/clojure/lang/PersistentTreeMap.java b/src/jvm/clojure/lang/PersistentTreeMap.java index 311ed7a4..f32ca7f7 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 extends Obj implements IPersistentMap, IPersistentCollection, Cloneable { +public class PersistentTreeMap extends APersistentMap { public final Comparator comp; public final Node tree; @@ -38,17 +38,6 @@ 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; diff --git a/src/jvm/clojure/lang/Tuple.java b/src/jvm/clojure/lang/Tuple.java index 3117227c..71ecaf8e 100644 --- a/src/jvm/clojure/lang/Tuple.java +++ b/src/jvm/clojure/lang/Tuple.java @@ -83,4 +83,6 @@ private boolean equalKey(Object k1,Object k2){ public ISeq seq() { return ArraySeq.create(array); } + + } |