K.Sasada's Home Page

Rucheme / Scheme(subset) interpreter on Ruby


What's Rucheme?

(Scheme|Ruby)初心者による Ruby で書かれた Scheme のサブセットのインタープリタです。

次のことができます。

次のことができるかもしれません。できないかもしれません。

次のことができません。

How to get Rucheme?

こちからどうぞ。

ruby と同じライセンスでお願いします。

How to install Rucheme?

Ruby

Ruby 1.6.7 ではSEGVします。Ruby 1.6.8 以降を使ってください。 多分、もう SEGVしないんじゃないかな。未確認。確認してるのは 1.6.8 だけです。

strscan

あおきみねろうさんの strscan が要ります。Ruby 1.7以上では標準添付らしいですが、1.6以下なら RAA - strscanより入手して、インストールしておいてください。

Rucheme

Rucheme 自体は、アーカイブを解凍して頂ければおしまいです。

How to use Rucheme?

Rucheme 開発者は次のようにするのが便利です。

ruby rucheme.rb

で、rucheme.rb の __END__ 以下に書かれた Scheme プログラムを評価します。次に現れる __END__ で終了です。

手抜きです。はい。ファイルから読み込むのは、すぐ出来ると思うんで、やりたきゃやってください。>やりました。次を参照。

How to use Rucheme Interactive Frontend?

ruby rcm.rb

で、(いいかげんな)対話型のインタープリタが起動します。多分。

ruby rcm.rb [file..]

で、ファイルの中身を評価して終了します。

test.scm というファイルが、私がテストに利用しているファイルです。

How to see Detail of Evaluation?

実行経過の詳細を表示させるためには、rcmlib/evaluator.rb の OUT_Flags を適宜変更してください。変更方法は勘を働かせてください。

How Rucheme execute?

(define (fact n)
  (if (> n 1)
    (* n (fact (- n 1)))
    1))

(fact 40) ;=> 815915283247897734345611269596115894272000000000

が計算できました。さすが ruby。C や Java ではこうは簡単に行きません。

(fact 50) だとスタックオーバーフロー :-p なんとか末尾再帰は頑張りたいところですけど、めんどうくさい。んー、でも足りないよなぁ。 下記参照。

real    0m0.281s
user    0m0.015s
sys     0m0.015s

Celeron1.4GHz,256MB,Win2k,Ruby1.6.8MSWin版 でこんなもん。

Proper Tail recursion

正しい末尾再帰ってやつに少し対応しました。lambda 式での末尾呼び出し、及び if 内での末尾呼び出しに対応しました。call/cc とか cond とかは対応してません(*2)

これによって、次のようなことができました。上記を末尾再帰な形に変更して実行します。

; simple tail recursion factorial function
(define (fact_ n res)
  (if (> n 1)
    (fact_ (- n 1) (* res n))
    res))

(define (fact n)
  (fact_ n 1))

  (fact 1000) ; or more big number is ok :)

結果は膨大なので略。一応 (fact 10000) とかも動いたらしい。10秒くらい。結果の検証してないけど。速度は ruby の半分ほど。・・・嘘かも。この例だと、Bignum の処理に時間がかかってるので、結果的にそうなります。まぁ、意外に速いです。数百倍は覚悟してたんだけどなぁ。

ついでに、ソースがむちゃくちゃ汚くなりました。やれやれ。

Binding with Ruby

(ruby-new ClassName args ...)

で、ClassName というクラスのインスタンスを返します。要するに、Ruby で言うところの ClassName.new *argsを返すわけです。

(ruby-call obj msg args...)

で、obj というRubyオブジェクトに msg を投げます。要するに、Ruby で言うところの obj.send *args をするわけです。

ClassNamemsg は、文字列でもシンボルでも、どちらでも構いません。

はっきり言ってしまうと、Ruby で出来ることの大半の機能をこれで利用することができます。いや、ほんと。

例外とブロックに関するもの以外は出来ちゃうんだってば。

Why do you develop Rucheme?(or Chatting)

このソフトは、教育用途に作られました。

私の。

いや、windows上で動くエディタが好きなのを使える scheme の処理系が見つけられず。DrScheme もいいんですけど(*3)、ステップ実行が出来ないようで。なら、作ってしまえ、と。

Rucheme は、駄目になるまでガンガン評価していきます。実行経過もガンガン垂れ流します。だから、教育用です。

私の。

まぁ、私がSICP読み会で利用するためのものです。ほんと。

というか、俺 scheme のプログラムなんて書いたことないんですけど。だから、scheme の勉強も兼ねています。これ。というか、それが一番の目的かなぁ。

いやぁ、馬鹿企画第二段ってことで。実用性を聞いたりすると呪われます。多分。

ちょっとした目的としては、ruby の continuation をつかったらさっくりできるんじゃねーか、という魂胆です。動いちゃいましたねぇ、あはは。いやー、もうrubyのlispなラッパーって感じですな、これは。ruby の機能をS式で使おうって感じで。

もっと根本的には言語処理系やってるのにLisp処理系も作ったことねーの? といわれるのが嫌だったからです。

だから、私を教育するためのソフトなんだってば。

今回は奇跡的に現実逃避が目的じゃありません。多分。いや、ちょっとあるかも。

そういえば、今回は英語圏へ発表できるようにコメントにも気を使いました。極力 コメントを書かない! という方針です。我ながらナイスな方針です。

ToDo

Bibliography


*1 というか、未だにマクロがよくわからない
*2 applyなぞ実装もしていない
*3 作ってる最中に実行するだけなら便利なのに気づいた。
Sasada Koichi / sasada@namikilab.tuat.ac.jp
$Date: 2003/04/28 10:27:52 $