summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2006-08-05 19:24:17 +0000
committerRich Hickey <richhickey@gmail.com>2006-08-05 19:24:17 +0000
commit397f768ca30a4615c753ec544dedc5c39be7743b (patch)
tree00dd0db8e2efb38df35f942e108eab721887c457 /src
parenta619d3a6f9cde068d0945ab26b275113c8ffde1b (diff)
added PersistentList, changed RT.cons to work with all collections
Diffstat (limited to 'src')
-rw-r--r--src/cli/runtime/ASeq.cs23
-rw-r--r--src/cli/runtime/LispReader.cs5
-rw-r--r--src/cli/runtime/PersistentList.cs55
-rw-r--r--src/cli/runtime/PersistentListMap.cs47
-rw-r--r--src/cli/runtime/RT.cs46
-rw-r--r--src/jvm/clojure/lang/ASeq.java20
-rw-r--r--src/jvm/clojure/lang/ISeq.java3
-rw-r--r--src/jvm/clojure/lang/LispReader.java6
-rw-r--r--src/jvm/clojure/lang/PersistentList.java50
-rw-r--r--src/jvm/clojure/lang/PersistentListMap.java41
-rw-r--r--src/jvm/clojure/lang/RT.java52
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;
}