经过几年的编程,似乎终于攻击SICP了。但是,我不是在Emacs中编辑和运行所有内容,而是使用不同的编辑器和简单的makefile来运行所有练习。这似乎并不完全是正典的,因为我找不到任何像运行文件那样基本的东西,直到“失败”。那么我如何在shell上运行Scheme ,以便它加载一个文件,按顺序计算每个表达式,并在遇到一个评估的语句时终止一个非零的退出代码如果成功评估整个文件,则#f
或退出代码为零?到目前为止最接近解决方案的内容:
$ cat ch1.scm
...
(= 1 2)
$ scheme --load ch1.scm
...
Loading "ch1.scm"... done
1 ]=>
编辑:换句话说,如果其中的任何表达式评估为#f
,是否有一些方法可以在加载ch1.scm期间停止评估?
答案 0 :(得分: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
,则可以使用MIT Scheme从Unix命令行调用它,如下所示:
mit-scheme --load `pwd`/unit.scm --eval '(read-and-test "/Users/aki/code/scratch/test.scm" (the-environment))'
(注意上面有一些与eval
和环境相关的MIT Scheme特定事项)
答案 1 :(得分:0)
我可以想到两种方式。蛮力的方式是编写一个expect
脚本,该脚本将scheme作为一个劣质过程运行,并一次为它提供一行,并检查返回的输出 - 基本上是一个机器人。更优雅的方法是将方案解释器中的顶级REPL替换为表达式求值为#f
时退出的REPL。