public class ABCL {
private static Interpreter interpreter;
private static boolean invertCase = false;
private static Function makeWebServiceArgs;
private static int lispRelease = 0;
private static boolean once = true;
public static void init() { // only called once
interpreter = Interpreter.createInstance();
invertCase();
load("com/xxx/lisp/clos-utils");
load("com/xxx/lisp/package-lru");
load("com/xxx/lisp/utils");
load("com/xxx/lisp/mappings");
makeWebServiceArgs = findLispFunction("UTILS", "make-web-service-args"); // this line is repeated in multiple places
}
private static void invertCase() {
interpreter.eval("(setf (readtable-case *readtable*) :invert)"); // make lisp case sensitive
invertCase = true;
}
public static String fixCase(String symbol) {
if (invertCase) {
int ucl = 0, lcl = 0;
char[] vec = symbol.toCharArray();
for (int i=0 ; i < vec.length && (ucl == 0 || lcl == 0) ; i++)
if (Character.isUpperCase(vec[i]))
ucl++;
else if (Character.isLowerCase(vec[i]))
lcl++;
if (ucl != 0 && lcl != 0 || ucl == 0 && lcl == 0)
return symbol;
else
if (ucl != 0)
return symbol.toLowerCase();
else
return symbol.toUpperCase();
} else
return symbol.toUpperCase();
}
public static void reset() {
// if (interpreter == null)
// return;
// try {
// interpreter.eval("(delete-package \"ARAHANT-UTILS\")");
// } catch (Throwable t) {
// }
if (interpreter == null)
return;
try {
interpreter.eval("(delete-package \"MAPPINGS\")");
} catch (Throwable t) {
}
if (interpreter == null)
return;
try {
interpreter.eval("(delete-package \"UTILS\")");
} catch (Throwable t) {
}
if (interpreter == null)
return;
try {
interpreter.eval("(delete-package \"PACKAGE-LRU\")");
} catch (Throwable t) {
}
if (interpreter == null)
return;
try {
interpreter.eval("(delete-package \"CLOS-UTILS\")");
} catch (Throwable t) {
}
load("com/xxx/lisp/clos-utils");
load("com/xxx/lisp/package-lru");
load("com/xxx/lisp/utils");
load("com/xxx/lisp/mappings");
makeWebServiceArgs = findLispFunction("UTILS", "make-web-service-args"); // this line is repeated in multiple places
}
public static LispObject load(String fileName) {
return eval("(load \"" + FileSystemUtils.getSourcePath() + fileName + "\")");
}
public static LispObject compileFile(String fileName) {
return eval("(compile-file \"" + FileSystemUtils.getSourcePath() + fileName + "\")");
}
public static void loadPackage(String lispPackage, String fileName) throws Exception {
try {
eval("(package-lru:load-package \"" + lispPackage + "\" \"" + FileSystemUtils.getSourcePath() + fileName + "\")");
} catch (Throwable t) {
// Convert Throwable to Exception
throw new Exception("Error loading lisp file " + fileName, t);
}
}
public static void packageDone(String lispPackage) {
if (FileSystemUtils.isUnderIDE())
eval("(package-lru:package-done-unload \"" + lispPackage + "\")");
else
eval("(package-lru:package-done \"" + lispPackage + "\")");
}
public static LispObject eval(String str) {
return interpreter.eval(str);
}
public static Function findLispFunction(String packageName, String funName) {
if (packageName == null || packageName.isEmpty())
packageName = "CL-USER";
// else
// packageName = fixCase(packageName);
org.armedbear.lisp.Package lispPackage = Packages.findPackage(packageName);
if (lispPackage == null)
throw new RuntimeException("Package " + packageName + " not found");
Symbol symbol = lispPackage.findAccessibleSymbol(fixCase(funName));
if (symbol == null)
throw new RuntimeException("Symbol " + packageName + ":" + fixCase(funName) + " not found");
Function fun = (Function) symbol.getSymbolFunction();
return fun;
}
public static LispObject executeLispFunction(Function fun, Object ... args) {
LispObject [] jargs;
jargs = new LispObject[args.length];
for (int i=0 ; i < args.length ; i++)
jargs[i] = JavaObject.getInstance(args[i], true);
return fun.execute(jargs);
}
public static LispObject executeLisp(String packageName, String funName, Object ... args) {
Function fun = findLispFunction(packageName, funName);
if (fun == null)
return null;
LispObject [] jargs;
jargs = new LispObject[args.length];
for (int i=0 ; i < args.length ; i++)
jargs[i] = JavaObject.getInstance(args[i], true);
return fun.execute(jargs);
}
public static LispObject executeLispArray(String packageName, String funName, Object [] args) {
Function fun = findLispFunction(packageName, funName);
if (fun == null)
return null;
LispObject [] jargs;
jargs = new LispObject[args.length];
for (int i=0 ; i < args.length ; i++)
jargs[i] = JavaObject.getInstance(args[i], true);
return fun.execute(jargs);
}
public static Function getMakeWebServiceArgs() {
return makeWebServiceArgs;
}
@SuppressWarnings("unchecked")
public static Object LispObjectToJavaObject(LispObject obj) {
if (obj.atom())
if (obj.characterp())
return obj.princToString().charAt(0);
else if (obj.stringp())
return obj.princToString();
else if (obj.integerp())
return obj.intValue();
else if (obj.realp())
return obj.doubleValue();
else if (obj.listp())
return null;
else if (obj.constantp())
return true;
else
return obj.princToString();
else if (obj.listp()) {
LinkedList ll = new LinkedList();
while (!obj.endp()) {
ll.addLast(LispObjectToJavaObject(obj.car()));
obj = obj.cdr();
}
return ll;
} else if (obj.vectorp()) {
int len = obj.length();
Object [] vec = new Object[len];
for (int i=0 ; i < len ; i++)
vec[i] = LispObjectToJavaObject(obj.AREF(i));
return vec;
} else
return null;
}
public static LispObject JavaObjectToLispObject(Object jobj) {
if (jobj instanceof Boolean)
return ((Boolean)jobj) ? Lisp.T : Lisp.NIL;
else if (jobj instanceof Character)
return LispCharacter.getInstance((Character)jobj);
else if (jobj instanceof Short)
return LispInteger.getInstance((Short)jobj);
else if (jobj instanceof Integer)
return LispInteger.getInstance((Integer)jobj);
else if (jobj instanceof Long)
return LispInteger.getInstance((Long)jobj);
else if (jobj instanceof Float)
return SingleFloat.getInstance((Float)jobj);
else if (jobj instanceof Double)
return DoubleFloat.getInstance((Double)jobj);
else if (jobj instanceof String)
return new SimpleString((String)jobj);
else if (jobj instanceof StringBuilder)
return new SimpleString((StringBuilder)jobj);
else if (jobj instanceof LinkedList) {
LispObject lobj = Lisp.NIL;
ListIterator it = ((LinkedList) jobj).listIterator();
while (it.hasNext())
lobj = new Cons(JavaObjectToLispObject(it.next()), lobj);
return lobj;
} else if (jobj instanceof Set) {
LispObject lobj = Lisp.NIL;
Iterator it = ((Set) jobj).iterator();
while (it.hasNext())
lobj = new Cons(JavaObjectToLispObject(it.next()), lobj);
return lobj;
} else if (jobj instanceof Array) {
Array a = (Array) jobj;
int len = Array.getLength(a);
SimpleVector vec = new SimpleVector(len);
for (int i=0 ; i < len ; i++)
vec.setSlotValue(i, JavaObjectToLispObject(Array.get(a, i)));
return null;
}
return null;
}
public static void printStackTrace(Throwable e) {
try {
Function fun = findLispFunction("UTILS", "print-stack-trace");
if (fun != null) {
LispObject stackTrace = LispThread.currentThread().backtrace(0);
if (stackTrace != null && stackTrace != Lisp.NIL) {
System.err.println("Lisp execution error");
fun.execute(stackTrace);
}
}
} catch (Throwable t) {
}
e.printStackTrace();
}
public static int getLispRelease() {
return lispRelease;
}
public static void setLispRelease(int lispRelease) {
ABCL.lispRelease = lispRelease;
}
}