Как получить значения в ABCL, используя Java
Я ищу API для обработки значений в реализации Armed Bear Common Lisp (ABCL) языка Common Lisp в JVM, используя Java.
Это работает, когда функция возвращает (только) список или строку.
Когда он возвращает несколько значений, я могу получить только первое возвращенное значение.
Я не знаю, как получить другие значения.
Это мой файл test.lisp:
(defun get-list ()
(list "abc" 12 'a 'b))
(defun get-value ()
(values "abc" 12 'a 'b))
И мой код Java:
public static void main(String[] args) throws Exception {
Interpreter interpreter = Interpreter.createInstance();
LispObject lobj = interpreter.eval("(load \"test.lisp\")");
org.armedbear.lisp.Package defaultPackage = Packages.findPackage("CL-USER");
Symbol myFunctionSym = defaultPackage.findAccessibleSymbol("GET-LIST");
Function myFunction = (Function) myFunctionSym.getSymbolFunction();
LispObject o = myFunction.execute();
System.out.println(o.listp()); // this return false
Symbol myFunctionSym2 = defaultPackage.findAccessibleSymbol("GET-VALUE");
Function myFunction2 = (Function) myFunctionSym.getSymbolFunction();
LispObject o2 = myFunction.execute();
}
4 ответа
Является multiple-value-bind
или же nth-value
что вы ищете, или есть что-то еще к этому вопросу?
Я думаю, что есть две ошибки копирования вставки с вашим кодом выше (вы хотите использовать myFunctionSym2
а также myFunction2
в последних двух строках, т.е.
Function myFunction2 = (Function) myFunctionSym2.getSymbolFunction();
LispObject o2 = myFunction2.execute();
System.out.println(o2.listp()); // additional line added by me
С этим у меня все работает.
После вызова функции, которая возвращает несколько значений, значения связаны с выполнением LispThread
до следующего звонка в Лисп.
Можно получить доступ к объекту значений в виде списка LispObject
экземпляры через звонок в getValues()
что подтверждается следующим кодом:
org.armedbear.lisp.Package cl = Packages.findPackage("CL");
Symbol valuesSymbol = cl.findAccessibleSymbol("VALUES");
LispObject[] valuesArgs = {
LispInteger.getInstance(1),
LispInteger.getInstance(2)
};
LispObject result = valuesSymbol.execute(valuesArgs);
LispObject[] values = LispThread.currentThread().getValues();
for (LispObject value: values) {
System.out.println("value ==> " + value.printObject());
}
Вы могли бы использовать multiple-value-bind
и т. д. на стороне Lisp назначать отдельным переменным, а затем обращаться к ним по отдельности в Java. Или вы могли бы позвонить multiple-value-bind
с Java. Это не тот ответ, который вы ищете. Я предполагаю, что вам действительно нужен метод, который вы можете вызывать в Java и который будет получать значения, отличные от первого. У меня нет такого ответа, но никто другой не предоставил этот ответ.
Тем не менее, ковыряясь в источнике и в Javadoc, я вижу, что классы Primitives
а также Symbol
есть методы VALUES
а также MULTIPLE_VALUE_BIND
, Я предполагаю, что они не предназначены для вызова в исходном коде пользователя, но они могут, по крайней мере, помочь вам найти нужный ответ.
И, наконец, я думаю, что это может быть то, что вам нужно спросить в списке рассылки ABCL. Вы можете сообщить полный ответ здесь как ответ на свой вопрос.