Brainfuckの後継言語であるBrainCrushのインタプリタを作成した。
新たな命令や仕様変更があっただけで、大部分はBrainfuckと変わっていない。
Brainfuckのインタプリタについては前回の記事を参照してほしい。
また作成にあたり、以下のページを参考にさせていただいた。
[1] dic.nicovideo.jp
[2] blog.metarin.net
Brainfuckからの変更箇所
参考資料[1]から引用する。
追加された命令
・「|」 … 現在のポインタの位置にある値と、その次のポインタの位置にある値をビットOR演算し、その次のポインタの位置に代入する。また、ポインタは現在の位置から1つ進められる。
・「&」 … 現在のポインタの位置にある値と、その次のポインタの位置にある値をビットAND演算し、その次のポインタの位置に代入する。また、ポインタは現在の位置から1つ進められる。
・「~」 … 現在のポインタの位置にある値をビットNOT演算(つまりビット反転)する。
・「^」 … 現在のポインタの位置にある値と、その次のポインタの位置にある値をビットXOR演算し、その次のポインタの位置に代入する。また、ポインタは現在の位置から1つ進められる。
追加された仕様
・実行時、メモリにはHello, world!に相当する72,101,108,108,111,44,32,119,111,114,108,100,33が0番地よりこの順で積まれる。
・終了時、現在指し示すポインタの値を、ポインタの値が0になるまでポインタを進めて出力する。
参考資料[2]によれば、この2つ目の仕様は、終了時に[.>]
を実行することと等価である。
そのため今回は、getline()
で受け取ったBrainCrushコードの末尾に[.>]
を付加することにより実装した。
コード
前回作成したBrainfuckのコードに加筆する形で作成した。
2行目で宣言しているフラグ"IS_CRUSH"をfalseにすれば、Brainfuckのインタプリタとして使用することも可能である。
(メモリの初期化部分はもっといい書き方があるはずなので、後日修正するかもしれない)
(2021/05/30 追記) ソースコードは以下に移動した。
実行
最初からメモリに"Hello, world!"が積まれており、なおかつ終了時に勝手に[.>]
を実行してくれるので、何も入力しなくても"Hello, world!"が出力される。
$ g++ brainfuck.cpp $ ./a.out Hello, world! [END OF RUNNING] $