NODE_FLIP系
NODE_DOTの範囲式が条件式として使われると、特別な意味になります。そういう位置にある範囲式はNODE_DOTではなくNODE_FLIPとしてコンパイルされます。
式1 .. 式2
は「式1が真になるまでは偽を返し、その後は式2が真を返すまでは真を返します。式2が真になれば状態は偽に戻ります」となっているそうです。つまり、この範囲式を評価するには、今「式1が真になるまで」の状態なのか、「その後は式2が真を返すまでは」の状態なのかをどこかに記憶しておく必要があります。
現在のYARVの実装では、範囲式の状態を保存する領域へのアクセスは、getspecial で行います。
ADD_INSN2(ret, nd_line(node), getspecial, INT2FIX(node->nd_cnt),
INT2FIX(0));
構文解析の段階で node->nd_cnt に$1,$2などとは重ならない番号が入っているので、それを利用しています。状態を記憶するために、式1待ちのときはfalse、式2待ちのときはtrueを入れます。というわけで、生成されるコードはこちらの通り。
getspecial
branchif lend
# 状態がtrueならlend:へジャンプ
eval 式1
dup
branchunless lfin
# 式1 が falseなら式全体がfalse
# 式1 が trueなら、それを状態に記憶
setspecial
lend:
eval 式2
branchunless ltrue
# 式2がfalseなら式全体がtrue
# 式2がtrueなら、falseを状態に記憶
putobject false
setspecial
ltrue:
putobject true
lfin: