7

Haskell 的main函数正是我想要的:评估文件何时自行加载(例如./myfile.hsor runhaskell myfile.hs)而不是其他情况。main当文件被另一个文件导入时不会被调用。newLISP也有这个功能。

Common Lisp 有等效的代码吗?

我阅读了CLISP 的源代码clisp myfile.lisp以下是用户输入or时发生的情况./myfile.lisp

  1. CLISP 保存myfile.lispp->argv_execute_file.
  2. CLISP 创建表达式(LOAD "p->argv_execute_file")并将其压入 Lisp 堆栈。
  3. CLISP 将任何附加的命令行参数保存在一个列表中。
  4. CLISP 将参数存储在 Lisp 变量*args*中。

CLISP 从不生成引用 的 Lisp 变量p->argv_execute_file,因此无法辨别myfile.lisp是由 REPL 中的用户直接加载,还是由另一个 Lisp 文件加载。如果只是(car *args*)myfile.lisp我的任务会很容易。

注意:如果文件是从 REPL 加载的,Shebangs 会给 CLISP 带来麻烦,所以我把这段代码放在~/.clisprc.lisp

(set-dispatch-macro-character #\# #\!
 (lambda (stream character n)
  (declare (ignore character n))
  (read-line stream nil nil t)
  nil))
4

2 回答 2

2

我找到了解决方案。这是一个shell技巧,但它有效。我将很快对其进行修改,使其适用于 CLISP 以外的 CL 实现。

#!/bin/sh
#|
exec clisp -q -q $0 $0 ${1+"$@"}
exit
|#

;;; Usage: ./scriptedmain.lisp

(defun main (args)
 (format t "Hello World!~%")
 (quit))

;;; With help from Francois-Rene Rideau
;;; http://tinyurl.com/cli-args
(let ((args
       #+clisp ext:*args*
       #+sbcl sb-ext:*posix-argv*
       #+clozure (ccl::command-line-arguments)
       #+gcl si:*command-args*
       #+ecl (loop for i from 0 below (si:argc) collect (si:argv i))
       #+cmu extensions:*command-line-strings*
       #+allegro (sys:command-line-arguments)
       #+lispworks sys:*line-arguments-list*
     ))

  (if (member (pathname-name *load-truename*)
              args
              :test #'(lambda (x y) (search x y :test #'equalp)))
    (main args)))
于 2010-11-29T00:50:47.747 回答
0

(eval-when (situation*) ...)

更新对不起令人困惑的答案。

我可能是错的,但似乎不可能完全按照你的意愿去做。我会制作一个 shell 脚本并调用clisp -i myfile.lisp -x (main).

是否有任何理由不使其可执行(在此处描述)?

PS Common Lisp 是一种语言,clisp也是其中一种实现。

于 2010-11-26T14:09:12.610 回答