定期ミートアップ 第9回 yhara
基本方針
効率は度外視、「動くこと」を最優先にする
if式の列に展開する
例
code:sk
match A.foo # Maybe<Int>を返すとする
when Some(n)
p n
else
p "none"
end
展開結果
おおよそ次のようになる
1つの節(clause)につき一つのif
expr@0は自動生成した引数名
衝突を避けるため通常では使用できない記号(@)を入れている
code:sk
(fn(expr@0: Maybe<Int>){
# when節1
if expr@0.class == ::Maybe::Some
n = expr@0.value
return (p n)
end
# else節
return (p "none")
# マッチしなかったとき
panic "no clause matched"
})(A.foo)
既知の問題
when内でreturnを使うと誤動作する
勝手にfnでくくっているため
以下のようにすればいいはず
ifの列ではなく、if-elseのネストにする(どれか一つの節しか実行されないよう)
結果を表す変数を用意し、そこに代入する
code:sk
expr@0 = A.foo
var result@1
if expr@0.class == ::Maybe::Some
if 条件2
n = expr@0.value
result@1 = n.to_s
else
次にいきたいがどうする? #→ 定期ミートアップ_第10回_yhara にて解決 end
else
if true
result@1 = "none"
else
panic "no clause matched"
end
end
変換の流れ
AST → HIR → MIR → LLVM IR (→ asm → 機械語)
ASTだけでmatchを展開することはできない
ん?嘘かも
聞きたいこと
ASTからHIRに変換するとき、ASTは破壊してよいか?
=> 別にいいのではないか(Rustなら、あとで保存したくなったとしても.cloneするだけで済むので)