Next: 12 Jscheme 5.0
Up: ソフトウェア特論 講義資料 JavaによるScheme言語処理系: Jscheme
Previous: 10 Pairクラス
PrimitiveクラスのApplyメソッドの中で呼ばれているJavaMethod
クラスの定義です.
package jscheme;
import java.lang.reflect.*;
/** @author Peter Norvig,
* peter@norvig.com http://www.norvig.com
* Copyright 1998 Peter Norvig,
* see http://www.norvig.com/license.html */
public class JavaMethod extends Procedure {
Class[] argClasses;
Method method;
boolean isStatic;
public JavaMethod(String methodName,
Object targetClassName,
Object argClassNames) {
this.name =
targetClassName + "." + methodName;
try {
argClasses = classArray(argClassNames);
method =
toClass(targetClassName).
getMethod(methodName,
argClasses);
isStatic =
Modifier.isStatic(method.getModifiers());
} catch (ClassNotFoundException e) {
error("Bad class, can't get method " + name);
} catch (NoSuchMethodException e) {
error("Can't get method " + name);
}
}
/** Apply the method to a list of arguments. **/
public Object apply(Scheme interpreter,
Object args) {
try {
if (isStatic)
return method.invoke(null, toArray(args));
else
return method.invoke(first(args),
toArray(rest(args)));
} catch (IllegalAccessException e) { ; }
catch (IllegalArgumentException e) { ; }
catch (InvocationTargetException e) { ; }
catch (NullPointerException e) { ; }
return error("Bad Java Method application:" + this
+ stringify(args) + ", ");
}
public static Class toClass(Object arg)
throws ClassNotFoundException {
if (arg instanceof Class) return (Class)arg;
arg = stringify(arg, false);
if (arg.equals("void"))
return java.lang.Void.TYPE;
else if (arg.equals("boolean"))
return java.lang.Boolean.TYPE;
else if (arg.equals("char"))
return java.lang.Character.TYPE;
else if (arg.equals("byte"))
return java.lang.Byte.TYPE;
else if (arg.equals("short"))
return java.lang.Short.TYPE;
else if (arg.equals("int"))
return java.lang.Integer.TYPE;
else if (arg.equals("long"))
return java.lang.Long.TYPE;
else if (arg.equals("float"))
return java.lang.Float.TYPE;
else if (arg.equals("double"))
return java.lang.Double.TYPE;
else return Class.forName((String)arg);
}
/** Convert a list of Objects into an array.
* Peek at the argClasses
* array to see what's expected.
* That enables us to convert between
* Double and Integer,
* something Java won't do automatically. **/
public Object[] toArray(Object args) {
int n = length(args);
int diff = n - argClasses.length;
if (diff != 0)
error(Math.abs(diff) + " too " +
((diff>0) ? "many" : "few")
+ " args to " + name);
Object[] array = new Object[n];
for(int i = 0;
i < n && i < argClasses.length; i++) {
if (argClasses[i] ==
java.lang.Integer.TYPE)
array[i] =
new Integer((int)num(first(args)));
else
array[i] = first(args);
args = rest(args);
}
return array;
}
/** Convert a list of class names into
an array of Classes. **/
public Class[] classArray(Object args)
throws ClassNotFoundException {
int n = length(args);
Class[] array = new Class[n];
for(int i = 0; i < n; i++) {
array[i] = toClass(first(args));
args = rest(args);
}
return array;
}
}
generated through LaTeX2HTML. M.Inaba 平成18年5月6日