java - ABCL 的解释器可以从 InputStream 加载 Lisp 源吗?
问题描述
我刚刚开始研究ABCL以将一些 Lisp 混合到 Java 中。现在,从文件中加载一些 Lisp 就足够了,我一直在查看示例。在每种情况下,模式都是:
Interpreter interpreter = Interpreter.createInstance();
interpreter.eval("(load \"lispfunctions.lisp\")");
lispfunctions.lisp
但是假设我正在构建一个 Maven 项目,以打包为JAR:我该如何加载src/main/resources
?我可以很容易地得到一个InputStream
——我可以带着它去某个地方吗?或者我在这里缺少另一个习惯用法来从这样的资源加载 Lisp 源代码?
解决方案
我已经完成了以下工作。我在 MacOS 上使用 ABCL 1.7.0,尽管我很确定这不是特定于版本的。
/* 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 确实被定义了。
我知道这些东西可能有点晦涩;我很乐意尝试回答任何问题。
推荐阅读
- r - Stargazer 未发布回归表
- c - 为什么当 i 较小时此代码有效,但当 i 较大时会出现分段错误?
- javascript - 来自 Laravel 后端的 Angular Formbuilder 验证
- angular - angular.json 排除开发构建的资产
- c++ - 以升序对链接列表进行排序并打印已排序的列表
- javascript - res.send 与 forEach 循环
- node.js - 使用级联删除 typeorm 中的 many2many 实体
- ansible - 如何在 ansible playbook 中的用户给定主机上运行用户给定的命令?
- sql - 如何为我的数据库中的所有表创建视图
- python - Plotly:更改森伯斯特图中元素的顺序