summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2007-08-19 17:10:29 +0000
committerRich Hickey <richhickey@gmail.com>2007-08-19 17:10:29 +0000
commitf12a76d3063e4a024b1e67a63c4f9fc12d168088 (patch)
tree04cae67af4dcf618ef270be752f02b23cffc9b01 /src
parent92075ac2c07da8a76bb3b07db4e59c8f7a10d915 (diff)
added ArgVector, commas as whitespace, commas in Map print
Diffstat (limited to 'src')
-rw-r--r--src/jvm/clojure/lang/ArgVector.java97
-rw-r--r--src/jvm/clojure/lang/LispReader.java37
-rw-r--r--src/jvm/clojure/lang/PersistentList.java12
-rw-r--r--src/jvm/clojure/lang/PersistentVector.java2
-rw-r--r--src/jvm/clojure/lang/RT.java15
5 files changed, 151 insertions, 12 deletions
diff --git a/src/jvm/clojure/lang/ArgVector.java b/src/jvm/clojure/lang/ArgVector.java
new file mode 100644
index 00000000..699662ed
--- /dev/null
+++ b/src/jvm/clojure/lang/ArgVector.java
@@ -0,0 +1,97 @@
+/**
+ * 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.
+ **/
+
+/* rich Aug 19, 2007 */
+
+package clojure.lang;
+
+import java.util.List;
+
+public class ArgVector extends Obj implements IPersistentArray, IPersistentList{
+
+final PersistentVector impl;
+
+public static final ArgVector EMPTY = new ArgVector(PersistentVector.EMPTY);
+
+static public ArgVector create(ISeq items){
+ return new ArgVector(PersistentVector.create(items));
+}
+
+static public ArgVector create(List items){
+ return new ArgVector(PersistentVector.create(items));
+}
+
+static public ArgVector create(Object... items){
+ return new ArgVector(PersistentVector.create(items));
+}
+
+private ArgVector(PersistentVector impl){
+ this.impl = impl;
+}
+
+private ArgVector(IPersistentMap meta, PersistentVector impl){
+ super(meta);
+ this.impl = impl;
+}
+
+public Obj withMeta(IPersistentMap meta){
+ if(meta != this.meta())
+ return new ArgVector(meta, impl);
+ return this;
+}
+
+public int length(){
+ return impl.length();
+}
+
+public Object nth(int i){
+ return impl.nth(i);
+}
+
+public IPersistentArray assocN(int i, Object val){
+ return new ArgVector(meta(), impl.assocN(i, val));
+}
+
+public boolean contains(Object key){
+ return impl.contains(key);
+}
+
+public IMapEntry entryAt(Object key){
+ return impl.entryAt(key);
+}
+
+public Associative assoc(Object key, Object val){
+ return new ArgVector(meta(), impl.assoc(key, val));
+}
+
+public Object valAt(Object key){
+ return impl.valAt(key);
+}
+
+public int count(){
+ return impl.count();
+}
+
+public ISeq seq(){
+ return impl.seq();
+}
+
+public IPersistentCollection cons(Object o){
+ return new ArgVector(meta(), impl.cons(o));
+}
+
+public Object peek(){
+ return impl.peek();
+}
+
+public IPersistentList pop(){
+ return new ArgVector(meta(), impl.pop());
+}
+}
diff --git a/src/jvm/clojure/lang/LispReader.java b/src/jvm/clojure/lang/LispReader.java
index cab54697..3556fbe9 100644
--- a/src/jvm/clojure/lang/LispReader.java
+++ b/src/jvm/clojure/lang/LispReader.java
@@ -42,7 +42,7 @@ static
macros[';'] = new CommentReader();
macros['\''] = new QuoteReader();
macros['`'] = new BackquoteReader();
- macros[','] = new UnquoteReader();
+ macros['~'] = new UnquoteReader();
macros['^'] = new MetaReader();
macros['('] = new ListReader();
macros[')'] = new UnmatchedDelimiterReader();
@@ -50,9 +50,14 @@ static
macros[']'] = new UnmatchedDelimiterReader();
macros['{'] = new MapReader();
macros['}'] = new UnmatchedDelimiterReader();
+ macros['|'] = new ArgVectorReader();
macros['\\'] = new CharacterReader();
}
+static boolean isWhitespace(int ch){
+ return Character.isWhitespace(ch) || ch == ',';
+}
+
static public Object read(PushbackReader r, boolean eofIsError, Object eofValue, boolean isRecursive)
throws Exception{
@@ -60,7 +65,7 @@ static public Object read(PushbackReader r, boolean eofIsError, Object eofValue,
{
int ch = r.read();
- while(Character.isWhitespace(ch))
+ while(isWhitespace(ch))
ch = r.read();
if(ch == -1)
@@ -118,7 +123,7 @@ static private String readToken(PushbackReader r, char initch) throws Exception{
for(; ;)
{
int ch = r.read();
- if(ch == -1 || Character.isWhitespace(ch) || isMacro(ch))
+ if(ch == -1 || isWhitespace(ch) || isMacro(ch))
{
r.unread(ch);
return sb.toString();
@@ -134,7 +139,7 @@ static private Object readNumber(PushbackReader r, char initch) throws Exception
for(; ;)
{
int ch = r.read();
- if(ch == -1 || Character.isWhitespace(ch) || isMacro(ch))
+ if(ch == -1 || isWhitespace(ch) || isMacro(ch))
{
r.unread(ch);
break;
@@ -374,10 +379,10 @@ static class MetaReader extends AFn{
else if(!(meta instanceof IPersistentMap))
throw new IllegalArgumentException("Metadata must be Symbol,Keyword or Map");
Object o = read(r, true, null, true);
- if(o instanceof Obj)
- return ((Obj) o).withMeta((IPersistentMap) meta);
+ if(o instanceof IObj)
+ return ((IObj) o).withMeta((IPersistentMap) meta);
else
- throw new IllegalArgumentException("Metadata can only be applied to Objs");
+ throw new IllegalArgumentException("Metadata can only be applied to IObjs");
}
}
@@ -435,7 +440,18 @@ static class CharacterReader extends AFn{
static class ListReader extends AFn{
public Object invoke(Object reader, Object leftparen) throws Exception{
PushbackReader r = (PushbackReader) reader;
- return RT.seq(readDelimitedList(')', r, true));
+ List list = readDelimitedList(')', r, true);
+ if(list.isEmpty())
+ return PersistentList.EMPTY;
+ return RT.seq(list);
+ }
+
+}
+
+static class ArgVectorReader extends AFn{
+ public Object invoke(Object reader, Object leftparen) throws Exception{
+ PushbackReader r = (PushbackReader) reader;
+ return ArgVector.create(readDelimitedList('|', r, true));
}
}
@@ -470,7 +486,7 @@ public static List readDelimitedList(char delim, PushbackReader r, boolean isRec
{
int ch = r.read();
- while(Character.isWhitespace(ch))
+ while(isWhitespace(ch))
ch = r.read();
if(ch == -1)
@@ -512,7 +528,8 @@ public static void main(String[] args){
ret = LispReader.read(r, true, null, false);
RT.print(ret, w);
w.write('\n');
- w.write(ret.getClass().toString());
+ if(ret != null)
+ w.write(ret.getClass().toString());
w.write('\n');
w.flush();
}
diff --git a/src/jvm/clojure/lang/PersistentList.java b/src/jvm/clojure/lang/PersistentList.java
index c597fb33..c7331ef5 100644
--- a/src/jvm/clojure/lang/PersistentList.java
+++ b/src/jvm/clojure/lang/PersistentList.java
@@ -10,6 +10,9 @@
package clojure.lang;
+import java.util.List;
+import java.util.ListIterator;
+
public class PersistentList extends ASeq{
private final Object _first;
@@ -39,6 +42,15 @@ PersistentList(IPersistentMap meta, Object _first, PersistentList _rest, int _co
this._count = _count;
}
+public static ISeq create(List init){
+ ISeq ret = EMPTY;
+ for(ListIterator i = init.listIterator(init.size()); i.hasPrevious();)
+ {
+ ret = ret.cons(i.previous());
+ }
+ return ret;
+}
+
public Object first(){
return _first;
}
diff --git a/src/jvm/clojure/lang/PersistentVector.java b/src/jvm/clojure/lang/PersistentVector.java
index 736c5795..d572bffa 100644
--- a/src/jvm/clojure/lang/PersistentVector.java
+++ b/src/jvm/clojure/lang/PersistentVector.java
@@ -343,7 +343,7 @@ public IMapEntry entryAt(Object key){
return null;
}
-public Associative assoc(Object key, Object val){
+public PersistentVector assoc(Object key, Object val){
if(key instanceof Number)
{
int i = ((Number) key).intValue();
diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java
index b950cdf6..9098124f 100644
--- a/src/jvm/clojure/lang/RT.java
+++ b/src/jvm/clojure/lang/RT.java
@@ -279,6 +279,13 @@ static public Iter iter(Object coll){
throw new IllegalArgumentException("Don't know how to create Iter from arg");
}
+static boolean hasTag(Object o, Object tag){
+ if(!(o instanceof IObj))
+ return false;
+ IPersistentMap meta = ((IObj) o).meta();
+ return RT.equal(tag, RT.get(TAG_KEY, meta));
+}
+
/**
* ********************* Boxing/casts ******************************
*/
@@ -538,6 +545,12 @@ static public void print(Object x, Writer w) throws Exception{
w.write(x.toString());
w.write('"');
}
+ else if(x instanceof ArgVector)
+ {
+ w.write('|');
+ printInnerSeq(seq(x), w);
+ w.write('|');
+ }
else if(x instanceof IPersistentMap)
{
w.write('{');
@@ -548,7 +561,7 @@ static public void print(Object x, Writer w) throws Exception{
w.write(' ');
print(e.val(), w);
if(s.rest() != null)
- w.write(' ');
+ w.write(", ");
}
w.write('}');
}