diff options
author | Rich Hickey <richhickey@gmail.com> | 2007-09-02 22:58:53 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2007-09-02 22:58:53 +0000 |
commit | 44e91204bbc4a8bf8217cb8b2eea14de94e6b9d2 (patch) | |
tree | f6b300945618b7a24181d10a27e4c64f7b3e0b1f /src | |
parent | 2115153ec692d1393c654b6a60be2a395ef1beb2 (diff) |
added quote
Diffstat (limited to 'src')
-rw-r--r-- | src/jvm/clojure/lang/BytecodeCompiler.java | 43 | ||||
-rw-r--r-- | src/jvm/clojure/lang/DynamicClassLoader.java | 11 |
2 files changed, 53 insertions, 1 deletions
diff --git a/src/jvm/clojure/lang/BytecodeCompiler.java b/src/jvm/clojure/lang/BytecodeCompiler.java index 04001490..c109010c 100644 --- a/src/jvm/clojure/lang/BytecodeCompiler.java +++ b/src/jvm/clojure/lang/BytecodeCompiler.java @@ -49,6 +49,7 @@ private static final Type VAR_TYPE = Type.getType(Var.class); private static final Type SYMBOL_TYPE = Type.getType(Symbol.class); private static final Type NUM_TYPE = Type.getType(Num.class); private static final Type IFN_TYPE = Type.getType(IFn.class); +final static Type CLASS_TYPE = Type.getType(Class.class); private static final Type[][] ARG_TYPES; private static final Type[] EXCEPTION_TYPES = {Type.getType(Exception.class)}; @@ -193,6 +194,46 @@ static abstract class LiteralExpr implements Expr{ } } +static class QuoteExpr extends LiteralExpr{ + //stuff quoted vals in classloader at compile time, pull out at runtime + //this won't work for static compilation... + final Object v; + final int id; + final static Type DYNAMIC_CLASSLOADER_TYPE = Type.getType(DynamicClassLoader.class); + final static Method getClassMethod = Method.getMethod("Class getClass()"); + final static Method getClassLoaderMethod = Method.getMethod("ClassLoader getClassLoader()"); + final static Method getQuotedValMethod = Method.getMethod("Object getQuotedVal(int)"); + + public QuoteExpr(int id, Object v){ + this.id = id; + this.v = v; + } + + Object val(){ + return v; + } + + public void emit(C context, FnExpr fn, GeneratorAdapter gen){ + if(context != C.STATEMENT) + { + gen.loadThis(); + gen.invokeVirtual(OBJECT_TYPE, getClassMethod); + gen.invokeVirtual(CLASS_TYPE, getClassLoaderMethod); + gen.checkCast(DYNAMIC_CLASSLOADER_TYPE); + gen.push(id); + gen.invokeVirtual(DYNAMIC_CLASSLOADER_TYPE, getQuotedValMethod); + } + } + + 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 NilExpr extends LiteralExpr{ Object val(){ return null; @@ -1065,6 +1106,8 @@ private static Expr analyzeSeq(C context, ISeq form, String name) throws Excepti 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 return InvokeExpr.parse(context, form); } diff --git a/src/jvm/clojure/lang/DynamicClassLoader.java b/src/jvm/clojure/lang/DynamicClassLoader.java index f3f8ab32..68990b76 100644 --- a/src/jvm/clojure/lang/DynamicClassLoader.java +++ b/src/jvm/clojure/lang/DynamicClassLoader.java @@ -17,7 +17,7 @@ import java.util.HashMap; //todo: possibly extend URLClassLoader? public class DynamicClassLoader extends ClassLoader{ - +HashMap<Integer, Object> quotedVals = new HashMap<Integer, Object>(); HashMap<String, byte[]> map = new HashMap<String, byte[]>(); public DynamicClassLoader(){ @@ -44,4 +44,13 @@ protected Class<?> findClass(String name) throws ClassNotFoundException{ return defineClass(name, bytes, 0, bytes.length); throw new ClassNotFoundException(name); } + +public void registerQuotedVal(int id, Object val){ + quotedVals.put(id, val); +} + +public Object getQuotedVal(int id){ + return quotedVals.get(id); +} + } |