Chicken Compiler

使用方法:

把 Scheme 编译成 C:

比如有一个文件叫 foo.scm.

chicken foo.scm -output-file foo.c

就会把 foo.scm 编译成 foo.c

把 C 编译成机器代码

接着:

gcc foo.c -o foo `chicken-config -cflags -libs`

就编译成了可执行程序。

只检查语法

chicken foo.scm -check-syntax

因为把一个上万行的 Scheme 编译成 C 是一个很漫长的过程,一个 9000 行的 Scheme 翻译成 C 就是 11 万行之多,还没有带运行时的 宏展开机制!

中间一旦有语法错误就全部得重来,所以在你确信语法无误之前可以 先把语法检查一下。

检查语法时,它会把宏全部展开。所以如果这一步能通过,编译应该 就没有问题。

启用 syntax-case

使用选项 -hygienic 可以启用 syntax-case 机制。这样被编译的 文件里的 syntax-case 才能被正确处理。

如果需要在运行时支持 syntax-case, 需要使用 -hygienic-at-run-time 选项。 如果你的程序需要能够在运行时定义一些宏,那么必须起动这个开 关。

否则,你的程序如果想 eval 一个含有宏,比如 "unless" 的文件, 就不能工作!

-hygienic-at-run-time 只包括了 R5RS 的宏机制。如果你想要让所 有宏的实现都能在运行时使用,就在文件里加一句:

(require 'moremacros)

多文件编译

如果一个,文件很长编译时不好管理。这样的话,你可以把程序分开 在几个 scm 文件里,比如:

;;; foo.scm
(declare (uses bar))
(write (fac 10)) (newline)
;;; bar.scm
(declare (unit bar))
(define (fac n)
  (if (zero? n)
      1
      (* n (fac (- n 1))) ) )

foo.scm 调用了 bar.scm 里的函数 fac. bar 是被作为一个库。那 么 bar 要在头部使用 unit 声明

(declare (unit bar))

foo 要在头部使用 use 声明:

(declare (uses bar))

编译时:

% chicken foo.scm -output-file foo.c
% chicken bar.scm -output-file bar.c -explicit-use

对 bar 使用 -explicit-use 参数,这样 bar.c 不会使用库。

然后,把它们编译成目标文件:

% gcc -c foo.c `chicken-config -cflags`
% gcc -c bar.c `chicken-config -cflags`

然后把它们连接在一起:

% gcc foo.o bar.o -o foo `chicken-config -libs`

优化

-optimize-level LEVEL 

可以指定从 0 到 3 的优化级别。

它实际上是一下优化选项的组合:

-optimize-leaf-routines
-lambda-lift

进行两种优化,分别叫做 leaf routine optimization 和 lambda-lifting。

-usual-integrations

它的含义是“就当标准的函数从来没有被重新定义过”。

-unsafe

不在运行时进行安全检查。

Debug

Chicken 编译大文件是需要很多时间的,所以编译这样的文件时最好 使用一些 debug 选项。它们可以指定在 -debug 后的字符串里。我 觉得最有用的是:

-debug 选项作用
t显示需要的时间
b显示一个 pass 已经进行的时间
o显示进行的优化
p显示 pass 信息