programming-languagecompiler-design
動機
chumskyのチュートリアルで、評価する関数の実装がライフタイム付きでこんな感じになってたの頭いいなと思ったので、RAIIにしたらもっとシンプルに見えるのではと思った
OCamlとかの関数型言語とかみたいに、env :: newbind
とかするのはRustではイテレータとか使いづらいしやっぱ微妙、というのもある
Environmentは評価全体で見ればLetやLambdaごとに分岐していく構造だけれど、局所的には1列のベクタで表現できるので、実はVec
で十分
こんな感じすかねえ
Rust初心者には逆にわかりにくかもしれないな、、、
lookupでは値をコピーして返してる(このオブジェクトが有効な期間は中身のベクタの不変参照を返すことができないため)
なんかDropのタイミングがうまく制御できずコンパイルを通せない、、、
し、綺麗ではあるけど言うほど記述量が減るわけではない
ので、evalを相互再帰するヘルパー関数とかでこういう感じにした方が楽かも
改善
微妙だったので結局ライフタイムで制御する方がいいのかもしれない
評価した時に、クロージャを作ると環境を保持する
Valueの中ではクロージャがEnv
と、bodyでExpr
を保持し、環境はValueを保持するので定義も内部構造も循環することになる
全部メモリ的にフラットな構造にするためは?
Envは評価結果のValueをIdで保持する
一度lookupしたらEnvのインデックスに置き換えて2度目以降のアクセスはキャッシュが効くようにする