日記

日本語の勉強のためのブログ

C++でBrainCrushのインタプリタを作った

Brainfuckの後継言語であるBrainCrushのインタプリタを作成した。
新たな命令や仕様変更があっただけで、大部分はBrainfuckと変わっていない。

Brainfuckインタプリタについては前回の記事を参照してほしい。

everykalax.hateblo.jp

また作成にあたり、以下のページを参考にさせていただいた。

[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 追記) ソースコードは以下に移動した。

github.com

実行

最初からメモリに"Hello, world!"が積まれており、なおかつ終了時に勝手に[.>]を実行してくれるので、何も入力しなくても"Hello, world!"が出力される。

$ g++ brainfuck.cpp
$ ./a.out

Hello, world!
[END OF RUNNING]
$