9

经过几年的编程,似乎是时候最终攻击SICP 了。但是,与其在 Emacs 中编辑和运行所有内容,我更愿意使用不同的编辑器和一个简单的makefile来运行所有练习。这似乎并不完全是经典,因为在某些“失败”之前,我找不到任何对像运行文件这样基本的东西的引用。那么如何在 shell 上运行 Scheme,以便它加载文件,按顺序评估每个表达式,并在遇到一个评估为或退出代码为零的语句时立即以非零退出代码终止,如果#f整个文件评估成功?到目前为止最接近解决方案的事情:

$ cat ch1.scm
...
(= 1 2)
$ scheme --load ch1.scm
...
Loading "ch1.scm"... done

1 ]=>

编辑:换句话说,如果其中的任何表达式评估为 ch1.s​​cm ,是否有某种方法可以在加载 ch1.s​​cm 期间停止评估#f

4

2 回答 2

5

如果您不想求助于成熟的单元测试库(可以理解),一种选择是编写自己的。您可以使用read从文件中读取 s 表达式,eval用于评估它们并测试它们是否为假,然后返回报告,如果发现错误则退出。像这样的东西应该工作:

(define (read-and-test filename env)
  (call-with-input-file
      filename
    (lambda (in)
      (let loop ((input (read in)))
        (if (eof-object? input)
            (display "done!")
            (begin
              (if (eval input env)
                  (begin
                    (display input)
                    (display " ok")
                    (newline)
                    (loop (read in)))
                  (begin
                    (display "failed on ")
                    (display input)
                    (newline)
                    (exit)))))))))

如果您将上述内容放在一个名为unit.scm的文件中,并且您要测试的文件名为test.scm,您可以从 Unix 命令行使用 MIT Scheme 调用它,如下所示:

mit-scheme --load `pwd`/unit.scm --eval '(read-and-test "/Users/aki/code/scratch/test.scm" (the-environment))'

(请注意,上面有一些 MIT 计划特定的东西,与eval环境相关)

于 2011-08-09T03:40:29.943 回答
0

我可以想到两种方法。蛮力的方法是编写一个expect脚本,将方案作为一个劣质进程运行,一次输入一行并检查返回的输出——基本上,作为一个机器人。更优雅的方法是将方案解释器中的顶级 REPL 替换为如果表达式计算为 则退出的#f

于 2011-08-09T03:19:22.087 回答