2011-08-08 46 views
9

经过几年的节目,似乎时间终于出击SICP。但是,我并不想编辑和运行Emacs中的所有内容,而是使用其他编辑器和简单的makefile来运行所有练习。这看起来并不完全正典,因为我找不到任何与运行文件一样基本的东西,除非某些“失败”。那么,如何外壳上运行方案,使其加载一个文件,评估在序列中的每个表情,并尽快与非零退出代码终止,因为它遇到了在评估为#f或退出代码的声明零如果整个文件被评估成功?最接近的事到目前为止的解决方案:运行SICP计划文件,如快速测试失败

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

1 ]=> 

编辑:换句话说,是有一些方法ch1.s​​cm负荷期间做出评价停止,如果任何表达式其中评估为#f

+1

你是不是在寻找像RackUnit(一个单元测试库http://docs.racket-lang.org /rackunit/index.html)? –

+0

这将是最后的手段,因为在像Python和Bash这样的语言中,这将是矫枉过正的。 – l0b0

+1

基本上什么是你想在bash做,可以直接在方案来完成,给我你的方法看起来像矫枉过正:) –

回答

0

我能想到的两种方法。蛮力的方法是编写一个expect脚本,该脚本将运行方案作为低级进程并一次提供一行,并检查返回的输出 - 基本上,它是一个机器人。更优雅的方式是将您的方案解释器中的顶级REPL替换为当表达式计算结果为#f时退出的方法。如果你不希望诉诸一个全面的单元测试库

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 --load `pwd`/unit.scm --eval '(read-and-test "/Users/aki/code/scratch/test.scm" (the-environment))' 

(注意有一些MIT计划具体上面的事,涉及到eval和enviroments)

相关问题