Scheme Compiler の勉強(37) - printer
ちょっと脱線して、scheme のオブジェクトを出力する機能をコンパイラに組み込む。じかに LLVM で書くのではなくて、Scheme で書いてコンパイルした結果を runtime に組み込むことにした。
リストの外部表現にはドット対(dotted notation)の他、 list notation というのがある。Scheme じゃないけど CLHS 22.1.3.5 http://www.lispworks.com/documentation/HyperSpec/Body/22_ace.htm に丁寧に書かれている。というのを随分前に調べたのだった。
Scheme で20行くらいの $display-pair は、コンパイルされて 130行くらいの LLVM プログラムになる。これを LLVM で最適化すると 50 行くらいになり、PowerPC のアセンブラになると 70 行くらいになった。Scheme 以外はちょっと手で書くのも読むのも嫌になる分量で、これを可能にするのが"コンパイラ"というアイディアなのだなぁと思う。
;; gauche gosh> (cons (cons 1 2) (cons 3 ())) ((1 . 2) 3) ;; 自作コンパイラもどき gosh> (run-program '(cons (cons 1 2) (cons 3 ()))) "((1 . 2) 3)\n" ;; 定義はこんな感じ。 (code (obj top) (if top ($display-char #\()) ($display-obj (car obj)) (if (pair? (cdr obj)) (begin ($display-char #\Space) ($display-pair (cdr obj) #f)) (if (not (null? (cdr obj))) (begin ($display-char #\Space) ($display-char #\.) ($display-char #\Space) ($display-obj (cdr obj))))) (if top ($display-char #\)))) ;;