mokeheheのScheme日記

ツッコミ、添削大歓迎です。いろいろ教えてください。

2008-01-27

Lispでいうところのコンパイルって、マシン語になるの?

Lispでいうところのコンパイルって、ネイティブマシン語に落ちるんじゃなくてバイトコードになるだけだよね?Lispのコードがマシン語に落ちるところを想像できないんだけど…。xyzzyもそうだし503 Service Unavailable gauche仮想マシンで実行してるし。

と思ってたらGCLというGNUのCommonLispは、コンパイルするとCのソースを吐き出すらしい。マジで?単にバイトコードを実行するCソースが出るとかじゃなくて、例えば if がちゃんと分岐になったりするのかな?

小っちゃい処理系

俺にも理解できるような、小っちゃい処理系を探す。2ちゃんスレのテンプレから

CAMPUS LIsP
  • 1000行。わかりやすい。
  • マクロなし
TinyScheme
  • コンパイルして動いた
  • ソースファイルはほぼ1つだけど、4500行もあって、おっかない。
  • TinySchemeは、MiniSchemeを元に作られてるとのこと
MiniScheme
  • 1ファイルだけ。2400行。
  • coded by Atsushi Moriwaki (11/5/1989)
  • Revised by Akira KIDA
AMScheme
  • Atsushi Moriwaki Lisp
  • 内容的にはこっちのほうが古いのかな?
  • R4RS
  • ソースが小分けになっているので、場合によってはこっちのほうが理解しやすいかも。
KIScheme
  • 日本語コメントなので安心
bit

バッククォート

同じくR5RSの「4.2.6 準引用」に、「(quasiquote (foo bar))」 で「`(foo bar)」、「(unquote a)」で「,a」、「(unquote-splicing a)」で「,@a」と同じと書いてある。

関数引数

R5RS の「4.1.4 手続き」を読んでいて、

((lambda x x) 3 4 5 6)  ;=> (3 4 5 6)

とできることを知った。関数への引数destructuring-bind されてるってことかな?

gosh> ((lambda (x (y) . z) (list x y z)) 'a '(b) 'c 'd)
*** ERROR: unbound variable: y

違うのか。

また、コロンで残り引数を受け取れる

((lambda (x y . z) z) 3 4 5 6)  ;=> (5 6)

「&rest rest」じゃなくていいんだね。ま、これだと0個以上の引数を受け取る関数は定義できませんが。

たけおかたけおか2008/07/27 20:18通りすがりの者です(もう、ここはチェックしないかも)
&& Optimization of GCL/KCL を書いている者です。

> コンパイラどうなってんだ?
CommonLispならコンパイルそのものは、あんまり難しくありませんよ。直感どおりにコードを生成すればよし。インタープリタからの呼び出しも、難しくはないはず。
問題は、実行中のLispインタープリタに、コンパイルした機械語コードをリンクする、いわゆる「インクリメンタル・リンク」を実現するテクニックです。それは、OSや、リンカを十分に理解していないと、うまく実装できないでしょう。
また、もっと本質的に難しいのは、ガーベジ・コレクタが動いたときに、コンパイルド・コードとうまく共存するかです。すごく単純に言うと、コンパイルド・コードが一時的に、リスト(など)のポインタを機械語レジスタの置いたときに、ガーベジ・コレクタが、そのレジスタをチェックしないと、矛盾が生じる、というような問題が出るので。

トラックバック - http://sicp.g.hatena.ne.jp/mokehehe/20080127