summaryrefslogtreecommitdiff
path: root/src/cli
diff options
context:
space:
mode:
Diffstat (limited to 'src/cli')
-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
5 files changed, 130 insertions, 46 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;