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 {