diff options
author | Rich Hickey <richhickey@gmail.com> | 2008-04-05 22:30:01 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2008-04-05 22:30:01 +0000 |
commit | ee2250dd7a5b6d6c99d276fa333ca663a555f5e8 (patch) | |
tree | ed1bcbcd6d55013f2ca88c470a82b98866a55ac5 | |
parent | dd837d94fca1f502f62def7d734d98bff3b0b20a (diff) |
phase 2 enhanced host calls, (.member target ...), (target.member ...), and (classname. ctor-args) macroexpansions
-rw-r--r-- | src/boot.clj | 14 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Compiler.java | 62 |
2 files changed, 58 insertions, 18 deletions
diff --git a/src/boot.clj b/src/boot.clj index 208db231..a0bd71ae 100644 --- a/src/boot.clj +++ b/src/boot.clj @@ -1587,21 +1587,17 @@ not-every? (comp not every?)) "If form represents a macro form, returns its expansion, else returns form." [form] - (let [v (and (seq? form) (. clojure.lang.Compiler (isMacro (first form))))] - (if v - (apply @v (rest form)) - form))) + (. clojure.lang.Compiler (macroexpand1 form))) (defn macroexpand "Repeatedly calls macroexpand-1 on form until it no longer represents a macro form, then returns it. Note neither macroexpand-1 nor macroexpand expand macros in subforms." [form] - (let [ex (macroexpand-1 form) - v (and (seq? ex) (. clojure.lang.Compiler (isMacro (first ex))))] - (if v - (macroexpand ex) - ex))) + (let [ex (macroexpand-1 form)] + (if (identical? ex form) + form + (macroexpand ex)))) (defn create-struct "Returns a structure basis object." diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java index 15b7afcf..f18a9602 100644 --- a/src/jvm/clojure/lang/Compiler.java +++ b/src/jvm/clojure/lang/Compiler.java @@ -698,7 +698,7 @@ static public abstract class HostExpr implements Expr{ } else { - ISeq call = (ISeq) ((RT.third(form) instanceof ISeq)?RT.third(form):RT.rest(RT.rest(form))); + ISeq call = (ISeq) ((RT.third(form) instanceof ISeq) ? RT.third(form) : RT.rest(RT.rest(form))); if(!(RT.first(call) instanceof Symbol)) throw new IllegalArgumentException("Malformed member expression"); Symbol sym = (Symbol) RT.first(call); @@ -3341,15 +3341,13 @@ static public Var isMacro(Object op) throws Exception{ return null; } -private static Expr analyzeSeq(C context, ISeq form, String name) throws Exception{ - Integer line = (Integer) LINE.get(); - try +public static Object macroexpand1(Object x) throws Exception{ + if(x instanceof ISeq) { - if(RT.meta(form) != null && RT.meta(form).containsKey(RT.LINE_KEY)) - line = (Integer) RT.meta(form).valAt(RT.LINE_KEY); - Var.pushThreadBindings( - RT.map(LINE, line)); + ISeq form = (ISeq) x; Object op = RT.first(form); + if(isSpecial(op)) + return x; //macro expansion Var v = isMacro(op); if(v != null) @@ -3357,13 +3355,59 @@ private static Expr analyzeSeq(C context, ISeq form, String name) throws Excepti try { Var.pushThreadBindings(RT.map(RT.MACRO_META, ((IObj) form).meta())); - return analyze(context, v.applyTo(form.rest())); + return v.applyTo(form.rest()); } finally { Var.popThreadBindings(); } } + else + { + if(op instanceof Symbol) + { + Symbol sym = (Symbol) op; + String sname = sym.name; + //(.substring s 2 5) => (. s substring 2 5) + if(sym.name.charAt(0) == '.') + { + Symbol meth = Symbol.intern(sname.substring(1)); + return RT.listStar(DOT, RT.second(form), meth, form.rest().rest()); + } + else + { + //(s.substring 2 5) => (. s substring 2 5) + int idx = sname.indexOf('.'); + if(idx > 0 && idx < sname.length() - 1 && idx == sname.lastIndexOf('.')) + { + Symbol target = Symbol.intern(sname.substring(0, idx)); + Symbol meth = Symbol.intern(sname.substring(idx + 1)); + return RT.listStar(DOT, target, meth, form.rest()); + } + //(StringBuilder. "foo") => (new StringBuilder "foo") + else if(idx == sname.length() - 1) + return RT.listStar(NEW, Symbol.intern(sname.substring(0, idx)), form.rest()); + } + } + } + } + return x; +} + +private static Expr analyzeSeq(C context, ISeq form, String name) throws Exception{ + Integer line = (Integer) LINE.get(); + try + { + if(RT.meta(form) != null && RT.meta(form).containsKey(RT.LINE_KEY)) + line = (Integer) RT.meta(form).valAt(RT.LINE_KEY); + Var.pushThreadBindings( + RT.map(LINE, line)); + + Object me = macroexpand1(form); + if(me != form) + return analyze(context, me); + + Object op = RT.first(form); IParser p; if(op.equals(FN)) return FnExpr.parse(context, form, name); |