commit e90f5e01b120169d78e65f2344779c181e189559
parent 101bc47198243e7c91907426102eb4a141275ac8
Author: tomas <tomas@logand.com>
Date: Fri, 30 Oct 2009 23:28:18 +0100
full dynamic dispatch to java implemented
Diffstat:
M | wl.java | | | 111 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------- |
1 file changed, 82 insertions(+), 29 deletions(-)
diff --git a/wl.java b/wl.java
@@ -436,7 +436,7 @@ class wl implements Runnable {
return lc.length < rc.length ? 1 : -1;
}
}
- class LtC implements Comparator<Constructor> { // code reuse in Java;-{
+ class LtC implements Comparator<Constructor> {
public int compare(Constructor l, Constructor r) {
// most specific first
Class[] lc = l.getParameterTypes();
@@ -449,25 +449,45 @@ class wl implements Runnable {
}
final LtM ltM = new LtM();
final LtC ltC = new LtC();
- boolean isApplicable(Method m, Object[] args) {
+ boolean isInstance(Class c, Any A) {
+ if(byte.class == c || Byte.class == c
+ || short.class == c || Short.class == c
+ || int.class == c || Integer.class == c
+ || long.class == c || Long.class == c
+ || float.class == c || Float.class == c
+ || double.class == c || Double.class == c) {
+ Object o = A.obj();
+ return A.isOnum()
+ || o instanceof Byte || o instanceof Short
+ || o instanceof Integer || o instanceof Long
+ || o instanceof Float || o instanceof Double;
+ }
+ if(boolean.class == c || Boolean.class == c) return true;
+ if(char.class == c || Character.class == c) {
+ if(A.isOstr()) return 1 == ((String) A.obj()).length();
+ else return A.isIsym() && 1 == A.nm().length();
+ }
+ return c.isInstance(A.isIsym() ? A.nm() : A.obj());
+ }
+ boolean isApplicable(Method m, Any[] a) {
Class[] c = m.getParameterTypes();
- if(c.length != args.length) return false; // nargs must be same
+ if(c.length != a.length) return false; // nargs must be same
for(int i = 0; i < c.length; i++)
- if(!c[i].isInstance(args[i])) // must be instanceof
- if(args[i] != null || !Object.class.equals(c[i]))
+ if(!isInstance(c[i], a[i])) // must be instanceof
+ if(a[i] != null || !Object.class.equals(c[i]))
return false;
return true;
}
- boolean isApplicable(Constructor m, Object[] args) {
+ boolean isApplicable(Constructor m, Any[] a) {
Class[] c = m.getParameterTypes();
- if(c.length != args.length) return false; // nargs must be same
+ if(c.length != a.length) return false; // nargs must be same
for(int i = 0; i < c.length; i++)
- if(!c[i].isInstance(args[i])) // must be instanceof
- if(args[i] != null || !Object.class.equals(c[i]))
+ if(!isInstance(c[i], a[i])) // must be instanceof
+ if(a[i] != null || !Object.class.equals(c[i]))
return false;
return true;
}
- Method applicableMethod(Class c, String nm, Object[] aa) {
+ Method applicableMethod(Class c, String nm, Any[] a) {
//Method m = c.getMethod(nm, ta);
// sort methods
@@ -479,13 +499,13 @@ class wl implements Runnable {
// apply first (most specific) applicable method
Method m = null;
for(Method method: methods)
- if(isApplicable(method, aa)) {
+ if(isApplicable(method, a)) {
m = method;
break;
}
return m;
}
- Constructor applicableConstructor(Class c, Object[] aa) {
+ Constructor applicableConstructor(Class c, Any[] a) {
//Constructor c = ((Class) C.obj()).getConstructor(ta);
// sort methods
@@ -496,31 +516,61 @@ class wl implements Runnable {
// apply first (most specific) applicable method
Constructor m = null;
for(Constructor method: methods)
- if(isApplicable(method, aa)) {
+ if(isApplicable(method, a)) {
m = method;
break;
}
return m;
}
+ Object jarg(Class c, Any A) {
+ if(byte.class == c || Byte.class == c)
+ return A.isOnum() ? ((BigInteger) A.obj()).byteValue() : A.obj();
+ if(short.class == c || Short.class == c)
+ return A.isOnum() ? ((BigInteger) A.obj()).shortValue() : A.obj();
+ if(int.class == c || Integer.class == c)
+ return A.isOnum() ? ((BigInteger) A.obj()).intValue() : A.obj();
+ if(long.class == c || Long.class == c)
+ return A.isOnum() ? ((BigInteger) A.obj()).longValue() : A.obj();
+ if(float.class == c || Float.class == c)
+ return A.isOnum() ? ((BigInteger) A.obj()).floatValue() : A.obj();
+ if(double.class == c || Double.class == c)
+ return A.isOnum() ? ((BigInteger) A.obj()).doubleValue() : A.obj();
+ if(boolean.class == c || Boolean.class == c) return NIL != A;
+ if(char.class == c || Character.class == c)
+ return (A.isOstr() ? (String) A.obj() : A.nm()).charAt(0);
+ if(A.isIsym()) return A.nm();
+ return A.obj();
+ }
+ Object[] methodArgs(Method m, Any[] a) {
+ Class[] c = m.getParameterTypes();
+ Object[] z = new Object[a.length];
+ for(int i = 0; i < c.length; i++)
+ z[i] = jarg(c[i], a[i]);
+ return z;
+ }
+ Object[] constructorArgs(Constructor m, Any[] a) {
+ Class[] c = m.getParameterTypes();
+ Object[] z = new Object[a.length];
+ for(int i = 0; i < c.length; i++)
+ z[i] = jarg(c[i], a[i]);
+ return z;
+ }
Any applyO(Any E, Any O) { // 'obj 'meth [arg ...]
Any I = E.cdr();
Any F = eval(I.car());
Any A = I.cdr();
Any Z = NIL;
- ArrayList<Object> a = new ArrayList();
- for(Any X = A; NIL != X; X = X.cdr()) {
- Any Y = eval(X.car());
- Object y = Y.isIsym() ? Y.nm() : Y.obj();
- a.add(y);
- }
+ ArrayList<Any> a = new ArrayList();
+ for(Any X = A; NIL != X; X = X.cdr())
+ a.add(eval(X.car()));
Object o = O.obj();
Class c = o instanceof Class ? (Class) o : o.getClass();
String nm = F.isOstr() ? (String) F.obj() : F.nm();
- Object[] aa = a.toArray();
+ Any[] aa = a.toArray(new Any[a.size()]);
try {
Method m = applicableMethod(c, nm, aa);
if(null == m) err(E, "No applicable method");
- Object r = m.invoke(o, aa);
+ Object r = m.invoke(o, methodArgs(m, aa));
Z = mkObj(r);
} catch(IllegalAccessException e) {
err(E, "IllegalAccessException");
@@ -631,6 +681,11 @@ class wl implements Runnable {
else err("Don't know how to lt");
return z;
}
+ // Any box(Any X) {
+ // Any Z = mkIsym(null, X);
+ // Z.nm(Z.toString());
+ // return Z;
+ // }
final wl Wl = this;
final BlockingQueue<Any> Que = new LinkedBlockingQueue<Any>();
@@ -1060,23 +1115,21 @@ class wl implements Runnable {
}
return Z;
}});
+ // fn("box", new Fn() {public Any fn(Any E) {return box(eval(E.cdr().car()));}});
fn("jnew", new Fn() {public Any fn(Any E) { // jnew 'cls [arg ...]
Any I = E.cdr();
Any C = eval(I.car());
Any A = I.cdr();
Any Z = NIL;
ArrayList<Object> a = new ArrayList();
- for(Any X = A; NIL != X; X = X.cdr()) {
- Any Y = eval(X.car());
- Object y = Y.isIsym() ? Y.nm() : Y.obj();
- a.add(y);
- }
+ for(Any X = A; NIL != X; X = X.cdr())
+ a.add(eval(X.car()));
Class c = (Class) C.obj();
- Object[] aa = a.toArray();
+ Any[] aa = a.toArray(new Any[a.size()]);
try {
Constructor m = applicableConstructor(c, aa);
if(null == m) err(E, "No applicable constructor");
- Object r = m.newInstance(aa);
+ Object r = m.newInstance(constructorArgs(m, aa));
Z = mkObj(r);
} catch(InstantiationException e) {
err(E, "InstantiationException");
@@ -1120,7 +1173,7 @@ class wl implements Runnable {
I = I.cdr();
}
ClassLoader l = this.getClass().getClassLoader();
- Class[] c = (Class[]) a.toArray(new Class[a.size()]);
+ Class[] c = a.toArray(new Class[a.size()]);
InvocationHandler h = new InvocationHandler() {
public Object invoke(Object p, Method m, Object[] a)
throws Throwable {