難読言語Brainf*ckのHello Worldをめちゃくちゃ分かりやすく解説した

Brainf*ck(Brainfuck)という言語をご存知でしょうか?

わずか8つの記号しか使えない変態言語なのですが、チューリング完全を満たしている立派なプログラミング言語です。

有名なHello World!のサンプルコードを見てほとんどの初学者は挫折してしまうのですが、わかりやすく解説してみました。

Brainf*ck の命令

Brainfu*kは以下の8つのコマンドのみを持つシンプルさを極めたプログラミング言語です。

コマンドだけなら一瞬で覚えられますね。

  1. > ポインタのインクリメント
  2. < ポインタのデクリメント
  3. +  ポインタが指す値をインクリメント
  4. -  ポインタが指す値をインクリメント
  5. .  ポインタが指す値を出力する
  6. ,  入力から1byte読み込んでポインタが指す先に格納する
  7. [  ポインタが指す値が0なら、対応する ] の直後にジャンプする
  8. ]  ポインタが指す値が0でないなら、対応する [ (の直後)にジャンプする

また、BrainF*ckでは前提条件として値が0で初期化されたメモリ空間が与えられます。

初期位置はアドレス0です。これはとても大事な前提なのでしっかり頭に入れておいてください。

Hello World!

こちらがBrainF*ckで”Hello World!”を出力するコードです。

これを解読していきます。

まずは  .  がポインタが指す値を出力するコマンドであることから最初の  . までが Hello World! の先頭文字 H を出力するプログラムであることが分かります。

実はこの H を出力するプログラムさえ理解できればHello World!は理解できたも同然なのです。(多分)

本記事ではこのプログラム >+++++++++[<++++++++>-]<. に焦点を当てて解説していきます。

*ちなみにこちらのサイトでWEB上でBrainf*ckを試すことができます。

A Brainfuck editor & optimizing interpreter, written in JavaScript. It's pretty fast.

単純な実装を考えてみる

H という文字はアスキーコード表を確認すると十進数の72にあたります。

初期位置であるアドレス0が指す値を + コマンドで72回インクリメントして . コマンドで出力すれば H が出力される気がします。

これを試してみると確かに H が出力されました。

これを短くするには?

先程のHを出力するプログラムに戻ります。 + で72回インクリメントするより短いですね。

まず >++++++++++++ で > コマンドのあと + コマンドを12回実行しているが分かります。

  • > コマンドでポインタをインクリメントしてアドレス1に移動し、
  • + コマンドでアドレス1が参照する値を12回インクリメントしています。

つまり、メモリ空間は下図のようにアドレス1の値が0から12に変化します。

*赤の太字は現在アドレス1に位置していることを表しています。

次に [  ~ ] コマンドが実行されます。

[ , ] コマンドで囲むと、今いるアドレス( 1 )の値が0になるまで [ ~ ] の中の処理を行うことができます。

では [ ~ ] の中のコマンド <++++++>- を見ていきましょう。

  • < コマンドでポインタをデクリメントしてアドレス1からアドレス0に移動し、
  • + コマンドでアドレス0が参照する値を6回インクリメントし、
  • > コマンドでポインタをインクリメントしてアドレス1に戻り、
  • - コマンドでアドレス1の値をデクリメントしています。

ここまで進むとメモリ空間は下図のようにアドレス0の値が0から6になり、アドレス1の値が12から11になっていることが分かります。また位置はアドレス1です。

今いるアドレス( 1 )の値は11なので、再び [ ~ ] の中のコマンド <++++++>- が呼び出されます。

するとアドレス0の値が6回インクリメントされ、アドレス1の値が1デクリメントされるので、メモリ空間はこうなりますね?

勘がいい方は気がついたかもしれませんが、これを繰り返していくと最終的にはアドレス0の値が6 x 12回インクリメントされて72になります。そしてアドレス1の値は0になったので [ ~ ] のループは終了します。

最後に < コマンドでアドレス0に移動して . コマンドで出力すれば72に対応するアスキーコード H が出力されます。

この要領で読み進めていけば、Hello World!も読める気がしてきましたよね?

これでBrainf*ckの最初の関門は突破できたのではないでしょうか?