diff options
author | Rich Hickey <richhickey@gmail.com> | 2009-03-03 22:31:55 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2009-03-03 22:31:55 +0000 |
commit | 69728918d3e00f821903e7e12771d4332937e288 (patch) | |
tree | 1d953d1e2f8c1de911d612e751d66d5521789395 | |
parent | 9723a7b5d693bec38dc57269b423094ababa9dd1 (diff) |
restore list constants as PersistentLists
-rw-r--r-- | src/jvm/clojure/lang/Compiler.java | 211 |
1 files changed, 127 insertions, 84 deletions
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java index 0b2b316c..e683da91 100644 --- a/src/jvm/clojure/lang/Compiler.java +++ b/src/jvm/clojure/lang/Compiler.java @@ -3188,90 +3188,133 @@ static public class FnExpr implements Expr{ // getCompiledClass(); } - void emitListAsObjectArray(Object value, GeneratorAdapter gen) { - gen.push(((List)value).size()); - gen.newArray(OBJECT_TYPE); - int i = 0; - for (Iterator it = ((List)value).iterator(); it.hasNext(); i++) { - gen.dup(); - gen.push(i); - emitValue(it.next(), gen); - gen.arrayStore(OBJECT_TYPE); - } - } - - void emitValue(Object value, GeneratorAdapter gen) { - boolean partial = true; - //System.out.println(value.getClass().toString()); - - if (value instanceof String) { - gen.push((String)value); - } else if (value instanceof Integer) { - gen.push(((Integer)value).intValue()); - gen.invokeStatic(Type.getType(Integer.class), Method.getMethod("Integer valueOf(int)")); - } else if (value instanceof Double) { - gen.push(((Double)value).doubleValue()); - gen.invokeStatic(Type.getType(Double.class), Method.getMethod("Double valueOf(double)")); - } else if (value instanceof Character) { - gen.push(((Character)value).charValue()); - gen.invokeStatic(Type.getType(Character.class), Method.getMethod("Character valueOf(char)")); - } else if (value instanceof Class) { - gen.push(((Class)value).getName()); - gen.invokeStatic(Type.getType(Class.class), Method.getMethod("Class forName(String)")); - } else if (value instanceof Symbol) { - gen.push(((Symbol)value).ns); - gen.push(((Symbol)value).name); - gen.invokeStatic(Type.getType(Symbol.class), Method.getMethod("clojure.lang.Symbol create(String,String)")); - } else if (value instanceof Keyword) { - emitValue(((Keyword)value).sym,gen); - gen.invokeStatic(Type.getType(Keyword.class), Method.getMethod("clojure.lang.Keyword intern(clojure.lang.Symbol)")); - } else if (value instanceof Var) { - Var var = (Var) value; - gen.push(var.ns.name.toString()); - gen.push(var.sym.toString()); - gen.invokeStatic(RT_TYPE, Method.getMethod("clojure.lang.Var var(String,String)")); - } else if (value instanceof IPersistentMap) { - List entries = new ArrayList(); - for (Map.Entry entry : (Set<Map.Entry>) ((Map)value).entrySet()) { - entries.add(entry.getKey()); - entries.add(entry.getValue()); - } - emitListAsObjectArray(entries, gen); - gen.invokeStatic(RT_TYPE, Method.getMethod("clojure.lang.IPersistentMap map(Object[])")); - } else if (value instanceof IPersistentVector) { - emitListAsObjectArray(value, gen); - gen.invokeStatic(RT_TYPE, Method.getMethod("clojure.lang.IPersistentVector vector(Object[])")); - } else if (value instanceof ISeq || value instanceof IPersistentList) { - emitListAsObjectArray(value, gen); - gen.invokeStatic(RT_TYPE, Method.getMethod("clojure.lang.ISeq arrayToList(Object[])")); - } else { - String cs = null; - try { - cs = RT.printString(value); - //System.out.println("WARNING SLOW CODE: " + value.getClass() + " -> " + cs); - } catch (Exception e) { - throw new RuntimeException("Can't embed object in code, maybe print-dup not defined: " + value); - } - if (cs.length() == 0) - throw new RuntimeException("Can't embed unreadable object in code: " + value); - - if (cs.startsWith("#<")) - throw new RuntimeException("Can't embed unreadable object in code: " + cs); - - gen.push(cs); - gen.invokeStatic(RT_TYPE, readStringMethod); - partial = false; - } - - if (partial) { - if (value instanceof Obj && RT.count(((Obj)value).meta()) > 0) { - gen.checkCast(IOBJ_TYPE); - emitValue(((Obj)value).meta(), gen); - gen.checkCast(IPERSISTENTMAP_TYPE); - gen.invokeInterface(IOBJ_TYPE, Method.getMethod("clojure.lang.IObj withMeta(clojure.lang.IPersistentMap)")); - } - } - } + void emitListAsObjectArray(Object value, GeneratorAdapter gen){ + gen.push(((List) value).size()); + gen.newArray(OBJECT_TYPE); + int i = 0; + for(Iterator it = ((List) value).iterator(); it.hasNext(); i++) + { + gen.dup(); + gen.push(i); + emitValue(it.next(), gen); + gen.arrayStore(OBJECT_TYPE); + } + } + + void emitValue(Object value, GeneratorAdapter gen){ + boolean partial = true; + //System.out.println(value.getClass().toString()); + + if(value instanceof String) + { + gen.push((String) value); + } + else if(value instanceof Integer) + { + gen.push(((Integer) value).intValue()); + gen.invokeStatic(Type.getType(Integer.class), Method.getMethod("Integer valueOf(int)")); + } + else if(value instanceof Double) + { + gen.push(((Double) value).doubleValue()); + gen.invokeStatic(Type.getType(Double.class), Method.getMethod("Double valueOf(double)")); + } + else if(value instanceof Character) + { + gen.push(((Character) value).charValue()); + gen.invokeStatic(Type.getType(Character.class), Method.getMethod("Character valueOf(char)")); + } + else if(value instanceof Class) + { + gen.push(((Class) value).getName()); + gen.invokeStatic(Type.getType(Class.class), Method.getMethod("Class forName(String)")); + } + else if(value instanceof Symbol) + { + gen.push(((Symbol) value).ns); + gen.push(((Symbol) value).name); + gen.invokeStatic(Type.getType(Symbol.class), + Method.getMethod("clojure.lang.Symbol create(String,String)")); + } + else if(value instanceof Keyword) + { + emitValue(((Keyword) value).sym, gen); + gen.invokeStatic(Type.getType(Keyword.class), + Method.getMethod("clojure.lang.Keyword intern(clojure.lang.Symbol)")); + } + else if(value instanceof Var) + { + Var var = (Var) value; + gen.push(var.ns.name.toString()); + gen.push(var.sym.toString()); + gen.invokeStatic(RT_TYPE, Method.getMethod("clojure.lang.Var var(String,String)")); + } + else if(value instanceof IPersistentMap) + { + List entries = new ArrayList(); + for(Map.Entry entry : (Set<Map.Entry>) ((Map) value).entrySet()) + { + entries.add(entry.getKey()); + entries.add(entry.getValue()); + } + emitListAsObjectArray(entries, gen); + gen.invokeStatic(RT_TYPE, + Method.getMethod("clojure.lang.IPersistentMap map(Object[])")); + } + else if(value instanceof IPersistentVector) + { + emitListAsObjectArray(value, gen); + gen.invokeStatic(RT_TYPE, Method.getMethod( + "clojure.lang.IPersistentVector vector(Object[])")); + } + else if(value instanceof ISeq || value instanceof IPersistentList) + { + emitListAsObjectArray(value, gen); + gen.invokeStatic(Type.getType(java.util.Arrays.class), + Method.getMethod("java.util.List asList(Object[])")); + gen.invokeStatic(Type.getType(PersistentList.class), + Method.getMethod( + "clojure.lang.IPersistentList create(java.util.List)")); + } + else + { + String cs = null; + try + { + cs = RT.printString(value); + //System.out.println("WARNING SLOW CODE: " + value.getClass() + " -> " + cs); + } + catch(Exception e) + { + throw new RuntimeException( + "Can't embed object in code, maybe print-dup not defined: " + + value); + } + if(cs.length() == 0) + throw new RuntimeException( + "Can't embed unreadable object in code: " + value); + + if(cs.startsWith("#<")) + throw new RuntimeException( + "Can't embed unreadable object in code: " + cs); + + gen.push(cs); + gen.invokeStatic(RT_TYPE, readStringMethod); + partial = false; + } + + if(partial) + { + if(value instanceof Obj && RT.count(((Obj) value).meta()) > 0) + { + gen.checkCast(IOBJ_TYPE); + emitValue(((Obj) value).meta(), gen); + gen.checkCast(IPERSISTENTMAP_TYPE); + gen.invokeInterface(IOBJ_TYPE, + Method.getMethod("clojure.lang.IObj withMeta(clojure.lang.IPersistentMap)")); + } + } + } void emitConstants(GeneratorAdapter clinitgen){ |