diff options
author | Rich Hickey <richhickey@gmail.com> | 2009-11-25 16:11:43 -0500 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2009-11-25 16:11:43 -0500 |
commit | c88ba226d4d64529dee3120719e48e0b08439eaa (patch) | |
tree | ab132cf6903bac82e30c9464f34aa9ee8512d944 /src/jvm | |
parent | 4d08439a9cf79f34a730714f12edd5959aae126e (diff) | |
parent | 5f9df70163bd9c7a168c1ef8cd2be67651401f29 (diff) |
Merge branch 'master' into new
Diffstat (limited to 'src/jvm')
-rw-r--r-- | src/jvm/clojure/lang/Compiler.java | 63 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Numbers.java | 140 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentTreeSet.java | 27 |
3 files changed, 208 insertions, 22 deletions
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java index 060ce4d6..c9fd7acf 100644 --- a/src/jvm/clojure/lang/Compiler.java +++ b/src/jvm/clojure/lang/Compiler.java @@ -384,7 +384,7 @@ static class DefExpr implements Expr{ else if(RT.count(form) < 2) throw new Exception("Too few arguments to def"); else if(!(RT.second(form) instanceof Symbol)) - throw new Exception("Second argument to def must be a Symbol"); + throw new Exception("First argument to def must be a Symbol"); Symbol sym = (Symbol) RT.second(form); Var v = lookupVar(sym, true); if(v == null) @@ -775,10 +775,11 @@ static public abstract class HostExpr implements Expr, MaybePrimitiveExpr{ if(maybeField) //field { Symbol sym = (Symbol) RT.third(form); - if(c != null) - return new StaticFieldExpr(line, c, sym.name); - else - return new InstanceFieldExpr(line, instance, sym.name); + Symbol tag = tagOf(form); + if(c != null) { + return new StaticFieldExpr(line, c, sym.name, tag); + } else + return new InstanceFieldExpr(line, instance, sym.name, tag); } else { @@ -786,13 +787,14 @@ static public abstract class HostExpr implements Expr, MaybePrimitiveExpr{ if(!(RT.first(call) instanceof Symbol)) throw new IllegalArgumentException("Malformed member expression"); Symbol sym = (Symbol) RT.first(call); + Symbol tag = tagOf(form); PersistentVector args = PersistentVector.EMPTY; for(ISeq s = RT.next(call); s != null; s = s.next()) args = args.cons(analyze(context == C.EVAL ? context : C.EXPRESSION, s.first())); if(c != null) - return new StaticMethodExpr(source, line, c, sym.name, args); + return new StaticMethodExpr(source, line, tag, c, sym.name, args); else - return new InstanceMethodExpr(source, line, instance, sym.name, args); + return new InstanceMethodExpr(source, line, tag, instance, sym.name, args); } } } @@ -887,16 +889,18 @@ static class InstanceFieldExpr extends FieldExpr implements AssignableExpr{ public final java.lang.reflect.Field field; public final String fieldName; public final int line; + public final Symbol tag; final static Method invokeNoArgInstanceMember = Method.getMethod("Object invokeNoArgInstanceMember(Object,String)"); final static Method setInstanceFieldMethod = Method.getMethod("Object setInstanceField(Object,String,Object)"); - public InstanceFieldExpr(int line, Expr target, String fieldName) throws Exception{ + public InstanceFieldExpr(int line, Expr target, String fieldName, Symbol tag) throws Exception{ this.target = target; this.targetClass = target.hasJavaClass() ? target.getJavaClass() : null; this.field = targetClass != null ? Reflector.getField(targetClass, fieldName, false) : null; this.fieldName = fieldName; this.line = line; + this.tag = tag; if(field == null && RT.booleanCast(RT.WARN_ON_REFLECTION.deref())) { ((PrintWriter) RT.ERR.deref()) @@ -951,11 +955,11 @@ static class InstanceFieldExpr extends FieldExpr implements AssignableExpr{ } public boolean hasJavaClass() throws Exception{ - return field != null; + return field != null || tag != null; } public Class getJavaClass() throws Exception{ - return field.getType(); + return tag != null ? HostExpr.tagToClass(tag) : field.getType(); } public Object evalAssign(Expr val) throws Exception{ @@ -991,17 +995,19 @@ static class StaticFieldExpr extends FieldExpr implements AssignableExpr{ public final String fieldName; public final Class c; public final java.lang.reflect.Field field; + public final Symbol tag; // final static Method getStaticFieldMethod = Method.getMethod("Object getStaticField(String,String)"); // final static Method setStaticFieldMethod = Method.getMethod("Object setStaticField(String,String,Object)"); final int line; - public StaticFieldExpr(int line, Class c, String fieldName) throws Exception{ + public StaticFieldExpr(int line, Class c, String fieldName, Symbol tag) throws Exception{ //this.className = className; this.fieldName = fieldName; this.line = line; //c = Class.forName(className); this.c = c; field = c.getField(fieldName); + this.tag = tag; } public Object eval() throws Exception{ @@ -1039,7 +1045,7 @@ static class StaticFieldExpr extends FieldExpr implements AssignableExpr{ public Class getJavaClass() throws Exception{ //Class c = Class.forName(className); //java.lang.reflect.Field field = c.getField(fieldName); - return field.getType(); + return tag != null ? HostExpr.tagToClass(tag) : field.getType(); } public Object evalAssign(Expr val) throws Exception{ @@ -1122,19 +1128,21 @@ static class InstanceMethodExpr extends MethodExpr{ public final IPersistentVector args; public final String source; public final int line; + public final Symbol tag; public final java.lang.reflect.Method method; final static Method invokeInstanceMethodMethod = Method.getMethod("Object invokeInstanceMethod(Object,String,Object[])"); - public InstanceMethodExpr(String source, int line, Expr target, String methodName, IPersistentVector args) + public InstanceMethodExpr(String source, int line, Symbol tag, Expr target, String methodName, IPersistentVector args) throws Exception{ this.source = source; this.line = line; this.args = args; this.methodName = methodName; this.target = target; + this.tag = tag; if(target.hasJavaClass() && target.getJavaClass() != null) { List methods = Reflector.getMethods(target.getJavaClass(), args.count(), methodName, false); @@ -1268,11 +1276,11 @@ static class InstanceMethodExpr extends MethodExpr{ } public boolean hasJavaClass(){ - return method != null; + return method != null || tag != null; } public Class getJavaClass() throws Exception{ - return method.getReturnType(); + return tag != null ? HostExpr.tagToClass(tag) : method.getReturnType(); } } @@ -1285,18 +1293,20 @@ static class StaticMethodExpr extends MethodExpr{ public final String source; public final int line; public final java.lang.reflect.Method method; + public final Symbol tag; final static Method forNameMethod = Method.getMethod("Class forName(String)"); final static Method invokeStaticMethodMethod = Method.getMethod("Object invokeStaticMethod(Class,String,Object[])"); - public StaticMethodExpr(String source, int line, Class c, String methodName, IPersistentVector args) + public StaticMethodExpr(String source, int line, Symbol tag, Class c, String methodName, IPersistentVector args) throws Exception{ this.c = c; this.methodName = methodName; this.args = args; this.source = source; this.line = line; + this.tag = tag; List methods = Reflector.getMethods(c, args.count(), methodName, true); if(methods.isEmpty()) @@ -1405,11 +1415,11 @@ static class StaticMethodExpr extends MethodExpr{ } public boolean hasJavaClass(){ - return method != null; + return method != null || tag != null; } public Class getJavaClass() throws Exception{ - return method.getReturnType(); + return tag != null ? HostExpr.tagToClass(tag) : method.getReturnType(); } } @@ -4932,6 +4942,15 @@ public static boolean namesStaticMember(Symbol sym){ return sym.ns != null && namespaceFor(sym) == null; } +public static Object preserveTag(ISeq src, Object dst) { + Symbol tag = tagOf(src); + if (tag != null && dst instanceof IObj) { + IPersistentMap meta = RT.meta(dst); + return ((IObj) dst).withMeta((IPersistentMap) RT.assoc(meta, RT.TAG_KEY, tag)); + } + return dst; +} + public static Object macroexpand1(Object x) throws Exception{ if(x instanceof ISeq) { @@ -4971,7 +4990,7 @@ public static Object macroexpand1(Object x) throws Exception{ { target = ((IObj)RT.list(IDENTITY, target)).withMeta(RT.map(RT.TAG_KEY,CLASS)); } - return RT.listStar(DOT, target, meth, form.next().next()); + return preserveTag(form, RT.listStar(DOT, target, meth, form.next().next())); } else if(namesStaticMember(sym)) { @@ -4980,7 +4999,7 @@ public static Object macroexpand1(Object x) throws Exception{ if(c != null) { Symbol meth = Symbol.intern(sym.name); - return RT.listStar(DOT, target, meth, form.next()); + return preserveTag(form, RT.listStar(DOT, target, meth, form.next())); } } else @@ -5029,7 +5048,7 @@ private static Expr analyzeSeq(C context, ISeq form, String name) throws Excepti throw new IllegalArgumentException("Can't call nil"); IFn inline = isInline(op, RT.count(RT.next(form))); if(inline != null) - return analyze(context, inline.applyTo(RT.next(form))); + return analyze(context, preserveTag(form, inline.applyTo(RT.next(form)))); IParser p; if(op.equals(FN)) return FnExpr.parse(context, form, name); @@ -5191,7 +5210,7 @@ private static Expr analyzeSymbol(Symbol sym) throws Exception{ if(c != null) { if(Reflector.getField(c, sym.name, true) != null) - return new StaticFieldExpr((Integer) LINE.deref(), c, sym.name); + return new StaticFieldExpr((Integer) LINE.deref(), c, sym.name, tag); throw new Exception("Unable to find static field: " + sym.name + " in " + c); } } diff --git a/src/jvm/clojure/lang/Numbers.java b/src/jvm/clojure/lang/Numbers.java index 8d5fd855..04002085 100644 --- a/src/jvm/clojure/lang/Numbers.java +++ b/src/jvm/clojure/lang/Numbers.java @@ -1537,6 +1537,146 @@ static public long[] long_array(Object sizeOrSeq){ } } +static public short[] short_array(int size, Object init){ + short[] ret = new short[size]; + if(init instanceof Short) + { + short s = (Short) init; + for(int i = 0; i < ret.length; i++) + ret[i] = s; + } + else + { + ISeq s = RT.seq(init); + for(int i = 0; i < size && s != null; i++, s = s.next()) + ret[i] = (Short) s.first(); + } + return ret; +} + +static public short[] short_array(Object sizeOrSeq){ + if(sizeOrSeq instanceof Number) + return new short[((Number) sizeOrSeq).intValue()]; + else + { + ISeq s = RT.seq(sizeOrSeq); + int size = RT.count(s); + short[] ret = new short[size]; + for(int i = 0; i < size && s != null; i++, s = s.next()) + ret[i] = (Short) s.first(); + return ret; + } +} + +static public char[] char_array(int size, Object init){ + char[] ret = new char[size]; + if(init instanceof Character) + { + char c = (Character) init; + for(int i = 0; i < ret.length; i++) + ret[i] = c; + } + else + { + ISeq s = RT.seq(init); + for(int i = 0; i < size && s != null; i++, s = s.next()) + ret[i] = (Character) s.first(); + } + return ret; +} + +static public char[] char_array(Object sizeOrSeq){ + if(sizeOrSeq instanceof Number) + return new char[((Number) sizeOrSeq).intValue()]; + else + { + ISeq s = RT.seq(sizeOrSeq); + int size = RT.count(s); + char[] ret = new char[size]; + for(int i = 0; i < size && s != null; i++, s = s.next()) + ret[i] = (Character) s.first(); + return ret; + } +} + +static public byte[] byte_array(int size, Object init){ + byte[] ret = new byte[size]; + if(init instanceof Byte) + { + byte b = (Byte) init; + for(int i = 0; i < ret.length; i++) + ret[i] = b; + } + else + { + ISeq s = RT.seq(init); + for(int i = 0; i < size && s != null; i++, s = s.next()) + ret[i] = (Byte) s.first(); + } + return ret; +} + +static public byte[] byte_array(Object sizeOrSeq){ + if(sizeOrSeq instanceof Number) + return new byte[((Number) sizeOrSeq).intValue()]; + else + { + ISeq s = RT.seq(sizeOrSeq); + int size = RT.count(s); + byte[] ret = new byte[size]; + for(int i = 0; i < size && s != null; i++, s = s.next()) + ret[i] = (Byte)s.first(); + return ret; + } +} + +static public boolean[] boolean_array(int size, Object init){ + boolean[] ret = new boolean[size]; + if(init instanceof Boolean) + { + boolean b = (Boolean) init; + for(int i = 0; i < ret.length; i++) + ret[i] = b; + } + else + { + ISeq s = RT.seq(init); + for(int i = 0; i < size && s != null; i++, s = s.next()) + ret[i] = (Boolean)s.first(); + } + return ret; +} + +static public boolean[] boolean_array(Object sizeOrSeq){ + if(sizeOrSeq instanceof Number) + return new boolean[((Number) sizeOrSeq).intValue()]; + else + { + ISeq s = RT.seq(sizeOrSeq); + int size = RT.count(s); + boolean[] ret = new boolean[size]; + for(int i = 0; i < size && s != null; i++, s = s.next()) + ret[i] = (Boolean)s.first(); + return ret; + } +} + +static public boolean[] booleans(Object array){ + return (boolean[]) array; +} + +static public byte[] bytes(Object array){ + return (byte[]) array; +} + +static public char[] chars(Object array){ + return (char[]) array; +} + +static public short[] shorts(Object array){ + return (short[]) array; +} + static public float[] floats(Object array){ return (float[]) array; } diff --git a/src/jvm/clojure/lang/PersistentTreeSet.java b/src/jvm/clojure/lang/PersistentTreeSet.java index f6f50125..e7e625de 100644 --- a/src/jvm/clojure/lang/PersistentTreeSet.java +++ b/src/jvm/clojure/lang/PersistentTreeSet.java @@ -27,6 +27,15 @@ public static PersistentTreeSet create(Object... init){ return ret; } +public static PersistentTreeSet create(Comparator comp, Object... init){ + PersistentTreeSet ret = new PersistentTreeSet(null, new PersistentTreeMap(null, comp)); + for(int i = 0; i < init.length; i++) + { + ret = (PersistentTreeSet) ret.cons(init[i]); + } + return ret; +} + public static PersistentTreeSet create(List init){ PersistentTreeSet ret = EMPTY; for(Object key : init) @@ -36,6 +45,15 @@ public static PersistentTreeSet create(List init){ return ret; } +public static PersistentTreeSet create(Comparator comp, List init){ + PersistentTreeSet ret = new PersistentTreeSet(null, new PersistentTreeMap(null, comp)); + for(Object key : init) + { + ret = (PersistentTreeSet) ret.cons(key); + } + return ret; +} + static public PersistentTreeSet create(ISeq items){ PersistentTreeSet ret = EMPTY; for(; items != null; items = items.next()) @@ -45,6 +63,15 @@ static public PersistentTreeSet create(ISeq items){ return ret; } +static public PersistentTreeSet create(Comparator comp, ISeq items){ + PersistentTreeSet ret = new PersistentTreeSet(null, new PersistentTreeMap(null, comp)); + for(; items != null; items = items.next()) + { + ret = (PersistentTreeSet) ret.cons(items.first()); + } + return ret; +} + PersistentTreeSet(IPersistentMap meta, IPersistentMap impl){ super(meta, impl); } |