Mini Schemeのコードリーディング

Tiny Schemeのサイトに置いてあるMini Schemeを読んでます。読んでいると言うより、書き換えながら遊んでる感じ。

雑感

2400行しかないので読みやすい。

  • Mini Schemeからの派生版として、Tiny Scheme, AM Scheme等がある。
    • オリジナルのコードは1989年製。古典です。
    • GIMP のScript-Fuは2.4からTiny-Fuと呼ばれるTiny-SchemeベースのSchemeになったらしい。驚き。
  • とにかく再帰が無い。GCから構文解析に至るまで全てGOTOで書かれてる。凄い気合です。
  • 動的に継続を生成するタイプ。UnlambdaのC版みたいな感じ。
  • opexeがちょっと読みずらい。

Schemeモドキから脱出してSchemeを作りたい。継続が欲しい、末尾呼び出しの最適化したい。GCが欲しい。と思ったときは、Mini Scheme系を読むとよさげな感じデス。

データ構造

凄くシンプル。

  • 基本的なオブジェクトはcellの中にunion{数値,文字列,ペア}という感じ。後は_flagで分ける。
  • グローバル変数に,仮想マシンを配置。マシンの構成は以下
  • GCは、マーク・アンド・スイープ。あらかじメモリを確保しておいて、フリーセルから使っていく、使い終わったらフリーセルに返す。

基本的な流れ

GCとプリミティブの初期化をしたら、とりあえず、Eval_Cycleに飛ぶ。Eval_Cycleでぐるぐる回る。

opexe_0がメインコードっぽい。


(+ 1 1)を追うと、最初に、LOAD継続を実行。そしたら、print継続、eval継続をプッシュして、READへ。(+ 1 1)を読み込んで、eval継続をポップ。apply。表示。LOADって感じ。eval以降はまだ追ってる最中。

evalが凄すぎる

とりあえず、evalをハック中。

とにかく継続の扱いに慣れることが重要。

  • 何らかの状態がある
  • 処理を分解する。
  • s_saveすると継続にプッシュする。このとき、value以外の全レジスタの状態を継続に保存する。
  • そしたらガリガリ加工する。自由にやっちゃって、valuesを作る。
  • s_returnすると継続からポップ。s_saveした時の状態に戻る。
  • valuesをs_saveしたときの状態に投げる事になる。また何らかの状態を処理していく。

リスト処理を追ってみる。

  • リストがある。
  • carの処理、cdrの処理に分解する。
  • cdrの処理は後でやるので継続に保存する。
  • carを加工する。
  • 継続をポップして、元の状態に戻す。carの結果を、cdrの処理に投げる。

継続はスレッドのようになってて、フレーム間では、レジスタの状態が全く違うというところがポイント。

マルチスレッドっすよ。マルチスレッド。

細かいところ

  • シンボルテーブルは持ってない。
    • つまりグローバル変数は無い。全てローカル。
    • 問題は、継続の中に丸々環境が入ってるので、ダンプしてみると環境だらけになってしまう。むぅ。ハックしにくい。
  • enum使ってない。
    • 古いコードなのでenumで書けるはずの所がenumで書かれていない。激しく長いので書き換えたほうがいいと思う。
    • Tiny-Schemeはマクロでうまく書いてある。

ここまでのまとめ

概要はなんとなく掴めてきた。

とにかく継続,継続,継続。goto,goto,goto。再帰が無いって大変だ。

僕もMini Schemeベースで作ってみようかな。