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: