diff options
author | Rich Hickey <richhickey@gmail.com> | 2007-08-19 17:10:29 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2007-08-19 17:10:29 +0000 |
commit | f12a76d3063e4a024b1e67a63c4f9fc12d168088 (patch) | |
tree | 04cae67af4dcf618ef270be752f02b23cffc9b01 /src | |
parent | 92075ac2c07da8a76bb3b07db4e59c8f7a10d915 (diff) |
added ArgVector, commas as whitespace, commas in Map print
Diffstat (limited to 'src')
-rw-r--r-- | src/jvm/clojure/lang/ArgVector.java | 97 | ||||
-rw-r--r-- | src/jvm/clojure/lang/LispReader.java | 37 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentList.java | 12 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentVector.java | 2 | ||||
-rw-r--r-- | src/jvm/clojure/lang/RT.java | 15 |
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('}'); } |