commit 2004f07abad444dbed83584edd10d32e4d3a227b
parent 4daa94954d15e88d1dc9db0a639cca1b47676cd0
Author: tomas <tomas@logand.com>
Date: Wed, 21 Oct 2009 00:08:44 +0200
In static+close(),'jnew' constr dyn dispatch,'read',needLength in out load
Diffstat:
M | java.wl | | | 22 | ++++++++++++---------- |
M | wl.java | | | 111 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------ |
2 files changed, 90 insertions(+), 43 deletions(-)
diff --git a/java.wl b/java.wl
@@ -321,8 +321,10 @@
# | cdr | map | maplist | mapcon |
# | car prop | maps | - | - |
+(de needLength (L) (foldl '((X Y) (cons NIL X)) NIL L))
+
(de map (F . @)
- (let (L (rest) M NIL A (need (length L)) B NIL E)
+ (let (L (rest) M NIL A (needLength L) B NIL E)
(loop
(setq M L B A E T)
(while M
@@ -335,7 +337,7 @@
(apply F A) ) ) )
(de mapc (F . @)
- (let (L (rest) M NIL A (need (length L)) B NIL E)
+ (let (L (rest) M NIL A (needLength L) B NIL E)
(loop
(setq M L B A E T)
(while M
@@ -347,7 +349,7 @@
(apply F A) ) ) )
(de mapcan (F . @)
- (let (L (rest) M NIL A (need (length L)) B NIL E)
+ (let (L (rest) M NIL A (needLength L) B NIL E)
(make
(loop
(setq M L B A E T)
@@ -360,7 +362,7 @@
(chain (apply F A)) ) ) ) )
(de mapcar (F . @)
- (let (L (rest) M NIL A (need (length L)) B NIL E)
+ (let (L (rest) M NIL A (needLength L) B NIL E)
(make
(loop
(setq M L B A E T)
@@ -373,7 +375,7 @@
(link (apply F A)) ) ) ) )
(de mapcon (F . @)
- (let (L (rest) M NIL A (need (length L)) B NIL E)
+ (let (L (rest) M NIL A (needLength L) B NIL E)
(make
(loop
(setq M L B A E T)
@@ -387,7 +389,7 @@
(chain (apply F A)) ) ) ) )
(de maplist (F . @)
- (let (L (rest) M NIL A (need (length L)) B NIL E)
+ (let (L (rest) M NIL A (needLength L) B NIL E)
(make
(loop
(setq M L B A E T)
@@ -406,17 +408,17 @@
(de in (F . P)
(let *In (jnew `(jclass 'wl$In) (jnew `(jclass 'java.io.FileInputStream) F))
(finally (*In 'close)
- (run P 1) ) ) )
+ (run P 1 '(*In)) ) ) ) # TODO
(de out (F . P)
(let *Out (jnew `(jclass 'java.io.PrintStream)
(jnew `(jclass 'java.io.FileOutputStream) F) )
(finally (*Out 'close)
- (run P 1) ) ) )
+ (run P 1 '(*Out)) ) ) ) # TODO
(de load @
- (for F (rest)
- (in F
+ (while (args)
+ (in (next)
(finally ()
(while (read)
(eval @ 1) ) ) ) ) )
diff --git a/wl.java b/wl.java
@@ -21,6 +21,7 @@ import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationHandler;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
+import java.io.IOException;
class wl implements Runnable {
@@ -195,11 +196,18 @@ class wl implements Runnable {
final Any At = mkIsym("@", NIL);
final Any Args = mkIsym("*Args", NIL);
- public class In {
+ public static class In {
InputStream s;
int b; // -2 ~ unbound, -1 ~ eof, otherwise 0--255
Character c; // null ~ NIL
public In(InputStream S) {s = S; clear();}
+ public void close() {
+ try {
+ s.close();
+ } catch(IOException e) {
+ err("Error closing wl$In");
+ }
+ }
void clear() {b = -2; c = null;}
public boolean eof() {return b == -1;}
public void eof(Any X) {if(NIL != X) b = -1;}
@@ -411,7 +419,7 @@ class wl implements Runnable {
}
// runtime dispatch
- class MethodComparator implements Comparator<Method> {
+ class LtM implements Comparator<Method> {
public int compare(Method l, Method r) {
// most specific first
Class[] lc = l.getParameterTypes();
@@ -422,7 +430,19 @@ class wl implements Runnable {
return lc.length < rc.length ? 1 : -1;
}
}
- final MethodComparator methodComparator = new MethodComparator();
+ class LtC implements Comparator<Constructor> { // code reuse in Java;-{
+ public int compare(Constructor l, Constructor r) {
+ // most specific first
+ Class[] lc = l.getParameterTypes();
+ Class[] rc = r.getParameterTypes();
+ for(int i = 0, j = 0; i < lc.length && j < rc.length; i++, j++)
+ if(!lc[i].equals(rc[i]) && lc[i].isAssignableFrom(rc[i]))
+ return 1;
+ return lc.length < rc.length ? 1 : -1;
+ }
+ }
+ final LtM ltM = new LtM();
+ final LtC ltC = new LtC();
boolean isApplicable(Method m, Object[] args) {
Class[] c = m.getParameterTypes();
if(c.length != args.length) return false; // nargs must be same
@@ -432,41 +452,67 @@ class wl implements Runnable {
return false;
return true;
}
+ boolean isApplicable(Constructor m, Object[] args) {
+ Class[] c = m.getParameterTypes();
+ if(c.length != args.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]))
+ return false;
+ return true;
+ }
+ Method applicableMethod(Class c, String nm, Object[] aa) {
+ //Method m = c.getMethod(nm, ta);
+
+ // sort methods
+ final List<Method> methods = new LinkedList<Method>();
+ for(Method m: c.getMethods())
+ if(m.getName().equals(nm))
+ methods.add(m);
+ Collections.sort(methods, ltM);
+ // apply first (most specific) applicable method
+ Method m = null;
+ for(Method method: methods)
+ if(isApplicable(method, aa)) {
+ m = method;
+ break;
+ }
+ return m;
+ }
+ Constructor applicableConstructor(Class c, Object[] aa) {
+ //Constructor c = ((Class) C.obj()).getConstructor(ta);
+
+ // sort methods
+ final List<Constructor> methods = new LinkedList<Constructor>();
+ for(Constructor m: c.getConstructors())
+ methods.add(m);
+ Collections.sort(methods, ltC);
+ // apply first (most specific) applicable method
+ Constructor m = null;
+ for(Constructor method: methods)
+ if(isApplicable(method, aa)) {
+ m = method;
+ break;
+ }
+ return m;
+ }
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();
- ArrayList<Class> t = 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);
- t.add(y.getClass());
}
+ 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();
- Class[] ta = (Class[]) t.toArray(new Class[aa.length]);
try {
- Object o = O.obj();
- Class c = o instanceof Class ? (Class) o : o.getClass();
- String nm = F.isOstr() ? (String) F.obj() : F.nm();
- //Method m = c.getMethod(nm, ta);
- //Object r = m.invoke(o, aa);
-
- // sort methods
- final List<Method> methods = new LinkedList<Method>();
- for(Method m: c.getMethods())
- if(m.getName().equals(nm))
- methods.add(m);
- Collections.sort(methods, methodComparator);
- // apply first (most specific) applicable method
- Method m = null;
- for(Method method: methods)
- if(isApplicable(method, aa)) {
- m = method;
- break;
- }
+ Method m = applicableMethod(c, nm, aa);
if(null == m) err(E, "No applicable method");
Object r = m.invoke(o, aa);
Z = mkObj(r);
@@ -899,22 +945,18 @@ class wl implements Runnable {
Any A = I.cdr();
Any Z = NIL;
ArrayList<Object> a = new ArrayList();
- ArrayList<Class> t = 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);
- t.add(y.getClass());
}
+ Class c = (Class) C.obj();
Object[] aa = a.toArray();
- Class[] ta = (Class[]) t.toArray(new Class[aa.length]);
try {
- // TODO might need dynamic dispatch here too
- Constructor c = ((Class) C.obj()).getConstructor(ta);
- Object r = c.newInstance(aa);
+ Constructor m = applicableConstructor(c, aa);
+ if(null == m) err(E, "No applicable constructor");
+ Object r = m.newInstance(aa);
Z = mkObj(r);
- } catch(NoSuchMethodException e) {
- err(E, "NoSuchMethodException");
} catch(InstantiationException e) {
err(E, "InstantiationException");
} catch(IllegalAccessException e) {
@@ -1030,6 +1072,9 @@ class wl implements Runnable {
}
return Z;
}});
+ fn("read", new Fn() {public Any fn(Any E) { // TODO
+ return read1(true);
+ }});
}
void print(Any E) {