2009-09-10
■ [biwascheme] ソースを分割した
最近、BiwaSchemeのソース(*.js)をYUI compressorで1ファイルに圧縮するようにしたので、ファイルを好きなだけ分割できるようになった。
ということで、長すぎたstackbase.jsを10分割(笑)しました。ほぼ1クラス1ファイルです。
あと、YUI compressorがコメントを削ってくれるので、ライブラリ関数の定義のところにコメントで関数の説明を書こうかなぁと思っていたり。いつやるか分かりませんが。
ドキュメント方面では、githubのwikiページで中間言語の仕様をまとめ始めています。 R6RSの例外処理を実装しようと思っていて、そろそろちゃんと動作を把握しないとなぁと(してなかったのか!)。
■ [biwascheme] 例外どうやって実装しよう
メモをwikiの方に上げましたが、R6RSの例外(raise, with-exception-handler)の実装を最近考えています。
- JSの例外を流用したら簡単なんじゃね?
- と一瞬思ったけど、スレッド跨げないから駄目だった。
- 処理系レベルで実装
- 中間言語に手を入れてどうのこうの
- ライブラリレベルで実装
- どうやって?
他の処理系を見るとSchemeレイヤでparameterizeとか使って実装してる。
まず、カレント例外ハンドラ(と、最低限、一個外側の例外ハンドラ)をどっかグローバルなところに置いておかないといけないのは確定。 2つだけ保持するか、リスト使って全部保持するかは処理系によって違うようだ。まあハンドラのスタックがあると考えればいいのかな?
んで値を設定する方は簡単で、問題は復元する方だよな。with-exception-handler(以下w/eh)が終わったらpopしなければならない。 …が、Schemeの場合call/ccで脱出されちゃう可能性があるんだよねぇ。
(w/eh h1 ; 処理1 ) (w/eh h2 ; 処理2 )
call/ccはgotoみたいなもんだから、処理2から処理1にジャンプする可能性がある。このときカレント例外ハンドラをh2からh1に切り替えなければならない。
もっと言うと、
(define (f) <処理f>) (w/eh h1 (lambda () (f))) (w/eh h2 (lambda () (f)))
となっていた場合、処理f時点でのカレント例外ハンドラは、fがh1の方から呼ばれたかh2の方から呼ばれたかによって動的に決まる。