NODE_BLOCK
お次は、NODE_BLOCK。RHG12章 の「幹」の説明を読んでみると、このノードは、文の並びをリストとしてつなぐためのノードです。細かいことは抜きにすると
7; 8; 9
という3つの文は
NODE_BLOCK(nd_head: 文"7"を表すノード, nd_next: NODE_BLOCK(nd_head: 文"8"を表すノード, nd_next: 文"9"を表すノード))
nd_headとnd_nextで構成される連結リストになります。
これのコンパイルは、リストの先頭から順番にそれぞれの文をコンパイルしていくだけですね。
case NODE_BLOCK:{ while (node && nd_type(node) == NODE_BLOCK) { COMPILE_(ret, "BLOCK body", node->nd_head, (node->nd_next == 0 && poped == 0) ? 0 : 1); node = node->nd_next; } if (node) { COMPILE_(ret, "BLOCK next", node->nd_next, poped); } break; }
ノードの種類がNODE_BLOCKである間は、「nd_headをコンパイルして、次に進む」を繰り返しています。次の文があるときはnd_headの文の値は捨てられるので、poped=1で再帰的にCOMPILE_を呼びます。
リストの最後のノードの値を捨てるべきかどうかは、このNODE_BLOCK全体の値を捨てるべきかどうかによって決まります。なので、最後のCOMPILE_にはpoped引数を再帰的に渡しています。