From: <as...@ma...> - 2003-10-27 00:33:52
|
On Sun, 26 Oct 2003, Peter Graves wrote: > And I guess you'd probably want > > (setf (jfield class-name field-name instance-ref) value) > > to work for the non-static field case, too. Yes, of course. > > There's no reason why we couldn't implement this in addition to the > "standard" ACL interface. Time for a java.lisp perhaps? Where this, and e.g. def-java-class &al could go? > Looks good. I've committed this (with a bit of reformatting). Thanks! Meanwhile, I realized that jfield should allow a class-ref and (and not just class-name) argument. But I'm not sending a patch now, because I have a more ambitious plan, and if you think it's OK, I'll put everything in one big patch. So: there are a couple of places (jfield, jstatic, jcall,...) where jlinker lets one use arguments that are easily converted to Java instances (fixnums, characters, strings, etc), so that there's no need to use jnew. Now instead of writing if(.. instanceof ..) .. else if (.. instanceof ..) ...'s all over the place, I think that using a small static inner class responsible for these conversion would pay off in the long run: static class LispToJavaConversion { LispToJavaConversion(String className, String targetClassName) { try { getValueMethod = Class.forName(className).getMethod("getValue",null); targetConstructor = Class.forName(targetClassName).getConstructor(new Class[] { getValueMethod.getReturnType() }); lispToJavaConversionMap.put(Class.forName(className),this); } catch (Exception e) { throw new Error("fatal error while loading Java.class"); } } Method getValueMethod; Constructor targetConstructor; static Map lispToJavaConversionMap = new Hashtable(10); static { new LispToJavaConversion("org.armedbear.lisp.Fixnum","java.lang.Integer"); new LispToJavaConversion("org.armedbear.lisp.LispFloat","java.lang.Double"); new LispToJavaConversion("org.armedbear.lisp.LispCharacter","java.lang.Character"); new LispToJavaConversion("org.armedbear.lisp.LispString","java.lang.String"); // etc. } static void set(Field f, Object arg) throws Throwable { try { LispToJavaConversion conv = (LispToJavaConversion) lispToJavaConversionMap.get(arg.getClass()); f.set(null,conv.targetConstructor.newInstance(new Object[] { conv.getValueMethod.invoke(arg,null) })); } catch (Throwable t) { throw t; } } } This one only satisfies jfield's needs, but I guess I can extend it to cater for the others. It lets me write LispToJavaConversion.set(f,args[2]); instead of if (args[2] instanceof Fixnum) f.set(instance,new Integer (((Fixnum)args[2]).getValue())); else if (args[2] instanceof LispFloat) f.set(instance,new Double (((LispFloat)args[2]).getValue())); else ... But it probably increases startup time, and may have other drawbacks, don't know, that's why I'm asking first. Andras |