diff options
author | Rich Hickey <richhickey@gmail.com> | 2007-09-16 15:56:14 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2007-09-16 15:56:14 +0000 |
commit | d041b1fe404e73fb01ee572825d32a1d9df731d7 (patch) | |
tree | 1966b98d21955403f0bfb763319beaf2ee8294b7 /src | |
parent | a6be4971c2e80127462bcd564e237fdfa293755c (diff) |
interim checkin
Diffstat (limited to 'src')
-rw-r--r-- | src/boot.clj | 2 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Compiler.java | 32 | ||||
-rw-r--r-- | src/jvm/clojure/lang/LispReader.java | 42 |
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;
|