diff options
author | Rich Hickey <richhickey@gmail.com> | 2009-05-16 20:18:43 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2009-05-16 20:18:43 +0000 |
commit | dbb85aafafc90a9b6021ef58c5cd4bd8a20600fc (patch) | |
tree | e21a8308865b640816846ab8d7b70fe3ae4595bc /src | |
parent | 939976735ea071cb00944b066392ab8b8d749918 (diff) |
do unrolls at top-level
Diffstat (limited to 'src')
-rw-r--r-- | src/clj/clojure/core.clj | 19 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Compiler.java | 57 |
2 files changed, 51 insertions, 25 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj index a65443da..2f594afc 100644 --- a/src/clj/clojure/core.clj +++ b/src/clj/clojure/core.clj @@ -3448,9 +3448,9 @@ (def gen-class) (defmacro with-loading-context [& body] - `((fn this# [] + `((fn loading# [] (. clojure.lang.Var (pushThreadBindings {clojure.lang.Compiler/LOADER - (-> this# .getClass .getClassLoader)})) + (-> loading# .getClass .getClassLoader)})) (try ~@body (finally @@ -3493,13 +3493,16 @@ gen-class-call (when gen-class-clause (list* `gen-class :name (.replace (str name) \- \_) :impl-ns name :main true (next gen-class-clause))) - references (remove #(= :gen-class (first %)) references)] - `(with-loading-context + references (remove #(= :gen-class (first %)) references) + ;ns-effect (clojure.core/in-ns name) + ] + `(do (clojure.core/in-ns '~name) - ~@(when gen-class-call (list gen-class-call)) - ~@(when (and (not= name 'clojure.core) (not-any? #(= :refer-clojure (first %)) references)) - `((clojure.core/refer '~'clojure.core))) - ~@(map process-reference references)))) + (with-loading-context + ~@(when gen-class-call (list gen-class-call)) + ~@(when (and (not= name 'clojure.core) (not-any? #(= :refer-clojure (first %)) references)) + `((clojure.core/refer '~'clojure.core))) + ~@(map process-reference references))))) (defmacro refer-clojure "Same as (refer 'clojure.core <filters>)" diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java index 82d4a77a..c8ab4daa 100644 --- a/src/jvm/clojure/lang/Compiler.java +++ b/src/jvm/clojure/lang/Compiler.java @@ -4519,6 +4519,13 @@ public static Object macroexpand1(Object x) throws Exception{ return x; } +static Object macroexpand(Object form) throws Exception{ + Object exf = macroexpand1(form); + if(exf != form) + return macroexpand(exf); + return form; +} + private static Expr analyzeSeq(C context, ISeq form, String name) throws Exception{ Integer line = (Integer) LINE.deref(); if(RT.meta(form) != null && RT.meta(form).containsKey(RT.LINE_KEY)) @@ -4569,22 +4576,26 @@ public static Object eval(Object form) throws Exception{ Var.pushThreadBindings(RT.map(LOADER, RT.makeClassLoader())); createdLoader = true; } - try - { - if(form instanceof IPersistentCollection + try { + form = macroexpand(form); + if(form instanceof IPersistentCollection && Util.equals(RT.first(form), DO)) { + ISeq s = RT.next(form); + for(;RT.next(s) != null;s = RT.next(s)) + eval(RT.first(s)); + return eval(RT.first(s)); + } + else if(form instanceof IPersistentCollection && !(RT.first(form) instanceof Symbol - && ((Symbol) RT.first(form)).name.startsWith("def"))) - { + && ((Symbol) RT.first(form)).name.startsWith("def"))) { FnExpr fexpr = (FnExpr) analyze(C.EXPRESSION, RT.list(FN, PersistentVector.EMPTY, form), "eval"); IFn fn = (IFn) fexpr.eval(); return fn.invoke(); - } - else - { + } + else { Expr expr = analyze(C.EVAL, form); return expr.eval(); - } } + } catch(Throwable e) { if(!(e instanceof CompilerException)) @@ -4949,6 +4960,23 @@ public static void pushNS(){ Symbol.create("*ns*")), null)); } +static void compile1(GeneratorAdapter gen, FnExpr fn, Object form) throws Exception{ + form = macroexpand(form); + if(form instanceof IPersistentCollection && Util.equals(RT.first(form), DO)) { + for(ISeq s = RT.next(form); s != null; s = RT.next(s)) { + compile1(gen, fn, RT.first(s)); + } + } + else { + Expr expr = analyze(C.EVAL, form); + fn.keywords = (IPersistentMap) KEYWORDS.deref(); + fn.vars = (IPersistentMap) VARS.deref(); + fn.constants = (PersistentVector) CONSTANTS.deref(); + expr.emit(C.EXPRESSION, fn, gen); + expr.eval(); + } +} + public static Object compile(Reader rdr, String sourcePath, String sourceName) throws Exception{ if(COMPILE_PATH.deref() == null) throw new Exception("*compile-path* not set"); @@ -4992,14 +5020,9 @@ public static Object compile(Reader rdr, String sourcePath, String sourceName) t for(Object r = LispReader.read(pushbackReader, false, EOF, false); r != EOF; r = LispReader.read(pushbackReader, false, EOF, false)) { - LINE_AFTER.set(pushbackReader.getLineNumber()); - Expr expr = analyze(C.EVAL, r); - fn.keywords = (IPersistentMap) KEYWORDS.deref(); - fn.vars = (IPersistentMap) VARS.deref(); - fn.constants = (PersistentVector) CONSTANTS.deref(); - expr.emit(C.EXPRESSION, fn, gen); - expr.eval(); - LINE_BEFORE.set(pushbackReader.getLineNumber()); + LINE_AFTER.set(pushbackReader.getLineNumber()); + compile1(gen, fn, r); + LINE_BEFORE.set(pushbackReader.getLineNumber()); } //end of load gen.returnValue(); |