summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2006-06-13 19:55:28 +0000
committerRich Hickey <richhickey@gmail.com>2006-06-13 19:55:28 +0000
commita6945186568b8265f775e448778255d16daba8db (patch)
tree014599db28e94c6462f1feb43fe188d556cddf1c
parent4ff27c7aa3347471e4f8372e4939d192b93ccfd3 (diff)
interim checkin - more work on reader
-rw-r--r--src/jvm/clojure/lang/ClassName.java19
-rw-r--r--src/jvm/clojure/lang/InstanceMemberName.java21
-rw-r--r--src/jvm/clojure/lang/LispReader.java99
-rw-r--r--src/jvm/clojure/lang/RT.java10
-rw-r--r--src/jvm/clojure/lang/StaticMemberName.java22
5 files changed, 165 insertions, 6 deletions
diff --git a/src/jvm/clojure/lang/ClassName.java b/src/jvm/clojure/lang/ClassName.java
new file mode 100644
index 00000000..d039cd5e
--- /dev/null
+++ b/src/jvm/clojure/lang/ClassName.java
@@ -0,0 +1,19 @@
+/**
+ * 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 ClassName {
+final public String className;
+
+public ClassName(String className) {
+ this.className = className;
+}
+}
diff --git a/src/jvm/clojure/lang/InstanceMemberName.java b/src/jvm/clojure/lang/InstanceMemberName.java
new file mode 100644
index 00000000..b0f8ff4b
--- /dev/null
+++ b/src/jvm/clojure/lang/InstanceMemberName.java
@@ -0,0 +1,21 @@
+/**
+ * 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 InstanceMemberName {
+final public String className;
+final public String memberName;
+
+public InstanceMemberName(String className, String memberName) {
+ this.className = className;
+ this.memberName = memberName;
+}
+}
diff --git a/src/jvm/clojure/lang/LispReader.java b/src/jvm/clojure/lang/LispReader.java
index 4c25b3ad..a36775c0 100644
--- a/src/jvm/clojure/lang/LispReader.java
+++ b/src/jvm/clojure/lang/LispReader.java
@@ -11,6 +11,7 @@
package clojure.lang;
import java.io.InputStreamReader;
+import java.io.Reader;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.math.BigInteger;
@@ -18,12 +19,21 @@ import java.math.BigInteger;
public class LispReader {
static IFn[] macros = new IFn[256];
-static Pattern symPat = Pattern.compile("[:]?[\\D&&[^:]][^:]*");
-static Pattern varPat = Pattern.compile("([\\D&&[^:]][^:]*):([\\D&&[^:]][^:]*)");
+static Pattern symbolPat = Pattern.compile("[:]?[\\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{
+macros['"'] = new StringReader();
+macros[';'] = new CommentReader();
+}
static public Object read(LineNumberingPushbackReader r, boolean eofIsError, Object eofValue, boolean isRecursive)
throws Exception {
@@ -45,17 +55,22 @@ static public Object read(LineNumberingPushbackReader r, boolean eofIsError, Obj
if (macroFn != null)
{
Object ret = macroFn.invoke(r, ch);
+ if(RT.suppressRead())
+ return null;
//no op macros return the reader
if (ret == r)
continue;
return ret;
}
- return readToken(r,ch);
+ String token = readToken(r,ch);
+ if(RT.suppressRead())
+ return null;
+ return interpretToken(token);
}
}
-static private Object readToken(LineNumberingPushbackReader r, int initch) throws Exception {
+static private String readToken(LineNumberingPushbackReader r, int initch) throws Exception {
StringBuilder sb = new StringBuilder();
sb.append((char)initch);
@@ -65,7 +80,7 @@ static private Object readToken(LineNumberingPushbackReader r, int initch) throw
if(ch == -1 || Character.isWhitespace(ch) || isMacro(ch))
{
r.unread(ch);
- return interpretToken(sb.toString());
+ return sb.toString();
}
sb.append((char)ch);
}
@@ -86,12 +101,33 @@ static private Object interpretToken(String s) {
ret = matchNumber(s);
if(ret != null)
return ret;
+ ret = matchHostName(s);
+ if(ret != null)
+ return ret;
+
throw new IllegalArgumentException("Invalid syntax: " + s);
}
+private static Object matchHostName(String s) {
+ Matcher m = accessorPat.matcher(s);
+ if(m.matches())
+ return new Accessor(s);
+ m = classNamePat.matcher(s);
+ if(m.matches())
+ return new ClassName(RT.resolveClassNameInContext(m.group(1)));
+ m = instanceMemberPat.matcher(s);
+ if(m.matches())
+ return new InstanceMemberName(RT.resolveClassNameInContext(m.group(1)),m.group(2));
+ m = staticMemberPat.matcher(s);
+ if(m.matches())
+ return new StaticMemberName(RT.resolveClassNameInContext(m.group(1)),m.group(2));
+
+ return null;
+}
+
private static Object matchSymbol(String s) {
- Matcher m = symPat.matcher(s);
+ Matcher m = symbolPat.matcher(s);
if(m.matches())
return Symbol.intern(s);
return null;
@@ -145,5 +181,56 @@ public static void main(String[] args){
e.printStackTrace();
}
}
+
+static class StringReader extends AFn{
+ public Object invoke(Object reader, Object doublequote) throws Exception {
+ StringBuilder sb = new StringBuilder();
+ Reader r = (Reader) reader;
+
+ for(int ch = r.read();ch != '"';ch = r.read())
+ {
+ if(ch == -1)
+ throw new Exception("EOF while reading string");
+ if(ch == '\\') //escape
+ {
+ ch = r.read();
+ if(ch == -1)
+ throw new Exception("EOF while reading string");
+ switch(ch)
+ {
+ case 't':
+ ch = '\t';
+ break;
+ case 'r':
+ ch = '\r';
+ break;
+ case 'n':
+ ch = '\n';
+ break;
+ case '\\':
+ break;
+ case '"':
+ break;
+ default:
+ throw new Exception("Unsupported escape character: \\" + (char)ch);
+ }
+ }
+ sb.append((char)ch);
+ }
+ return sb.toString();
+ }
+}
+
+static class CommentReader extends AFn{
+ public Object invoke(Object reader, Object semicolon) throws Exception {
+ Reader r = (Reader) reader;
+ int ch;
+ do
+ {
+ ch = r.read();
+ } while (ch != -1 && ch != '\n' && ch != '\r');
+ return r;
+ }
+}
}
diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java
index cbb4f7e6..aea8e677 100644
--- a/src/jvm/clojure/lang/RT.java
+++ b/src/jvm/clojure/lang/RT.java
@@ -306,6 +306,16 @@ static public boolean isLineNumberingReader(Reader r) {
return r instanceof LineNumberingPushbackReader;
}
+static public String resolveClassNameInContext(String className) {
+ //todo - look up in context var
+ return className;
+}
+
+static public boolean suppressRead(){
+ //todo - look up in suppress-read var
+ return false;
+}
+
///////////////////////////////// values //////////////////////////
static public Object setValues(Object... vals)
diff --git a/src/jvm/clojure/lang/StaticMemberName.java b/src/jvm/clojure/lang/StaticMemberName.java
new file mode 100644
index 00000000..4cbc89c4
--- /dev/null
+++ b/src/jvm/clojure/lang/StaticMemberName.java
@@ -0,0 +1,22 @@
+/**
+ * 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 StaticMemberName {
+final public String className;
+final public String memberName;
+
+public StaticMemberName(String className, String memberName) {
+ this.className = className;
+ this.memberName = memberName;
+}
+
+}