Open3
簡易Schemeフロントエンドの製作
色々と悩んでみたけど、mruby方式でインタプリタを作って実アプリでベンチマークした方が良さそうなので、フロントエンドはとりあえず適当に用意することに。
mruby方式 = 一旦スクリプトをバイトコードにコンパイルしてしまってから実行する。
Alexpander
今回はマクロの展開のためにAlexpanderを使う。
(配布元のサイトは消滅してしまったようだ。BSD3 or GPL2+。)
Alexpanderを通すと、R5RS Schemeのプログラムで使用される構文を begin
define
if
delay
lambda
letrec
quote
set!
の8種類にまで減らしてくれる。当然 and
のような構文は if
の連鎖になるので出力されるプログラムは相応に複雑になるが。。また、 map
のような構文ではないライブラリ手続きは別途実装する必要がある。
バイトコード
バイトコードはyuniの簡易FASLとSECDV VMを使う。
簡易FASL(drypack)
drypackは、いわゆる(U)LEB128( https://en.wikipedia.org/wiki/LEB128 )の数値列でS式をシリアライズする。テキスト表現のS式よりもreaderの実装が簡単にできるというメリットがある。
SECDV VM
SCEDV VMはtail callと多値を直接扱える必要最低限の機能を持ったVMで、そのコンパイラは過去に書いている:
VMの命令としてシンボルを使うとちょっとVMの実装が面倒になるといった問題があるので、これを改造して使うことにする。
コンパイラの出力はS式となる。つまり、ラベル等の解決は自分でやる必要がある。