Как получить значения в 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. Вы можете сообщить полный ответ здесь как ответ на свой вопрос.

Другие вопросы по тегам