summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2007-09-02 22:58:53 +0000
committerRich Hickey <richhickey@gmail.com>2007-09-02 22:58:53 +0000
commit44e91204bbc4a8bf8217cb8b2eea14de94e6b9d2 (patch)
treef6b300945618b7a24181d10a27e4c64f7b3e0b1f /src
parent2115153ec692d1393c654b6a60be2a395ef1beb2 (diff)
added quote
Diffstat (limited to 'src')
-rw-r--r--src/jvm/clojure/lang/BytecodeCompiler.java43
-rw-r--r--src/jvm/clojure/lang/DynamicClassLoader.java11
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);
+}
+
}