Может ли интерпретатор ABCL загрузить исходный текст Lisp из InputStream?

Я только начал смотреть на ABCL, чтобы смешать немного Lisp с Java. На данный момент достаточно загрузить немного Lisp из файла, и я просмотрел примеры. В любом случае шаблон следующий:

Interpreter interpreter = Interpreter.createInstance();
interpreter.eval("(load \"lispfunctions.lisp\")");

Но скажем, я создаю проект Maven с целью упаковки в виде JAR: как я могу загрузить lispfunctions.lisp от src/main/resources? Я легко могу получитьInputStreamâ € ”могу я пойти куда-нибудь с этим? Или есть еще одна идиома, которую мне здесь не хватает для загрузки исходного кода Lisp с такого ресурса?

1 ответ

Решение

Я получил следующие результаты. Я работаю с ABCL 1.7.0 на MacOS, хотя уверен, что это не зависит от версии.

/* load_lisp_within_jar.java -- use ABCL to load Lisp file as resource in jar
 * copyright 2020 by Robert Dodier
 * I release this work under terms of the GNU General Public License
 */

/* To run this example:
$ javac -cp /path/to/abcl.jar -d . load_lisp_within_jar.java
$ cat << EOF > foo.lisp
(defun f (x) (1+ x))
EOF
$ jar cvf load_lisp_within_jar.jar load_lisp_within_jar.class foo.lisp
$ java -cp load_lisp_within_jar.jar:/path/to/abcl.jar load_lisp_within_jar
 *
 * Expected output:
(F 100) => 101
 */
import org.armedbear.lisp.*;
import java.io.*;

public class load_lisp_within_jar {
    public static void main (String [] args) {
        try {
            // It appears that interpreter instance is required even though
            // it isn't used directly; I guess it arranges global resources.
            Interpreter I = Interpreter.createInstance ();

            LispObject LOAD_function = Symbol.LOAD.getSymbolFunction ();

            // Obtain an input stream for Lisp source code in jar.
            ClassLoader L = load_lisp_within_jar.class.getClassLoader ();
            InputStream f = L.getResourceAsStream ("foo.lisp");
            Stream S = new Stream (Symbol.SYSTEM_STREAM, f, Symbol.CHARACTER);

            // Call COMMON-LISP:LOAD with input stream as argument.
            LOAD_function.execute (S);

            // Verify that function F has been defined.
            Symbol F = Packages.findPackage ("COMMON-LISP-USER").findAccessibleSymbol ("F");
            LispObject F_function = F.getSymbolFunction ();
            LispObject x = F_function.execute (LispInteger.getInstance (100));
            System.out.println ("(F 100) => " + x.javaInstance ());
        }
        catch (Exception e) {
            System.err.println ("oops: " + e);
            e.printStackTrace ();
        }
    }
}

Как видите, программа сначала получает функцию, связанную с символом LOAD. (Для удобства многие, а может и все символы COMMON-LISP имеют статические определения, поэтому вы можете просто сказатьSymbol.LOAD вместо поиска символа через findAccessibleSymbol.) Затем входной поток передается в функцию загрузки. После этого мы проверяем, что наша функция F действительно определена.

Я знаю, что все это может быть непонятным; Буду рад ответить на любые вопросы.

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