diff options
author | Rich Hickey <richhickey@gmail.com> | 2006-08-05 19:24:17 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2006-08-05 19:24:17 +0000 |
commit | 397f768ca30a4615c753ec544dedc5c39be7743b (patch) | |
tree | 00dd0db8e2efb38df35f942e108eab721887c457 /src | |
parent | a619d3a6f9cde068d0945ab26b275113c8ffde1b (diff) |
added PersistentList, changed RT.cons to work with all collections
Diffstat (limited to 'src')
-rw-r--r-- | src/cli/runtime/ASeq.cs | 23 | ||||
-rw-r--r-- | src/cli/runtime/LispReader.cs | 5 | ||||
-rw-r--r-- | src/cli/runtime/PersistentList.cs | 55 | ||||
-rw-r--r-- | src/cli/runtime/PersistentListMap.cs | 47 | ||||
-rw-r--r-- | src/cli/runtime/RT.cs | 46 | ||||
-rw-r--r-- | src/jvm/clojure/lang/ASeq.java | 20 | ||||
-rw-r--r-- | src/jvm/clojure/lang/ISeq.java | 3 | ||||
-rw-r--r-- | src/jvm/clojure/lang/LispReader.java | 6 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentList.java | 50 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentListMap.java | 41 | ||||
-rw-r--r-- | src/jvm/clojure/lang/RT.java | 52 |
11 files changed, 257 insertions, 91 deletions
diff --git a/src/cli/runtime/ASeq.cs b/src/cli/runtime/ASeq.cs index 9636e80b..18c307d6 100644 --- a/src/cli/runtime/ASeq.cs +++ b/src/cli/runtime/ASeq.cs @@ -13,25 +13,34 @@ using System; namespace clojure.lang
{
-public abstract class ASeq : ISeq{
-
-public Object peek() {
+public abstract class ASeq : Obj, ISeq{
+
+ public override Obj withMeta(IPersistentMap meta)
+ {
+ if(_meta == meta)
+ return this;
+ Obj ret = (Obj)MemberwiseClone();
+ ret._meta = meta;
+ return ret;
+ }
+
+public virtual Object peek() {
return first();
}
-public IPersistentList pop() {
+public virtual IPersistentList pop() {
return rest();
}
-public int count() {
+public virtual int count() {
return 1 + RT.count(rest());
}
-public ISeq seq() {
+public virtual ISeq seq() {
return this;
}
-public IPersistentCollection cons(Object o) {
+public virtual IPersistentCollection cons(Object o) {
return new Cons(o, this);
}
diff --git a/src/cli/runtime/LispReader.cs b/src/cli/runtime/LispReader.cs index 36c47d3a..35b3b0b8 100644 --- a/src/cli/runtime/LispReader.cs +++ b/src/cli/runtime/LispReader.cs @@ -292,10 +292,7 @@ public static ISeq readDelimitedList(char delim, LineNumberingTextReader r, bool }
}
- ISeq ret = null;
- for(int i=a.Count-1;i>=0;--i)
- ret = RT.cons(a[i], ret);
- return ret;
+ return RT.seq(a);
}
/*
diff --git a/src/cli/runtime/PersistentList.cs b/src/cli/runtime/PersistentList.cs new file mode 100644 index 00000000..dbe4412c --- /dev/null +++ b/src/cli/runtime/PersistentList.cs @@ -0,0 +1,55 @@ +/**
+ * 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;
+ +namespace clojure.lang
+{ +
+public class PersistentList : ASeq {
+
+private readonly Object _first;
+private readonly PersistentList _rest;
+private readonly int _count;
+
+public PersistentList(Object first) {
+ this._first = first;
+ this._rest = null;
+
+ this._count = 1;
+}
+
+private PersistentList(Object first, PersistentList rest) {
+ this._first = first;
+ this._rest = rest;
+
+ this._count = 1 + rest.count();
+ this._meta = rest._meta;
+}
+
+override public Object first() {
+ return _first;
+}
+
+override public ISeq rest() {
+ return _rest;
+}
+
+override public int count() {
+ return _count;
+}
+
+override public IPersistentCollection cons(Object o) {
+ return new PersistentList(o,this);
+}
+
+}
+
+}
diff --git a/src/cli/runtime/PersistentListMap.cs b/src/cli/runtime/PersistentListMap.cs index 272ca299..e632a67a 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 : APersistentMap, IMapEntry, ISeq
+public class PersistentListMap : APersistentMap, IMapEntry
{
static public PersistentListMap EMPTY = new PersistentListMap();
@@ -218,19 +218,25 @@ internal class Tail : PersistentListMap { return this;
}
- override public Object first()
- {
- return this;
- }
+ class Seq : ASeq{
+ Tail t;
- override public ISeq rest()
- {
- return null;
- }
+ public Seq(Tail t) {
+ this.t = t;
+ }
+ override public Object first()
+ {
+ return t;
+ }
+ override public ISeq rest()
+ {
+ return null;
+ }
+ }
override public ISeq seq()
{
- return this;
+ return new Seq(this);
}
}
@@ -317,20 +323,25 @@ internal class Link : PersistentListMap { return null;
}
+ class Seq : ASeq{
+ Link lnk;
- override public Object first()
- {
- return this;
- }
+ public Seq(Link lnk) {
+ this.lnk = lnk;
+ }
- override public ISeq rest()
- {
- return _rest;
+ override public Object first() {
+ return lnk;
+ }
+
+ override public ISeq rest() {
+ return lnk._rest.seq();
+ }
}
override public ISeq seq()
{
- return this;
+ return new Seq(this);
}
PersistentListMap create(Object k, Object v, IPersistentMap r)
diff --git a/src/cli/runtime/RT.cs b/src/cli/runtime/RT.cs index 75d581f2..2d7e765e 100644 --- a/src/cli/runtime/RT.cs +++ b/src/cli/runtime/RT.cs @@ -179,10 +179,22 @@ static public ISeq seq(Object coll) { static public double doubleCast(Object x)
{
return Convert.ToDouble(x);
- }
-static public Cons cons(Object x, Object y) {
-return new Cons(x, seq(y));
-}
+ }
+
+static public IPersistentCollection cons(Object x, IPersistentCollection y)
+ {
+ if (y == null)
+ return new PersistentList(x);
+ return y.cons(x);
+ }
+
+static public ISeq cons(Object x, ISeq y)
+ {
+ if (y == null)
+ return new PersistentList(x);
+ return (ISeq)y.cons(x);
+ }
+
static public Object first(Object x) {
return seq(x).first();
@@ -192,64 +204,64 @@ static public ISeq rest(Object x) { return seq(x).rest();
}
-static public Cons list()
+static public ISeq list()
{
return null;
}
-static public Cons list(Object arg1)
+static public ISeq list(Object arg1)
{
return cons(arg1, null);
}
-static public Cons list(Object arg1, Object arg2)
+static public ISeq list(Object arg1, Object arg2)
{
return listStar(arg1, arg2, null);
}
-static public Cons list(Object arg1, Object arg2, Object arg3)
+static public ISeq list(Object arg1, Object arg2, Object arg3)
{
return listStar(arg1, arg2, arg3, null);
}
-static public Cons list(Object arg1, Object arg2, Object arg3, Object arg4)
+static public ISeq list(Object arg1, Object arg2, Object arg3, Object arg4)
{
return listStar(arg1, arg2, arg3, arg4, null);
}
-static public Cons list(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5)
+static public ISeq list(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5)
{
return listStar(arg1, arg2, arg3, arg4, arg5, null);
}
-static public Cons listStar(Object arg1, ISeq rest)
+static public ISeq listStar(Object arg1, ISeq rest)
{
return cons(arg1, rest);
}
-static public Cons listStar(Object arg1, Object arg2, ISeq rest)
+static public ISeq listStar(Object arg1, Object arg2, ISeq rest)
{
return cons(arg1, cons(arg2, rest));
}
-static public Cons listStar(Object arg1, Object arg2, Object arg3, ISeq rest)
+static public ISeq listStar(Object arg1, Object arg2, Object arg3, ISeq rest)
{
return cons(arg1, cons(arg2, cons(arg3, rest)));
}
-static public Cons listStar(Object arg1, Object arg2, Object arg3, Object arg4, ISeq rest)
+static public ISeq listStar(Object arg1, Object arg2, Object arg3, Object arg4, ISeq rest)
{
return cons(arg1, cons(arg2, cons(arg3, cons(arg4, rest))));
}
-static public Cons listStar(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, ISeq rest)
+static public ISeq listStar(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, ISeq rest)
{
return cons(arg1, cons(arg2, cons(arg3, cons(arg4, cons(arg5, rest)))));
}
-static public Cons arrayToList(Object[] a)
+static public ISeq arrayToList(Object[] a)
{
- Cons ret = null;
+ ISeq ret = null;
for (int i = a.Length - 1; i >= 0; --i)
ret = cons(a[i], ret);
return ret;
diff --git a/src/jvm/clojure/lang/ASeq.java b/src/jvm/clojure/lang/ASeq.java index 272b6e5e..3d2168d4 100644 --- a/src/jvm/clojure/lang/ASeq.java +++ b/src/jvm/clojure/lang/ASeq.java @@ -10,7 +10,7 @@ package clojure.lang;
-public abstract class ASeq implements ISeq{
+public abstract class ASeq extends Obj implements ISeq{
public Object peek() {
return first();
@@ -28,7 +28,23 @@ public ISeq seq() { return this;
}
-public IPersistentCollection cons(Object o) {
+public ISeq cons(Object o) {
return new Cons(o, this);
}
+
+
+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/ISeq.java b/src/jvm/clojure/lang/ISeq.java index ff6e325f..52f0d5d2 100644 --- a/src/jvm/clojure/lang/ISeq.java +++ b/src/jvm/clojure/lang/ISeq.java @@ -21,4 +21,7 @@ public interface ISeq extends IPersistentList{ Object first() ;
ISeq rest() ;
+
+ISeq cons(Object o);
+
}
diff --git a/src/jvm/clojure/lang/LispReader.java b/src/jvm/clojure/lang/LispReader.java index ce0d2980..f04e9821 100644 --- a/src/jvm/clojure/lang/LispReader.java +++ b/src/jvm/clojure/lang/LispReader.java @@ -286,10 +286,8 @@ public static ISeq readDelimitedList(char delim, PushbackReader r, boolean isRec }
}
- ISeq ret = null;
- for(int i=a.size()-1;i>=0;--i)
- ret = RT.cons(a.get(i), ret);
- return ret;
+
+ return RT.seq(a);
}
public static void main(String[] args){
diff --git a/src/jvm/clojure/lang/PersistentList.java b/src/jvm/clojure/lang/PersistentList.java new file mode 100644 index 00000000..22424e0c --- /dev/null +++ b/src/jvm/clojure/lang/PersistentList.java @@ -0,0 +1,50 @@ +/**
+ * 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 class PersistentList extends ASeq {
+
+private final Object _first;
+private final PersistentList _rest;
+private final int _count;
+
+public PersistentList(Object first) {
+ this._first = first;
+ this._rest = null;
+
+ this._count = 1;
+}
+
+private PersistentList(Object first, PersistentList rest) {
+ this._first = first;
+ this._rest = rest;
+
+ this._count = 1 + rest.count();
+ this._meta = rest._meta;
+}
+
+public Object first() {
+ return _first;
+}
+
+public ISeq rest() {
+ return _rest;
+}
+
+public int count() {
+ return _count;
+}
+
+public ISeq cons(Object o) {
+ return new PersistentList(o,this);
+}
+
+}
diff --git a/src/jvm/clojure/lang/PersistentListMap.java b/src/jvm/clojure/lang/PersistentListMap.java index 175e10d8..f32b25e6 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 APersistentMap implements IMapEntry, ISeq +public class PersistentListMap extends APersistentMap implements IMapEntry { static public PersistentListMap EMPTY = new PersistentListMap(); @@ -150,10 +150,6 @@ static class Tail extends PersistentListMap { return null; } - public int capacity(){ - return 1; - } - public Object key(){ return _key; } @@ -199,17 +195,24 @@ static class Tail extends PersistentListMap { } return this; } + static class Seq extends ASeq{ + Tail t; - public Object first() { - return this; + public Seq(Tail t) { + this.t = t; + } + + public Object first() { + return t; } public ISeq rest() { return null; } + } public ISeq seq() { - return this; + return new Seq(this); } } @@ -294,20 +297,24 @@ static class Link extends PersistentListMap { return null; } - public int capacity(){ - return count(); - } + static class Seq extends ASeq{ + Link lnk; - public Object first() { - return this; - } + public Seq(Link lnk) { + this.lnk = lnk; + } - public ISeq rest() { - return _rest; + public Object first() { + return lnk; + } + + public ISeq rest() { + return lnk._rest.seq(); + } } public ISeq seq() { - return this; + return new Seq(this); } PersistentListMap create(Object k,Object v,PersistentListMap r){ diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java index 4d3a8c75..ce89b096 100644 --- a/src/jvm/clojure/lang/RT.java +++ b/src/jvm/clojure/lang/RT.java @@ -193,8 +193,16 @@ static public double doubleCast(Object x) /******************************************* list support ********************************/ -static public Cons cons(Object x, Object y) { -return new Cons(x, seq(y)); +static public IPersistentCollection cons(Object x, IPersistentCollection y) { + if(y == null) + return new PersistentList(x); + return y.cons(x); +} + +static public ISeq cons(Object x, ISeq y) { + if(y == null) + return new PersistentList(x); + return y.cons(x); } static public Object first(Object x) { @@ -205,55 +213,55 @@ static public ISeq rest(Object x) { return seq(x).rest(); } -static public Cons list() +static public ISeq list() { return null; } -static public Cons list(Object arg1) throws Exception { -return cons(arg1, null); +static public ISeq list(Object arg1) throws Exception { + return new PersistentList(arg1); } -static public Cons list(Object arg1, Object arg2) throws Exception { +static public ISeq list(Object arg1, Object arg2) throws Exception { return listStar(arg1, arg2, null); } -static public Cons list(Object arg1, Object arg2, Object arg3) throws Exception { +static public ISeq list(Object arg1, Object arg2, Object arg3) throws Exception { return listStar(arg1, arg2, arg3, null); } -static public Cons list(Object arg1, Object arg2, Object arg3, Object arg4) throws Exception { +static public ISeq list(Object arg1, Object arg2, Object arg3, Object arg4) throws Exception { return listStar(arg1, arg2, arg3, arg4, null); } -static public Cons list(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) throws Exception { +static public ISeq list(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) throws Exception { return listStar(arg1, arg2, arg3, arg4, arg5, null); } -static public Cons listStar(Object arg1, ISeq rest) throws Exception { -return cons(arg1, rest); +static public ISeq listStar(Object arg1, ISeq rest) throws Exception { +return (ISeq) cons(arg1, rest); } -static public Cons listStar(Object arg1, Object arg2, ISeq rest) throws Exception { -return cons(arg1, cons(arg2, rest)); +static public ISeq listStar(Object arg1, Object arg2, ISeq rest) throws Exception { +return (ISeq) cons(arg1, cons(arg2, rest)); } -static public Cons listStar(Object arg1, Object arg2, Object arg3, ISeq rest) throws Exception { -return cons(arg1, cons(arg2, cons(arg3, rest))); +static public ISeq listStar(Object arg1, Object arg2, Object arg3, ISeq rest) throws Exception { +return (ISeq) cons(arg1, cons(arg2, cons(arg3, rest))); } -static public Cons listStar(Object arg1, Object arg2, Object arg3, Object arg4, ISeq rest) throws Exception { -return cons(arg1, cons(arg2, cons(arg3, cons(arg4, rest)))); +static public ISeq listStar(Object arg1, Object arg2, Object arg3, Object arg4, ISeq rest) throws Exception { +return (ISeq) cons(arg1, cons(arg2, cons(arg3, cons(arg4, rest)))); } -static public Cons listStar(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, ISeq rest) throws Exception { -return cons(arg1, cons(arg2, cons(arg3, cons(arg4, cons(arg5, rest))))); +static public ISeq listStar(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, ISeq rest) throws Exception { +return (ISeq) cons(arg1, cons(arg2, cons(arg3, cons(arg4, cons(arg5, rest))))); } -static public Cons arrayToList(Object[] a) throws Exception { - Cons ret = null; +static public ISeq arrayToList(Object[] a) throws Exception { + ISeq ret = null; for(int i=a.length-1;i>=0;--i) - ret = cons(a[i], ret); + ret = (ISeq) cons(a[i], ret); return ret; } |