summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2007-09-16 15:56:14 +0000
committerRich Hickey <richhickey@gmail.com>2007-09-16 15:56:14 +0000
commitd041b1fe404e73fb01ee572825d32a1d9df731d7 (patch)
tree1966b98d21955403f0bfb763319beaf2ee8294b7 /src
parenta6be4971c2e80127462bcd564e237fdfa293755c (diff)
interim checkin
Diffstat (limited to 'src')
-rw-r--r--src/boot.clj2
-rw-r--r--src/jvm/clojure/lang/Compiler.java32
-rw-r--r--src/jvm/clojure/lang/LispReader.java42
3 files changed, 52 insertions, 24 deletions
diff --git a/src/boot.clj b/src/boot.clj
index 05f1acde..a6af2b3d 100644
--- a/src/boot.clj
+++ b/src/boot.clj
@@ -12,7 +12,7 @@
([& args]
(. clojure.lang.PersistentVector (create args))))
-(defn hashmap
+(defn hash-map
([] {})
([& args]
(. clojure.lang.PersistentHashMap (create args))))
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java
index d342fa09..180c150f 100644
--- a/src/jvm/clojure/lang/Compiler.java
+++ b/src/jvm/clojure/lang/Compiler.java
@@ -50,7 +50,7 @@ static final Symbol NEW = Symbol.create("new");
//static final Symbol UNQUOTE_SPLICING = Symbol.create("unquote-splicing");
//static final Symbol SYNTAX_QUOTE = Symbol.create("clojure", "syntax-quote");
static final Symbol LIST = Symbol.create("clojure", "list");
-static final Symbol HASHMAP = Symbol.create("clojure", "hashmap");
+static final Symbol HASHMAP = Symbol.create("clojure", "hash-map");
static final Symbol VECTOR = Symbol.create("clojure", "vector");
static final Symbol _AMP_ = Symbol.create("&");
@@ -2015,7 +2015,7 @@ static class FnMethod{
NEXT_LOCAL_NUM, 0));
//register 'this' as local 0
- registerLocal(THISFN, null);
+ registerLocal(THISFN, null, null);
PSTATE state = PSTATE.REQ;
PersistentVector argLocals = PersistentVector.EMPTY;
@@ -2034,7 +2034,7 @@ static class FnMethod{
else
{
- LocalBinding lb = registerLocal(p, tagOf(p) != null ? HostExpr.tagToClass(tagOf(p)) : null);
+ LocalBinding lb = registerLocal(p, tagOf(p), null);
argLocals = argLocals.cons(lb);
switch(state)
{
@@ -2101,23 +2101,27 @@ static class FnMethod{
static class LocalBinding{
final Symbol sym;
- final Class javaClass;
+ final Symbol tag;
+ final Expr init;
final int idx;
final String name;
- public LocalBinding(int num, Symbol sym, Class javaClass){
+ public LocalBinding(int num, Symbol sym, Symbol tag, Expr init){
this.idx = num;
this.sym = sym;
- this.javaClass = javaClass;
+ this.tag = tag;
+ this.init = init;
name = munge(sym.name);
}
public boolean hasJavaClass() throws Exception{
- return javaClass != null;
+ return tag != null
+ || (init != null && init.hasJavaClass());
}
public Class getJavaClass() throws Exception{
- return javaClass;
+ return tag != null ? HostExpr.tagToClass(tag)
+ : init.getJavaClass();
}
}
@@ -2268,13 +2272,7 @@ static class LetExpr implements Expr{
Expr init = analyze(C.EXPRESSION, bindings.nth(i + 1), sym.name);
//sequential enhancement of env (like Lisp let*)
- Symbol tag = tagOf(sym);
- Class declClass = null;
- if(tag != null)
- declClass = HostExpr.tagToClass(tag);
- else if(init.hasJavaClass())
- declClass = init.getJavaClass();
- LocalBinding lb = registerLocal(sym, declClass);
+ LocalBinding lb = registerLocal(sym, tagOf(sym), init);
BindingInit bi = new BindingInit(lb, init);
bindingInits = bindingInits.cons(bi);
@@ -2398,9 +2396,9 @@ static class RecurExpr implements Expr{
}
}
-private static LocalBinding registerLocal(Symbol sym, Class javaClass) throws Exception{
+private static LocalBinding registerLocal(Symbol sym, Symbol tag, Expr init) throws Exception{
int num = getAndIncLocalNum();
- LocalBinding b = new LocalBinding(num, sym, javaClass);
+ LocalBinding b = new LocalBinding(num, sym, tag, init);
IPersistentMap localsMap = (IPersistentMap) LOCAL_ENV.get();
LOCAL_ENV.set(RT.assoc(localsMap, b.sym, b));
FnMethod method = (FnMethod) METHOD.get();
diff --git a/src/jvm/clojure/lang/LispReader.java b/src/jvm/clojure/lang/LispReader.java
index 6fa03009..578204c0 100644
--- a/src/jvm/clojure/lang/LispReader.java
+++ b/src/jvm/clojure/lang/LispReader.java
@@ -26,12 +26,15 @@ static Symbol QUOTE = Symbol.create(null, "quote");
static Symbol CONCAT = Symbol.create("clojure", "concat");
static Symbol LIST = Symbol.create("clojure", "list");
static Symbol APPLY = Symbol.create("clojure", "apply");
-static Symbol HASHMAP = Symbol.create("clojure", "hashmap");
+static Symbol HASHMAP = Symbol.create("clojure", "hash-map");
static Symbol VECTOR = Symbol.create("clojure", "vector");
static Symbol WITH_META = Symbol.create("clojure", "with-meta");
+static Symbol META = Symbol.create("clojure", "meta");
+static Symbol DEREF = Symbol.create("clojure", "deref");
static Keyword LINE_KEY = Keyword.intern("clojure", "line");
static IFn[] macros = new IFn[256];
+static IFn[] dispatchMacros = new IFn[256];
static Pattern symbolPat = Pattern.compile("[:]?([\\D&&[^:/]][^:/]*/)?[\\D&&[^:/]][^:/]*");
//static Pattern varPat = Pattern.compile("([\\D&&[^:\\.]][^:\\.]*):([\\D&&[^:\\.]][^:\\.]*)");
static Pattern intPat = Pattern.compile("[-+]?[0-9]+\\.?");
@@ -47,10 +50,11 @@ static
{
macros['"'] = new StringReader();
macros[';'] = new CommentReader();
- macros['\''] = new QuoteReader();
+ macros['\''] = new WrappingReader(Compiler.QUOTE);
+ macros['@'] = new WrappingReader(DEREF);
+ macros['^'] = new WrappingReader(META);
macros['`'] = new SyntaxQuoteReader();
macros['~'] = new UnquoteReader();
- macros['^'] = new MetaReader();
macros['('] = new ListReader();
macros[')'] = new UnmatchedDelimiterReader();
macros['['] = new VectorReader();
@@ -59,6 +63,11 @@ static
macros['}'] = new UnmatchedDelimiterReader();
// macros['|'] = new ArgVectorReader();
macros['\\'] = new CharacterReader();
+ macros['#'] = new DispatchReader();
+
+
+ dispatchMacros['^'] = new MetaReader();
+ dispatchMacros['\''] = new WrappingReader(Compiler.THE_VAR);
}
static boolean isWhitespace(int ch){
@@ -140,7 +149,7 @@ static private String readToken(PushbackReader r, char initch) throws Exception{
for(; ;)
{
int ch = r.read();
- if(ch == -1 || isWhitespace(ch) || isMacro(ch))
+ if(ch == -1 || isWhitespace(ch) || isTerminatingMacro(ch))
{
r.unread(ch);
return sb.toString();
@@ -231,6 +240,9 @@ static private boolean isMacro(int ch){
return (ch < macros.length && macros[ch] != null);
}
+static private boolean isTerminatingMacro(int ch){
+ return (ch != '#' && ch < macros.length && macros[ch] != null);
+}
static class StringReader extends AFn{
public Object invoke(Object reader, Object doublequote) throws Exception{
@@ -284,15 +296,33 @@ static class CommentReader extends AFn{
}
-static class QuoteReader extends AFn{
+static class WrappingReader extends AFn{
+ final Symbol sym;
+
+ public WrappingReader(Symbol sym){
+ this.sym = sym;
+ }
+
public Object invoke(Object reader, Object quote) throws Exception{
PushbackReader r = (PushbackReader) reader;
Object o = read(r, true, null, true);
- return RT.list(Compiler.QUOTE, o);
+ return RT.list(sym, o);
}
}
+static class DispatchReader extends AFn{
+ public Object invoke(Object reader, Object hash) throws Exception{
+ int ch = ((Reader) reader).read();
+ if(ch == -1)
+ throw new Exception("EOF while reading character");
+ IFn fn = dispatchMacros[ch];
+ if(fn == null)
+ throw new Exception(String.format("No dispatch macro for: %c", (char) ch));
+ return fn.invoke(reader, ch);
+ }
+}
+
static class MetaReader extends AFn{
public Object invoke(Object reader, Object caret) throws Exception{
PushbackReader r = (PushbackReader) reader;