海野秀之(うんのひでゆき)の外部記憶
Twitter (twilog) / RSS / アンテナ / ぶくま
ようやく、State Monad (書いたことないので)恐怖症を克服し、munchExp を State Monad として書き始めた。やっぱこうだよな。適切なツールをつかってる実感というか、快適な感じ。
ただ、書いて、寝てみて、もっとうまく書けるよなと思った(寝ながら)。
munchExp (T.STR s) =
state $ \st ->
let
insts = get_insts st
temp = get_temp st
(t, temp') = Temp.newTemp temp
inst = A.strInstr s [t]
in
(t, st{get_insts=insts ++ [inst], get_temp=temp'})
これは、次のように書き直したい:
munchExp (T.STR s) =
do
t <- newTemp
emit $ A.strInstr s [t]
return t
こう書けるように、newTemp :: State CgenState Temp.Temp や、emit :: State CgenState () を書くのだろう。"emit" という単語は、Tiger book がそういうボキャブラリなので。(状態の型も名前を変えよう> CgenState)
これで、より State Monad っぽい書き方になったかなぁとは思うんだけど…。聞くところによると、「do 記法は有害だから使うな」という説もあるらしいのが、ちょっとだけ気になってる。
ま、いいか。
https://github.com/unnohideyuki/Tiger-in-Haskell
Codegen を書いていて、これまでのところでイマイチわかってなかったところに気づいて修正。関数の戻り値は、Tree 言語上どうやって表現されることになってたのか、わかんなくなって。Translate では、戻り値を RV に格納するような MOVE 命令を Proc の body に追加するべきだった。
Translate をそのように直して、それに対応する MOVE 文の munchStm も書いた。
Tiger 言語の関数・プロシージャは、すべて、Dalvik 上では Object を返すメソッドにマッピングされることになる。(UNIT は CONST 0)
Canon の理解があやふやなのは、動かしながら&テストを書きながら理解していこう。
だいぶ、わからない部分がなくなってきた。
9章ぬけたら、いよいよレジスタ割り付けだ。