summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2009-05-16 20:18:43 +0000
committerRich Hickey <richhickey@gmail.com>2009-05-16 20:18:43 +0000
commitdbb85aafafc90a9b6021ef58c5cd4bd8a20600fc (patch)
treee21a8308865b640816846ab8d7b70fe3ae4595bc /src
parent939976735ea071cb00944b066392ab8b8d749918 (diff)
do unrolls at top-level
Diffstat (limited to 'src')
-rw-r--r--src/clj/clojure/core.clj19
-rw-r--r--src/jvm/clojure/lang/Compiler.java57
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();