Brainf*ck の [ と ] のセマンティクス

Brian Raiter 氏の http://www.muppetlabs.com/~breadbox/bf/ では、Brainf*ck の [ と ] を次のように定義している。

  • [ ポインタの指すバイトが 0 なら、対応する ] の直後に飛ぶ
  • ] ポインタの指すバイトが非 0 なら、対応する [ に飛ぶ

この定義は微妙に対称ではなく、また冗長性がある。すなわち、] によって [ に飛んだ時には、既にポインタの指すバイトが非ゼロであることはわかっているから、[ によるゼロテストは無駄である。従って、] で非ゼロのテストを行うなら、飛び先は [ そのものではなく、[ の直後でよい。

  • [ ポインタの指すバイトが 0 なら、対応する ] の直後に飛ぶ
  • ] ポインタの指すバイトが非 0 なら、対応する [ の直後に飛ぶ

とすると、対称的な定義になる。
一方、相当する C のコード片として、] は } に対応する、としている。この場合 ] は無条件ジャンプで [ に飛ぶものと言える。Érdi Gergő 氏の FPGA 実装 http://gergo.erdi.hu/blog/2013-01-19-a_brainfuck_cpu_in_fpga/ では Brainf*ck の [ ] を while 型から do while 型にチェンジして実装した、とあるが、「while 型」とはこのことを指している(と思われる)。while 型であることを明確にした定義は次のようになるだろう。

  • [ ポインタの指すバイトが 0 なら、対応する ] の直後に飛ぶ
  • ] 対応する [ に飛ぶ

] を無条件ジャンプとした場合、実装の内部仕様は微妙に違ったものになるが(インストラクションポインタが、] の後に必ず [ を指すことがあるか、そうでないかの違い)言語の外部仕様は変化しない。
前述の FPGA 実装における do while 型にチェンジとは(おそらく簡単化のために)[ をジャンプ先を示す単なるプレースホルダ(ラベルのようなもの)としてジャンプしないものとしたものである(あろう)。次のような定義と思われる。

  • [ なにもしない(NOP)
  • ] ポインタの指すバイトが 0 なら、対応する [ の直後に飛ぶ