3

我正在从一个 shell 脚本调用一个 Lisp 函数(以及其他一些东西)。为简洁起见,以下是脚本的相关部分:

./gcl -load /tmp/calendrica-3.0.cl -batch -eval '(格式 T "~a" (CC3::sunset (CC3::fixed-from-gregorian (CC3::gregorian-date 1996 CC3:: 2 月 25 日)) CC3::jerusalem))' 728714.7349874675

上面的代码工作正常,但我必须为每个使用的符号附加包名 CC3;这使得代码笨拙且难以键入。

我试图像这样简化它,使用use-package

./gcl -load /tmp/calendrica-3.0.cl -batch -eval '(format T "~a" (use-package "CC3") (sunset (fixed-from-gregorian (gregorian-date 1996 february 25))耶路撒冷))'

更容易阅读和输入,但不幸的是它不起作用。我已经尝试了各种方法来包含该use-package指令,但到目前为止还没有成功。

通过 GNU Common Lisp (gcl) 的加载指令启动 Lisp 程序时甚至可以包含use-package指令吗?

更新: 解决方案是按照接受的答案的建议使用多个评估。

./gcl -load /tmp/calendrica-3.0.cl -batch -eval '(use-package "CC3")' -eval '(format T "~a" (sunset (fixed-from-gregorian (gregorian-date 1996 2 月 25 日))耶路撒冷))”

4

2 回答 2

6

也许你可以使用多个 eval,这就是我对 sbcl 所做的。

#!/bin/sh
sbcl --noinform \
   --eval '(load "boot.lisp")' \
   --eval '(in-package #:my-pkg)' \
   --eval "(do-something-useful)" # do-something-useful is in my-pkg
于 2015-02-05T18:00:39.237 回答
3

也许可以这样做,但它会很丑陋。

如果你给它一个表单表单评估,它会先读取表单。因此,在评估期间更改阅读器(告诉新包,...)为时已晚。因此需要提前完成。

CL-USER 1 > (eval (read-from-string "(foo::bar)"))
Error: Reader cannot find package FOO.

Better:

CL-USER 5 > (eval '(progn (defpackage foo (:use "CL"))
                          (read-from-string "(foo::bar)")))
(FOO::BAR)

因此,如果您想将单个表单传递给 eval,您将编写它首先创建包,然后从以表单编码的字符串读取/评估。棘手。

备择方案:

  • 也许 Lisp 在启动时允许-eval多种形式?做任何你需要初始化 Lisp 的事情,以了解第一种-eval形式的包。然后让代码以第二种形式执行。

  • 写一个文件并将必要的表格放在那里。加载它。由于一个文件可以包含多个表单,因此您可以在顶部放置DEFPACKAGE,IN-PACKAGE或类似的,然后根据它在文件中放置其余代码。

于 2015-02-05T10:34:23.010 回答