从终端命令提示符运行Common Lisp函数

时间:2013-11-30 14:56:39

标签: lisp common-lisp sbcl

我很难找到答案,所以也许这是不可能的。我希望能够灵活地从命令行加载/编译lisp文件,即不在emacs内部,然后也可以从命令行运行该文件中的一个lisp函数。这无疑是实现特定的功能,因此任何提供此功能的实现的指针(或者它可能是相当标准的,我不知道)。我正在使用SBCL并喜欢它,所以如果可以做到这一点会很棒。

我也在使用Mac OSX和终端。

4 个答案:

答案 0 :(得分:21)

SBCL手册描述了三个有用的选项

  

3.3.1 Runtime Options

     

--noinform
  禁止打印任何横幅或其他横幅   启动时的信息性消息。这使得编写Lisp变得更容易   在Unix管道中干净利落的程序。另见--noprint   和--disable-debugger选项。

  

3.3.2 Toplevel Options

     

--eval command
  执行任何初始化文件后,但在标准输入上启动read-eval-print循环之前,请阅读并评估   给出的命令。可以使用多个--eval选项,以及所有选项   将按照它们出现在命令中的顺序读取和执行   线。

     

--load filename
  这相当于--eval '(load "filename")'。特殊语法旨在减少调用时引用的问题   来自shell脚本的SBCL。

给定文件test.lisp,内容为

(defun hello-world ()
  (print 'hello-world)
  (terpri))

我们可以用SBCL做到这一点:

$ sbcl --noinform --load test.lisp --eval '(progn (hello-world) (sb-ext:quit))'

HELLO-WORLD 

(progn ... (sb-ext:quit))确保程序在执行(hello-world)后结束。否则你会被放入SBCL提示符。由于代码是在SBCL中自动编译的,因此运行的函数已经在运行(hello-world)时编译。如果您事先编译了文件,则可以将编译后的文件传递给--load。例如,

$ sbcl --noinform --load test.fasl --eval '(hello-world)'

HELLO-WORLD 

事实上,考虑到--load--eval (load "filename")的等价,你可以只使用文件名的基础,如果有编译版本,那么SBCL应该加载它,如果没有,然后SBCL将加载源文件,你将以这种方式获得编译代码。例如,在下文中,我们仅使用--load test

$ sbcl --noinform --load test --eval '(hello-world)'

HELLO-WORLD 

答案 1 :(得分:4)

以下内容来自first google result

  

CLISP

     

如果您正在使用CLISP Common Lisp环境,则以下情况适用。

     

要将名为test.lisp的程序编译为名为test.fas的字节码文件,请执行以下操作。

     

clisp -c test.lisp

     

如果您希望显示较少的输出,请执行以下操作。

     

clisp -q -c test.lisp

     

要运行已编译的(或者甚至是未编译的,如果跳过上述步骤)Lisp文件,请执行以下操作,假设您的入口函数名为main。通常,main函数的结果会在完成时显示,但是(quit)命令会阻止它。 -on-error abort选项可防止clisp进入调试提示,并在出现错误时退出。

     

clisp -q -q -on-error abort -x'(progn(load“test”)(main)(quit))'

我刚刚在我的arch linux终端上测试了它,你可以执行以下操作:

$ clisp myprogram.lisp

这将在终端中运行程序。如果您想将其编译为稍后运行,请参阅上面的内容。

答案 2 :(得分:1)

正如其他人所表明的那样,几乎所有的实现都通过终端运行一些Lisp代码。还有一些包装器为许多实现提供了一个通用接口:CIMcl-launch

答案 3 :(得分:1)

我正在尝试通过knitr将#use-cases-nav .resources-links .active Common-Lisp集成到R中。 以下是一些有关如何将评估请求发送到sbcl并将其返回给R的测试。这适用于发送表单而不是文件。在终端上:

sbcl
;; 120

sbcl --noinform --eval '(progn (print (* 2 3 4 5)) (sb-ext:quit))'
;; HELLO-WORLD

sbcl --noinform --eval '(progn (print (* 2 3 4 5)) (sb-ext:quit))'
;; 0
;; 1
;; 2
;; 3
;; 4