diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/jvm/clojure/lang/LispReader.java | 98 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentHashMap.java | 13 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentVector.java | 9 | ||||
-rw-r--r-- | src/jvm/clojure/lang/RT.java | 2 |
4 files changed, 84 insertions, 38 deletions
diff --git a/src/jvm/clojure/lang/LispReader.java b/src/jvm/clojure/lang/LispReader.java index ed9210f1..cab54697 100644 --- a/src/jvm/clojure/lang/LispReader.java +++ b/src/jvm/clojure/lang/LispReader.java @@ -14,6 +14,7 @@ import java.io.*; import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.ArrayList;
+import java.util.List;
import java.math.BigInteger;
public class LispReader{
@@ -24,16 +25,16 @@ static Symbol UNQUOTE = Symbol.create(null, "unquote"); static Symbol UNQUOTE_SPLICING = Symbol.create(null, "unquote-splicing");
static IFn[] macros = new IFn[256];
-static Pattern symbolPat = Pattern.compile("[:]?[\\D&&[^:\\.]][^:\\.]*");
-static Pattern varPat = Pattern.compile("([\\D&&[^:\\.]][^:\\.]*):([\\D&&[^:\\.]][^:\\.]*)");
+static Pattern symbolPat = Pattern.compile("[:]?([\\D&&[^:/]][^:/]*/)?[\\D&&[^:/]][^:/]*");
+//static Pattern varPat = Pattern.compile("([\\D&&[^:\\.]][^:\\.]*):([\\D&&[^:\\.]][^:\\.]*)");
static Pattern intPat = Pattern.compile("[-+]?[0-9]+\\.?");
static Pattern ratioPat = Pattern.compile("([-+]?[0-9]+)/([0-9]+)");
static Pattern floatPat = Pattern.compile("[-+]?[0-9]+(\\.[0-9]+)?([eE][-+]?[0-9]+)?");
-static Pattern accessorPat = Pattern.compile("\\.[a-zA-Z_]\\w*");
-static Pattern instanceMemberPat = Pattern.compile("\\.([a-zA-Z_][\\w\\.]*)\\.([a-zA-Z_]\\w*)");
-static Pattern staticMemberPat = Pattern.compile("([a-zA-Z_][\\w\\.]*)\\.([a-zA-Z_]\\w*)");
-static Pattern classNamePat = Pattern.compile("([a-zA-Z_][\\w\\.]*)\\.");
+//static Pattern accessorPat = Pattern.compile("\\.[a-zA-Z_]\\w*");
+//static Pattern instanceMemberPat = Pattern.compile("\\.([a-zA-Z_][\\w\\.]*)\\.([a-zA-Z_]\\w*)");
+//static Pattern staticMemberPat = Pattern.compile("([a-zA-Z_][\\w\\.]*)\\.([a-zA-Z_]\\w*)");
+//static Pattern classNamePat = Pattern.compile("([a-zA-Z_][\\w\\.]*)\\.");
static
{
@@ -42,8 +43,13 @@ static macros['\''] = new QuoteReader();
macros['`'] = new BackquoteReader();
macros[','] = new UnquoteReader();
+ macros['^'] = new MetaReader();
macros['('] = new ListReader();
macros[')'] = new UnmatchedDelimiterReader();
+ macros['['] = new VectorReader();
+ macros[']'] = new UnmatchedDelimiterReader();
+ macros['{'] = new MapReader();
+ macros['}'] = new UnmatchedDelimiterReader();
macros['\\'] = new CharacterReader();
}
@@ -218,11 +224,11 @@ static private Object interpretToken(String s) throws Exception{ }
Object ret = null;
- ret = matchVar(s);
+ ret = matchSymbol(s);
if(ret != null)
return ret;
- return Symbol.intern(null, s);
+ throw new Exception("Invalid token: " + s);
}
/*
private static Object matchHostName(String s) {
@@ -250,12 +256,27 @@ private static Object matchSymbol(String s) { }
*/
+private static Object matchSymbol(String s){
+ Matcher m = symbolPat.matcher(s);
+ if(m.matches())
+ {
+ boolean isKeyword = s.charAt(0) == ':';
+ Symbol sym = Symbol.intern(s.substring(isKeyword ? 1 : 0));
+ if(isKeyword)
+ return new Keyword(sym);
+ return sym;
+ }
+ return null;
+}
+
+/*
private static Object matchVar(String s) throws Exception{
Matcher m = varPat.matcher(s);
if(m.matches())
return Module.intern(m.group(1), m.group(2));
return null;
}
+*/
private static Object matchNumber(String s){
Matcher m = intPat.matcher(s);
@@ -320,10 +341,6 @@ static class StringReader extends AFn{ }
return sb.toString();
}
-
- public Obj withMeta(IPersistentMap meta){
- throw new UnsupportedOperationException();
- }
}
static class CommentReader extends AFn{
@@ -337,9 +354,6 @@ static class CommentReader extends AFn{ return r;
}
- public Obj withMeta(IPersistentMap meta){
- throw new UnsupportedOperationException();
- }
}
static class QuoteReader extends AFn{
@@ -349,9 +363,23 @@ static class QuoteReader extends AFn{ return RT.list(QUOTE, o);
}
- public Obj withMeta(IPersistentMap meta){
- throw new UnsupportedOperationException();
+}
+
+static class MetaReader extends AFn{
+ public Object invoke(Object reader, Object caret) throws Exception{
+ PushbackReader r = (PushbackReader) reader;
+ Object meta = read(r, true, null, true);
+ if(meta instanceof Symbol || meta instanceof Keyword)
+ meta = RT.map(RT.TAG_KEY, meta);
+ 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);
+ else
+ throw new IllegalArgumentException("Metadata can only be applied to Objs");
}
+
}
static class BackquoteReader extends AFn{
@@ -361,10 +389,6 @@ static class BackquoteReader extends AFn{ return RT.list(BACKQUOTE, o);
}
- public Obj withMeta(IPersistentMap meta){
- throw new UnsupportedOperationException();
-
- }
}
static class UnquoteReader extends AFn{
@@ -386,10 +410,6 @@ static class UnquoteReader extends AFn{ }
}
- public Obj withMeta(IPersistentMap meta){
- throw new UnsupportedOperationException();
-
- }
}
static class CharacterReader extends AFn{
@@ -410,22 +430,30 @@ static class CharacterReader extends AFn{ throw new Exception("Unsupported character: \\" + token);
}
- public Obj withMeta(IPersistentMap meta){
- throw new UnsupportedOperationException();
+}
+static class ListReader extends AFn{
+ public Object invoke(Object reader, Object leftparen) throws Exception{
+ PushbackReader r = (PushbackReader) reader;
+ return RT.seq(readDelimitedList(')', r, true));
}
+
}
-static class ListReader extends AFn{
+static class VectorReader extends AFn{
public Object invoke(Object reader, Object leftparen) throws Exception{
PushbackReader r = (PushbackReader) reader;
- return readDelimitedList(')', r, true);
+ return PersistentVector.create(readDelimitedList(']', r, true));
}
- public Obj withMeta(IPersistentMap meta){
- throw new UnsupportedOperationException();
+}
+static class MapReader extends AFn{
+ public Object invoke(Object reader, Object leftparen) throws Exception{
+ PushbackReader r = (PushbackReader) reader;
+ return PersistentHashMap.create(readDelimitedList('}', r, true));
}
+
}
static class UnmatchedDelimiterReader extends AFn{
@@ -433,13 +461,9 @@ static class UnmatchedDelimiterReader extends AFn{ throw new Exception("Unmatched delimiter: " + rightdelim);
}
- public Obj withMeta(IPersistentMap meta){
- throw new UnsupportedOperationException();
-
- }
}
-public static ISeq readDelimitedList(char delim, PushbackReader r, boolean isRecursive) throws Exception{
+public static List readDelimitedList(char delim, PushbackReader r, boolean isRecursive) throws Exception{
ArrayList a = new ArrayList();
for(; ;)
@@ -474,7 +498,7 @@ public static ISeq readDelimitedList(char delim, PushbackReader r, boolean isRec }
- return RT.seq(a);
+ return a;
}
public static void main(String[] args){
diff --git a/src/jvm/clojure/lang/PersistentHashMap.java b/src/jvm/clojure/lang/PersistentHashMap.java index f8534bf5..e4c99512 100644 --- a/src/jvm/clojure/lang/PersistentHashMap.java +++ b/src/jvm/clojure/lang/PersistentHashMap.java @@ -47,6 +47,19 @@ public static IPersistentMap create(Object... init){ return ret; } +public static IPersistentMap create(List init){ + IPersistentMap ret = EMPTY; + for(Iterator i = init.iterator(); i.hasNext();) + { + Object key = i.next(); + if(!i.hasNext()) + throw new IllegalArgumentException(String.format("No value supplied for key: %s", key)); + Object val = i.next(); + ret = ret.assoc(key, val); + } + return ret; +} + /* * @param init {key1,val1,key2,val2,...} */ diff --git a/src/jvm/clojure/lang/PersistentVector.java b/src/jvm/clojure/lang/PersistentVector.java index f99bac02..736c5795 100644 --- a/src/jvm/clojure/lang/PersistentVector.java +++ b/src/jvm/clojure/lang/PersistentVector.java @@ -14,6 +14,7 @@ package clojure.lang; import java.util.Vector; import java.util.Random; +import java.util.List; public class PersistentVector extends Obj implements IPersistentArray, IPersistentList{ final int cnt; @@ -32,6 +33,14 @@ static public PersistentVector create(ISeq items){ return ret; } +static public PersistentVector create(List items){ + //todo - consider building tree directly + PersistentVector ret = EMPTY; + for(Object item : items) + ret = ret.cons(item); + return ret; +} + /** * This ctor may capture/alias the passed array, so do not modify later ! */ diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java index 8a65dfdc..b950cdf6 100644 --- a/src/jvm/clojure/lang/RT.java +++ b/src/jvm/clojure/lang/RT.java @@ -516,7 +516,7 @@ static public void print(Object x, Writer w) throws Exception{ if(o.meta() != null) { IPersistentMap meta = o.meta(); - w.write("#^"); + w.write("^"); if(meta.count() == 1 && meta.contains(TAG_KEY)) print(meta.valAt(TAG_KEY), w); else |