マクロツイーター

はてダから移行した記事の表示が崩れてますが、そのうちに直せればいいのに(えっ)

条件文における「展開」

TeX は実行制御を全てマクロ展開だけで行う言語である。だから展開の仕組みを正しく理解すること(もっと具体的にいえば「\expandafter をどう使うか」)は、ある程度複雑なプログラムを「思った通りに書く」ために欠かせない。その中でも「条件文と展開との関係」は一番厄介なものだと思う。数学的に「綺麗な」形は次のようなものだろう。

  • \iftrue〈真〉\else〈偽〉\fi を一回展開すると 〈真〉 になる。
  • \iffalse〈真〉\else〈偽〉\fi を一回展開すると 〈偽〉 になる。

(ただし、「結果が真/偽になる \if 条件」を \iftrue\iffalse で代表させた。((この後、実際の TeX の動作の解説を行うが、「条件部はどんなに複雑(例えば \ifnum\count\the3\day\@gobble?*\string0=\z@ とか)でも一回展開で処理される」ことを予め述べておく。)))

ただこの方法は、場合により後に続くトークン列の大規模な組み換え(ずっと後ろにある \fi だけを除去する)が必要になるので実装には適切でない。実際の TeX は内部で「条件ネストレベル」と「今のレベルまでの判断の結果」を記憶していて、「不成立である分岐に入った時点でその部分を読み飛ばす」という処理を行っている。((e-TeX では「条件ネストレベル」を \currentiflevel、「最内レベルの判断結果」を \currentifbranch というパラメタで参照できる。))だから、\if-トークン、\else\fi(これを仮に「条件トークン」と総称する)はその内部状態を変える標識として「展開」されなければならない。例えば、典型的な末尾再帰の形式


\def\xx@loop{%
\if〈終了条件〉 〈終了処理〉
\else 〈反復処理〉 \expandafter\xx@loop \fi
}

で、\xx@loop の呼出の前に \expandafter が要るのも、呼出の前に \fi を「展開」する必要がある(そうでないと末尾再帰にならない)からである。

では、条件トークンは実際にはどのように「展開」されるのか。これは TeX の参考書でも書いているものが見当たらない。色々と実験した結果から得た(かつ参考書の記述と矛盾しない)推測は、どうやら次のようになっているらしい。

状況一回展開後
\iftrue〈真〉【真】〈真〉
\iffalse〈真〉\fi〈後〉〈後〉
\iffalse〈真〉\else〈偽〉【偽】〈偽〉
【真】\else〈偽〉\fi〈後〉〈後〉
【真】\fi〈後〉〈後〉
【偽】\fi〈後〉〈後〉

この表は次のように解釈する。

  • \if...〈真〉[\else〈偽〉]\fi〈後〉 の書式を想定する
  • 先と同様に「結果が真/偽になる \if 条件」を \iftrue\iffalse で代表させる。
  • 簡単のためネストしていないとする。すなわち〈真〉と〈偽〉は条件トークンを含まない。
  • 「【真】xxx」は、現在の先頭トークン列が xxx で「真」の分岐に入っていることを表す。「【偽】xxx」も同様。