summaryrefslogtreecommitdiff
path: root/src/jvm/clojure
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2008-04-05 22:30:01 +0000
committerRich Hickey <richhickey@gmail.com>2008-04-05 22:30:01 +0000
commitee2250dd7a5b6d6c99d276fa333ca663a555f5e8 (patch)
treeed1bcbcd6d55013f2ca88c470a82b98866a55ac5 /src/jvm/clojure
parentdd837d94fca1f502f62def7d734d98bff3b0b20a (diff)
phase 2 enhanced host calls, (.member target ...), (target.member ...), and (classname. ctor-args) macroexpansions
Diffstat (limited to 'src/jvm/clojure')
-rw-r--r--src/jvm/clojure/lang/Compiler.java62
1 files changed, 53 insertions, 9 deletions
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);