SECDV VMのインタプリタできた。後で何か書く。https://github.com/okuoku/yuni/commit/42b819b3ca09f716eb2f180d54065a4291e313e3 基本的にスムースに動いて後はヒープとかコンパイラを残すのみだけど、MIT Schemeの微妙な多値の実装に半日悩んだ。

MIT Schemeの多値、つまりcall-with-values手続きとvalues手続きはこのように実装されている。

( define ( values . objects ) ( lambda ( receiver ) ( apply receiver objects ))) ( define ( call-with-values thunk receiver ) (( thunk ) receiver ))

... 確かに、MIT-Schemeのドキュメントには、

Thunk must return multiple values using the values procedure.

と有るのでこういう実装でも良いんだろうけど、大抵のScheme処理系は、

( call-with-values ( lambda () 1 ) ( lambda ( value ) value ))

のようにして、1値をvalues手続きを使わずに返すことは許している。MIT Schemeのこの制約がR5RS/R7RS的にオッケーなのかどうかはまだちゃんと調べていないが、yuniではとりあえず

( define ( call-with-values thunk receiver ) ( let (( t ( thunk ))) ( cond (( procedure? t ) ( t receiver )) ( else ( receiver t )))))

call-with-valuesを1値の場合の専用処理を加えた形にoverrideすることで対策した。当然コレではgenericにはダメで、多値を期待されたthunkが、手続きオブジェクトの1値を返す場合にうまく動かない。