SCHEMEON.jsにevalなど付け加えてみた
Javascriptだけで実装しているSchemeインタプリタSCHEMEON.jsにevalを付け加えてみました。
http://www.d2.dion.ne.jp/~ujiie/schemeonjs/
evalの実装は、null-environment, scheme-report-environment, interaction-environmentのことを考えなければとても簡単。
でもr5rsにはこの3つのどれかがevalの第2引数に与えられることになっている。
- null-environment (たぶん)シンタックスのみ実装された環境(プリミティブ手続きは未実装)
- scheme-report-environment r5rsで規定されている手続きなども定義された環境
- interaction-envioronment 通常の環境
これをグローバル環境上で選別してやらなきゃならない。
ちょっとよくわからなかったのが、例えば、scheme-report-environment上で新たに定義したシンボルがinteraction-environmentにどう影響してくるのか。
Gaucheでちょっと確認してみました。
gosh> (eval '(define a 1) (scheme-reort-environment 5)) a gosh> a 1 gosh> (define a 2) a gosh> (eval 'a (scheme-report-environment 5)) 1 gosh> a 2 gosh> (eval '(set! a 3) (scheme-report-environment 5)) a gosh> a 2
なるほどー。
つまり、interaction-environmentでシンボルが定義されていないときはscheme-report-environmentを見に行くけど、interaction-environmnetでシンボルが定義されているときはinteraction-environmentの定義を見に行くと。
で、evalでscheme-report-environmentなど下位の環境が指定されたときは、interaction-environmentでの定義は無視される。
この関係は多分null-environmentでも同じ。
この挙動を基本に、SCHEMEON.jsでも実装してみました。
実行スピードになるべく影響が出ないように工夫して実装したけど、おおむねうまくいっているみたい。