summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2007-09-08 16:40:16 +0000
committerRich Hickey <richhickey@gmail.com>2007-09-08 16:40:16 +0000
commitd3ba5541568cd748daae80a9866fa109ded2d520 (patch)
tree2a7949297cce4e6b6f21fd7976310621642e1899 /src
parent9913465259449b6b278b304eb24e03ef20a194d0 (diff)
added dispatch map for parsers
Diffstat (limited to 'src')
-rw-r--r--src/boot.clj24
-rw-r--r--src/jvm/clojure/lang/Compiler.java466
-rw-r--r--src/jvm/clojure/lang/LispReader.java16
3 files changed, 292 insertions, 214 deletions
diff --git a/src/boot.clj b/src/boot.clj
index bfac2270..ffa83c04 100644
--- a/src/boot.clj
+++ b/src/boot.clj
@@ -6,6 +6,21 @@
(. (the-var defn) (setMacro))
+(defn contains [coll key]
+ (. RT (contains coll key)))
+
+(defn get [coll key]
+ (. RT (get coll key)))
+
+(defn assoc [coll key val]
+ (. RT (assoc coll key val)))
+
+(defn dissoc [coll key]
+ (. RT (dissoc coll key)))
+
+(defn count [coll]
+ (. RT (count coll)))
+
(def defmacro (fn [name & args]
(list 'do
(cons 'defn (cons name args))
@@ -22,7 +37,7 @@
(def t (. RT T))
(defn vector
- ([] (. clojure.lang.PersistentVector EMPTY))
+ ([] [])
([& args]
(. clojure.lang.PersistentVector (create args))))
@@ -178,12 +193,13 @@
(nil? x) (recur (first xs) (rest xs))
:else (lazy-cons (first x) (apply concat (rest x) xs)))))
-(defn andf [& args]
+(defn andfn [& args]
(if (nil? (rest args))
(first args)
(and (first args) (recur (rest args)))))
-(defn orf [& args]
+(defn orfn [& args]
(if (nil? args)
nil
- (or (first args) (recur (rest args))))) \ No newline at end of file
+ (or (first args) (recur (rest args)))))
+
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java
index 1e65c211..6536db16 100644
--- a/src/jvm/clojure/lang/Compiler.java
+++ b/src/jvm/clojure/lang/Compiler.java
@@ -42,13 +42,44 @@ static final Symbol EQL_REF = Symbol.create("eql-ref?");
static final Symbol INSTANCE = Symbol.create("instance?");
static final Symbol THISFN = Symbol.create("thisfn");
-static final Symbol IFN = Symbol.create("clojure.lang", "IFn");
static final Symbol CLASS = Symbol.create("class");
+static final Symbol UNQUOTE = Symbol.create("unquote");
+static final Symbol UNQUOTE_SPLICING = Symbol.create("unquote-splicing");
+static final Symbol SYNTAX_QUOTE = Symbol.create("syntax-quote");
-static final Symbol IMPORT = Symbol.create("import");
-static final Symbol USE = Symbol.create("use");
static final Symbol _AMP_ = Symbol.create("&");
+//static final Symbol IMPORT = Symbol.create("import");
+//static final Symbol USE = Symbol.create("use");
+
+//static final Symbol IFN = Symbol.create("clojure.lang", "IFn");
+
+static IPersistentMap specials = RT.map(
+ DEF, new DefExpr.Parser(),
+ LOOP, new LetExpr.Parser(),
+ RECUR, new RecurExpr.Parser(),
+ IF, new IfExpr.Parser(),
+ LET, new LetExpr.Parser(),
+ DO, new BodyExpr.Parser(),
+ FN, null,
+ QUOTE, new QuoteExpr.Parser(),
+ THE_VAR, new TheVarExpr.Parser(),
+ DOT, new HostExpr.Parser(),
+ ASSIGN, new AssignExpr.Parser(),
+ TRY_FINALLY, new TryFinallyExpr.Parser(),
+ THROW, new ThrowExpr.Parser(),
+ MONITOR_ENTER, new MonitorEnterExpr.Parser(),
+ MONITOR_EXIT, new MonitorExitExpr.Parser(),
+ EQL_REF, new EqlRefExpr.Parser(),
+ INSTANCE, new InstanceExpr.Parser(),
+ THISFN, null,
+ CLASS, null,
+ UNQUOTE, null,
+ UNQUOTE_SPLICING, null,
+ SYNTAX_QUOTE, null,
+ _AMP_, null
+);
+
private static final int MAX_POSITIONAL_ARITY = 20;
private static final Type OBJECT_TYPE;
private static final Type KEYWORD_TYPE = Type.getType(Keyword.class);
@@ -121,6 +152,10 @@ interface Expr{
void emit(C context, FnExpr fn, GeneratorAdapter gen);
}
+interface IParser{
+ Expr parse(C context, Object form) throws Exception;
+}
+
static class DefExpr implements Expr{
final Var var;
final Expr init;
@@ -151,18 +186,20 @@ static class DefExpr implements Expr{
gen.pop();
}
- public static Expr parse(C context, ISeq form) throws Exception{
- //(def x) or (def x initexpr)
- if(RT.count(form) > 3)
- throw new Exception("Too many arguments to def");
- else if(RT.count(form) < 2)
- throw new Exception("Too few arguments to def");
- else if(!(RT.second(form) instanceof Symbol))
- throw new Exception("Second argument to def must be a Symbol");
- Var v = lookupVar((Symbol) RT.second(form), true);
- if(!v.sym.ns.equals(currentNS()))
- throw new Exception("Can't create defs outside of current ns");
- return new DefExpr(v, analyze(C.EXPRESSION, RT.third(form), v.sym.name), RT.count(form) == 3);
+ static class Parser implements IParser{
+ public Expr parse(C context, Object form) throws Exception{
+ //(def x) or (def x initexpr)
+ if(RT.count(form) > 3)
+ throw new Exception("Too many arguments to def");
+ else if(RT.count(form) < 2)
+ throw new Exception("Too few arguments to def");
+ else if(!(RT.second(form) instanceof Symbol))
+ throw new Exception("Second argument to def must be a Symbol");
+ Var v = lookupVar((Symbol) RT.second(form), true);
+ if(!v.sym.ns.equals(currentNS()))
+ throw new Exception("Can't create defs outside of current ns");
+ return new DefExpr(v, analyze(C.EXPRESSION, RT.third(form), v.sym.name), RT.count(form) == 3);
+ }
}
}
@@ -184,13 +221,16 @@ static class AssignExpr implements Expr{
target.emitAssign(context, fn, gen, val);
}
- public static Expr parse(C context, ISeq form) throws Exception{
- if(RT.length(form) != 3)
- throw new IllegalArgumentException("Malformed assignment, expecting (= target val)");
- Expr target = analyze(C.EXPRESSION, RT.second(form));
- if(!(target instanceof AssignableExpr))
- throw new IllegalArgumentException("Invalid assignment target");
- return new AssignExpr((AssignableExpr) target, analyze(C.EXPRESSION, RT.third(form)));
+ static class Parser implements IParser{
+ public Expr parse(C context, Object frm) throws Exception{
+ ISeq form = (ISeq) frm;
+ if(RT.length(form) != 3)
+ throw new IllegalArgumentException("Malformed assignment, expecting (= target val)");
+ Expr target = analyze(C.EXPRESSION, RT.second(form));
+ if(!(target instanceof AssignableExpr))
+ throw new IllegalArgumentException("Invalid assignment target");
+ return new AssignExpr((AssignableExpr) target, analyze(C.EXPRESSION, RT.third(form)));
+ }
}
}
@@ -247,12 +287,14 @@ static class TheVarExpr implements Expr{
fn.emitVar(gen, var);
}
- public static Expr parse(C context, ISeq form) throws Exception{
- Symbol sym = (Symbol) RT.second(form);
- Var v = lookupVar(sym, false);
- if(v != null)
- return new TheVarExpr(v);
- throw new Exception("Unable to resolve var: " + sym + " in this context");
+ static class Parser implements IParser{
+ public Expr parse(C context, Object form) throws Exception{
+ Symbol sym = (Symbol) RT.second(form);
+ Var v = lookupVar(sym, false);
+ if(v != null)
+ return new TheVarExpr(v);
+ throw new Exception("Unable to resolve var: " + sym + " in this context");
+ }
}
}
@@ -289,39 +331,42 @@ static interface AssignableExpr{
}
static abstract class HostExpr implements Expr{
- public static Expr parse(C context, ISeq form) throws Exception{
- //(. x fieldname-sym) or (. x (methodname-sym args...))
- if(RT.length(form) != 3)
- throw new IllegalArgumentException("Malformed member expression, expecting (. target member)");
- //determine static or instance
- //static target must be symbol, either fully.qualified.Classname or Classname that has been imported
- String className = maybeClassName(RT.second(form));
- //at this point className will be non-null if static
- Expr instance = null;
- if(className == null)
- instance = analyze(C.EXPRESSION, RT.second(form));
-
- if(RT.third(form) instanceof Symbol) //field
- {
- Symbol sym = (Symbol) RT.third(form);
- if(className != null)
- return new StaticFieldExpr(className, sym.name);
- else
- return new InstanceFieldExpr(instance, sym.name);
- }
- else if(RT.third(form) instanceof ISeq && RT.first(RT.third(form)) instanceof Symbol)
- {
- Symbol sym = (Symbol) RT.first(RT.third(form));
- PersistentVector args = PersistentVector.EMPTY;
- for(ISeq s = RT.rest(RT.third(form)); s != null; s = s.rest())
- args = args.cons(analyze(C.EXPRESSION, s.first()));
- if(className != null)
- return new StaticMethodExpr(className, sym.name, args);
+ static class Parser implements IParser{
+ public Expr parse(C context, Object frm) throws Exception{
+ ISeq form = (ISeq) frm;
+ //(. x fieldname-sym) or (. x (methodname-sym args...))
+ if(RT.length(form) != 3)
+ throw new IllegalArgumentException("Malformed member expression, expecting (. target member)");
+ //determine static or instance
+ //static target must be symbol, either fully.qualified.Classname or Classname that has been imported
+ String className = maybeClassName(RT.second(form));
+ //at this point className will be non-null if static
+ Expr instance = null;
+ if(className == null)
+ instance = analyze(C.EXPRESSION, RT.second(form));
+
+ if(RT.third(form) instanceof Symbol) //field
+ {
+ Symbol sym = (Symbol) RT.third(form);
+ if(className != null)
+ return new StaticFieldExpr(className, sym.name);
+ else
+ return new InstanceFieldExpr(instance, sym.name);
+ }
+ else if(RT.third(form) instanceof ISeq && RT.first(RT.third(form)) instanceof Symbol)
+ {
+ Symbol sym = (Symbol) RT.first(RT.third(form));
+ PersistentVector args = PersistentVector.EMPTY;
+ for(ISeq s = RT.rest(RT.third(form)); s != null; s = s.rest())
+ args = args.cons(analyze(C.EXPRESSION, s.first()));
+ if(className != null)
+ return new StaticMethodExpr(className, sym.name, args);
+ else
+ return new InstanceMethodExpr(instance, sym.name, args);
+ }
else
- return new InstanceMethodExpr(instance, sym.name, args);
- }
- else
- throw new IllegalArgumentException("Malformed member expression");
+ throw new IllegalArgumentException("Malformed member expression");
+ }
}
private static String maybeClassName(Object form){
@@ -533,12 +578,14 @@ static class QuoteExpr extends LiteralExpr{
}
}
- public static Expr parse(C context, ISeq form){
- Object v = RT.second(form);
- int id = RT.nextID();
- DynamicClassLoader loader = (DynamicClassLoader) LOADER.get();
- loader.registerQuotedVal(id, v);
- return new QuoteExpr(id, v);
+ static class Parser implements IParser{
+ public Expr parse(C context, Object form){
+ Object v = RT.second(form);
+ int id = RT.nextID();
+ DynamicClassLoader loader = (DynamicClassLoader) LOADER.get();
+ loader.registerQuotedVal(id, v);
+ return new QuoteExpr(id, v);
+ }
}
}
@@ -671,6 +718,12 @@ static class MonitorEnterExpr implements Expr{
NIL_EXPR.emit(context, fn, gen);
}
}
+
+ static class Parser implements IParser{
+ public Expr parse(C context, Object form) throws Exception{
+ return analyze(C.EXPRESSION, RT.second(form));
+ }
+ }
}
static class MonitorExitExpr implements Expr{
@@ -692,6 +745,13 @@ static class MonitorExitExpr implements Expr{
NIL_EXPR.emit(context, fn, gen);
}
}
+
+ static class Parser implements IParser{
+ public Expr parse(C context, Object form) throws Exception{
+ return analyze(C.EXPRESSION, RT.second(form));
+ }
+ }
+
}
static class TryFinallyExpr implements Expr{
@@ -726,17 +786,20 @@ static class TryFinallyExpr implements Expr{
gen.mark(end);
}
- public static Expr parse(C context, ISeq form) throws Exception{
- //(try-finally try-expr finally-expr)
- if(form.count() != 3)
- throw new IllegalArgumentException(
- "Wrong number of arguments, expecting: (try-finally try-expr finally-expr) ");
+ static class Parser implements IParser{
+ public Expr parse(C context, Object frm) throws Exception{
+ ISeq form = (ISeq) frm;
+ //(try-finally try-expr finally-expr)
+ if(form.count() != 3)
+ throw new IllegalArgumentException(
+ "Wrong number of arguments, expecting: (try-finally try-expr finally-expr) ");
- if(context == C.EVAL)
- return analyze(context, RT.list(RT.list(FN, PersistentVector.EMPTY, form)));
+ if(context == C.EVAL)
+ return analyze(context, RT.list(RT.list(FN, PersistentVector.EMPTY, form)));
- return new TryFinallyExpr(analyze(context, RT.second(form)),
- analyze(C.STATEMENT, RT.third(form)));
+ return new TryFinallyExpr(analyze(context, RT.second(form)),
+ analyze(C.STATEMENT, RT.third(form)));
+ }
}
}
@@ -758,8 +821,10 @@ static class ThrowExpr implements Expr{
gen.throwException();
}
- public static Expr parse(C context, ISeq form) throws Exception{
- return new ThrowExpr(analyze(C.EXPRESSION, RT.second(form)));
+ static class Parser implements IParser{
+ public Expr parse(C context, Object form) throws Exception{
+ return new ThrowExpr(analyze(C.EXPRESSION, RT.second(form)));
+ }
}
}
@@ -794,14 +859,17 @@ static class InstanceExpr implements Expr{
}
}
- public static Expr parse(C context, ISeq form) throws Exception{
- //(instance? x Classname)
- if(form.count() != 3)
- throw new Exception("wrong number of arguments, expecting: (instance? x Classname)");
- String className = HostExpr.maybeClassName(RT.third(form));
- if(className == null)
- throw new IllegalArgumentException("Unable to resolve classname: " + RT.third(form));
- return new InstanceExpr(analyze(C.EXPRESSION, RT.second(form)), className);
+ static class Parser implements IParser{
+ public Expr parse(C context, Object frm) throws Exception{
+ ISeq form = (ISeq) frm;
+ //(instance? x Classname)
+ if(form.count() != 3)
+ throw new Exception("wrong number of arguments, expecting: (instance? x Classname)");
+ String className = HostExpr.maybeClassName(RT.third(form));
+ if(className == null)
+ throw new IllegalArgumentException("Unable to resolve classname: " + RT.third(form));
+ return new InstanceExpr(analyze(C.EXPRESSION, RT.second(form)), className);
+ }
}
}
@@ -834,12 +902,15 @@ static class EqlRefExpr implements Expr{
gen.pop();
}
- public static Expr parse(C context, ISeq form) throws Exception{
- //(eql-ref? x y)
- if(form.count() != 3)
- throw new Exception("wrong number of arguments, expecting: (eql-ref? x y)");
+ static class Parser implements IParser{
+ public Expr parse(C context, Object frm) throws Exception{
+ ISeq form = (ISeq) frm;
+ //(eql-ref? x y)
+ if(form.count() != 3)
+ throw new Exception("wrong number of arguments, expecting: (eql-ref? x y)");
- return new EqlRefExpr(analyze(C.EXPRESSION, RT.second(form)), analyze(C.EXPRESSION, RT.third(form)));
+ return new EqlRefExpr(analyze(C.EXPRESSION, RT.second(form)), analyze(C.EXPRESSION, RT.third(form)));
+ }
}
}
@@ -873,15 +944,18 @@ static class IfExpr implements Expr{
gen.mark(endLabel);
}
- public static Expr parse(C context, ISeq form) throws Exception{
- //(if test then) or (if test then else)
- if(form.count() > 4)
- throw new Exception("Too many arguments to if");
- else if(form.count() < 3)
- throw new Exception("Too few arguments to if");
- return new IfExpr(analyze(C.EXPRESSION, RT.second(form)),
- analyze(context, RT.third(form)),
- analyze(context, RT.fourth(form)));
+ static class Parser implements IParser{
+ public Expr parse(C context, Object frm) throws Exception{
+ ISeq form = (ISeq) frm;
+ //(if test then) or (if test then else)
+ if(form.count() > 4)
+ throw new Exception("Too many arguments to if");
+ else if(form.count() < 3)
+ throw new Exception("Too few arguments to if");
+ return new IfExpr(analyze(C.EXPRESSION, RT.second(form)),
+ analyze(context, RT.third(form)),
+ analyze(context, RT.fourth(form)));
+ }
}
}
@@ -976,7 +1050,7 @@ static class MapExpr implements Expr{
gen.pop();
}
- public static Expr parse(C context, IPersistentMap form) throws Exception{
+ static public Expr parse(C context, IPersistentMap form) throws Exception{
IPersistentVector keyvals = PersistentVector.EMPTY;
for(ISeq s = RT.seq(form); s != null; s = s.rest())
{
@@ -1011,12 +1085,13 @@ static class VectorExpr implements Expr{
gen.pop();
}
- public static Expr parse(C context, IPersistentVector form) throws Exception{
+ static public Expr parse(C context, IPersistentVector form) throws Exception{
IPersistentVector args = PersistentVector.EMPTY;
for(int i = 0; i < form.count(); i++)
args = (IPersistentVector) args.cons(analyze(C.EXPRESSION, form.nth(i)));
return new VectorExpr(args);
}
+
}
static class InvokeExpr implements Expr{
@@ -1050,7 +1125,7 @@ static class InvokeExpr implements Expr{
gen.pop();
}
- public static Expr parse(C context, ISeq form) throws Exception{
+ static public Expr parse(C context, ISeq form) throws Exception{
Expr fexpr = analyze(C.EXPRESSION, form.first());
PersistentVector args = PersistentVector.EMPTY;
for(ISeq s = RT.seq(form.rest()); s != null; s = s.rest())
@@ -1058,7 +1133,8 @@ static class InvokeExpr implements Expr{
args = args.cons(analyze(C.EXPRESSION, s.first()));
}
if(args.count() > MAX_POSITIONAL_ARITY)
- throw new IllegalArgumentException(String.format("No more than %d args supported", MAX_POSITIONAL_ARITY));
+ throw new IllegalArgumentException(
+ String.format("No more than %d args supported", MAX_POSITIONAL_ARITY));
return new InvokeExpr(fexpr, args);
}
}
@@ -1128,7 +1204,8 @@ static class FnExpr implements Expr{
{
for(int i = variadicMethod.reqParms.count() + 1; i <= MAX_POSITIONAL_ARITY; i++)
if(methodArray[i] != null)
- throw new Exception("Can't have fixed arity function with more params than variadic function");
+ throw new Exception(
+ "Can't have fixed arity function with more params than variadic function");
}
IPersistentCollection methods = null;
@@ -1383,7 +1460,7 @@ static class FnMethod{
if(method.reqParms.count() > MAX_POSITIONAL_ARITY)
throw new Exception("Can't specify more than " + MAX_POSITIONAL_ARITY + " params");
LOOP_LOCALS.set(loopLocals);
- method.body = BodyExpr.parse(C.RETURN, body);
+ method.body = (new BodyExpr.Parser()).parse(C.RETURN, body);
return method;
}
finally
@@ -1459,17 +1536,22 @@ static class BodyExpr implements Expr{
this.exprs = exprs;
}
- static Expr parse(C context, ISeq forms) throws Exception{
- PersistentVector exprs = PersistentVector.EMPTY;
- for(; forms != null; forms = forms.rest())
- {
- Expr e = (context == C.STATEMENT || forms.rest() != null) ?
- analyze(C.STATEMENT, forms.first())
- :
- analyze(context, forms.first());
- exprs = exprs.cons(e);
- }
- return new BodyExpr(exprs);
+ static class Parser implements IParser{
+ public Expr parse(C context, Object frms) throws Exception{
+ ISeq forms = (ISeq) frms;
+ if(RT.equal(RT.first(forms), DO))
+ forms = RT.rest(forms);
+ PersistentVector exprs = PersistentVector.EMPTY;
+ for(; forms != null; forms = forms.rest())
+ {
+ Expr e = (context == C.STATEMENT || forms.rest() != null) ?
+ analyze(C.STATEMENT, forms.first())
+ :
+ analyze(context, forms.first());
+ exprs = exprs.cons(e);
+ }
+ return new BodyExpr(exprs);
+ }
}
public Object eval() throws Exception{
@@ -1521,54 +1603,60 @@ static class LetExpr implements Expr{
this.isLoop = isLoop;
}
- static Expr parse(C context, ISeq form, boolean isLoop) throws Exception{
- //(let [var val var2 val2 ...] body...)
- if(!(RT.second(form) instanceof IPersistentVector))
- throw new IllegalArgumentException("Bad binding form, expected vector");
+ static class Parser implements IParser{
+ public Expr parse(C context, Object frm) throws Exception{
+ ISeq form = (ISeq) frm;
+ //(let [var val var2 val2 ...] body...)
+ boolean isLoop = RT.first(form).equals(LOOP);
+ if(!(RT.second(form) instanceof IPersistentVector))
+ throw new IllegalArgumentException("Bad binding form, expected vector");
- IPersistentVector bindings = (IPersistentVector) RT.second(form);
- if((bindings.count() % 2) != 0)
- throw new IllegalArgumentException("Bad binding form, expected matched symbol expression pairs");
+ IPersistentVector bindings = (IPersistentVector) RT.second(form);
+ if((bindings.count() % 2) != 0)
+ throw new IllegalArgumentException("Bad binding form, expected matched symbol expression pairs");
- ISeq body = RT.rest(RT.rest(form));
+ ISeq body = RT.rest(RT.rest(form));
- if(context == C.EVAL)
- return analyze(context, RT.list(RT.list(FN, PersistentVector.EMPTY, form)));
+ if(context == C.EVAL)
+ return analyze(context, RT.list(RT.list(FN, PersistentVector.EMPTY, form)));
- IPersistentMap dynamicBindings = RT.map(LOCAL_ENV, LOCAL_ENV.get(),
- NEXT_LOCAL_NUM, NEXT_LOCAL_NUM.get());
- if(isLoop)
- dynamicBindings = dynamicBindings.assoc(LOOP_LOCALS, null);
-
- try
- {
- Var.pushThreadBindings(dynamicBindings);
+ IPersistentMap dynamicBindings = RT.map(LOCAL_ENV, LOCAL_ENV.get(),
+ NEXT_LOCAL_NUM, NEXT_LOCAL_NUM.get());
+ if(isLoop)
+ dynamicBindings = dynamicBindings.assoc(LOOP_LOCALS, null);
- PersistentVector bindingInits = PersistentVector.EMPTY;
- PersistentVector loopLocals = PersistentVector.EMPTY;
- for(int i = 0; i < bindings.count(); i += 2)
+ try
{
- if(!(bindings.nth(i) instanceof Symbol))
- throw new IllegalArgumentException("Bad binding form, expected symbol, got: " + bindings.nth(i));
- Symbol sym = (Symbol) bindings.nth(i);
-
- Expr init = analyze(C.EXPRESSION, bindings.nth(i + 1), sym.name);
- //sequential enhancement of env (like Lisp let*)
- LocalBinding lb = registerLocal(sym, tagOf(sym));
- BindingInit bi = new BindingInit(lb, init);
- bindingInits = bindingInits.cons(bi);
+ Var.pushThreadBindings(dynamicBindings);
+ PersistentVector bindingInits = PersistentVector.EMPTY;
+ PersistentVector loopLocals = PersistentVector.EMPTY;
+ for(int i = 0; i < bindings.count(); i += 2)
+ {
+ if(!(bindings.nth(i) instanceof Symbol))
+ throw new IllegalArgumentException(
+ "Bad binding form, expected symbol, got: " + bindings.nth(i));
+ Symbol sym = (Symbol) bindings.nth(i);
+
+ Expr init = analyze(C.EXPRESSION, bindings.nth(i + 1), sym.name);
+ //sequential enhancement of env (like Lisp let*)
+ LocalBinding lb = registerLocal(sym, tagOf(sym));
+ BindingInit bi = new BindingInit(lb, init);
+ bindingInits = bindingInits.cons(bi);
+
+ if(isLoop)
+ loopLocals = loopLocals.cons(lb);
+ }
if(isLoop)
- loopLocals = loopLocals.cons(lb);
+ LOOP_LOCALS.set(loopLocals);
+ return new LetExpr(bindingInits, (new BodyExpr.Parser()).parse(isLoop ? C.RETURN : context, body),
+ isLoop);
}
- if(isLoop)
- LOOP_LOCALS.set(loopLocals);
- return new LetExpr(bindingInits, BodyExpr.parse(isLoop ? C.RETURN : context, body), isLoop);
- }
- finally
- {
- Var.popThreadBindings();
- }
+ finally
+ {
+ Var.popThreadBindings();
+ }
+ }
}
public Object eval() throws Exception{
@@ -1628,20 +1716,23 @@ static class RecurExpr implements Expr{
gen.goTo(loopLabel);
}
- public static Expr parse(C context, ISeq form) throws Exception{
- IPersistentVector loopLocals = (IPersistentVector) LOOP_LOCALS.get();
- if(context != C.RETURN || loopLocals == null)
- throw new UnsupportedOperationException("Can only recur from tail position");
- PersistentVector args = PersistentVector.EMPTY;
- for(ISeq s = RT.seq(form.rest()); s != null; s = s.rest())
- {
- args = args.cons(analyze(C.EXPRESSION, s.first()));
- }
- if(args.count() != loopLocals.count())
- throw new IllegalArgumentException(
- String.format("Mismatched argument count to recur, expected: %d args, got: %d",
- loopLocals.count(), args.count()));
- return new RecurExpr(loopLocals, args);
+ static class Parser implements IParser{
+ public Expr parse(C context, Object frm) throws Exception{
+ ISeq form = (ISeq) frm;
+ IPersistentVector loopLocals = (IPersistentVector) LOOP_LOCALS.get();
+ if(context != C.RETURN || loopLocals == null)
+ throw new UnsupportedOperationException("Can only recur from tail position");
+ PersistentVector args = PersistentVector.EMPTY;
+ for(ISeq s = RT.seq(form.rest()); s != null; s = s.rest())
+ {
+ args = args.cons(analyze(C.EXPRESSION, s.first()));
+ }
+ if(args.count() != loopLocals.count())
+ throw new IllegalArgumentException(
+ String.format("Mismatched argument count to recur, expected: %d args, got: %d",
+ loopLocals.count(), args.count()));
+ return new RecurExpr(loopLocals, args);
+ }
}
}
@@ -1704,40 +1795,11 @@ private static Expr analyzeSeq(C context, ISeq form, String name) throws Excepti
return analyze(context, v.applyTo(form.rest()));
}
}
- if(op.equals(DEF))
- return DefExpr.parse(context, form);
- else if(op.equals(IF))
- return IfExpr.parse(context, form);
- else if(op.equals(FN))
+ IParser p;
+ if(op.equals(FN))
return FnExpr.parse(context, form, name);
- else if(op.equals(DO))
- return BodyExpr.parse(context, form.rest());
- else if(op.equals(LET))
- return LetExpr.parse(context, form, false);
- else if(op.equals(LOOP))
- return LetExpr.parse(context, form, true);
- else if(op.equals(RECUR))
- return RecurExpr.parse(context, form);
- else if(op.equals(QUOTE))
- return QuoteExpr.parse(context, form);
- else if(op.equals(DOT))
- return HostExpr.parse(context, form);
- else if(op.equals(THE_VAR))
- return TheVarExpr.parse(context, form);
- else if(op.equals(ASSIGN))
- return AssignExpr.parse(context, form);
- else if(op.equals(TRY_FINALLY))
- return TryFinallyExpr.parse(context, form);
- else if(op.equals(THROW))
- return ThrowExpr.parse(context, form);
- else if(op.equals(MONITOR_ENTER))
- return new MonitorEnterExpr(analyze(C.EXPRESSION, RT.second(form)));
- else if(op.equals(MONITOR_EXIT))
- return new MonitorExitExpr(analyze(C.EXPRESSION, RT.second(form)));
- else if(op.equals(EQL_REF))
- return EqlRefExpr.parse(context, form);
- else if(op.equals(INSTANCE))
- return InstanceExpr.parse(context, form);
+ else if((p = (IParser) specials.valAt(op)) != null)
+ return p.parse(context, form);
else
return InvokeExpr.parse(context, form);
}
diff --git a/src/jvm/clojure/lang/LispReader.java b/src/jvm/clojure/lang/LispReader.java
index 563f29f8..63a3c564 100644
--- a/src/jvm/clojure/lang/LispReader.java
+++ b/src/jvm/clojure/lang/LispReader.java
@@ -19,10 +19,10 @@ import java.math.BigInteger;
public class LispReader{
-static Symbol QUOTE = Symbol.create(null, "quote");
-static Symbol SYNTAX_QUOTE = Symbol.create(null, "syntax-quote");
-static Symbol UNQUOTE = Symbol.create(null, "unquote");
-static Symbol UNQUOTE_SPLICING = Symbol.create(null, "unquote-splicing");
+//static Symbol QUOTE = Symbol.create(null, "quote");
+//static Symbol SYNTAX_QUOTE = Symbol.create(null, "syntax-quote");
+//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&&[^:/]][^:/]*/)?[\\D&&[^:/]][^:/]*");
@@ -370,7 +370,7 @@ static class QuoteReader extends AFn{
public Object invoke(Object reader, Object quote) throws Exception{
PushbackReader r = (PushbackReader) reader;
Object o = read(r, true, null, true);
- return RT.list(QUOTE, o);
+ return RT.list(Compiler.QUOTE, o);
}
}
@@ -396,7 +396,7 @@ static class SyntaxQuoteReader extends AFn{
public Object invoke(Object reader, Object backquote) throws Exception{
PushbackReader r = (PushbackReader) reader;
Object o = read(r, true, null, true);
- return RT.list(SYNTAX_QUOTE, o);
+ return RT.list(Compiler.SYNTAX_QUOTE, o);
}
}
@@ -410,13 +410,13 @@ static class UnquoteReader extends AFn{
if(ch == '@')
{
Object o = read(r, true, null, true);
- return RT.list(UNQUOTE_SPLICING, o);
+ return RT.list(Compiler.UNQUOTE_SPLICING, o);
}
else
{
r.unread(ch);
Object o = read(r, true, null, true);
- return RT.list(UNQUOTE, o);
+ return RT.list(Compiler.UNQUOTE, o);
}
}