1. HOME
  2. ブログ
  3. IT技術
  4. 【第4回】Brainfuckを実装しながら学ぶC++【実装してみよう!後編】
【第4回】Brainfuckを実装しながら学ぶC++【実装してみよう!後編】

【第4回】Brainfuckを実装しながら学ぶC++【実装してみよう!後編】

第4回~Brainfuckを実装しながら学ぶC++

Brainfuckを実装しながら学ぶC++」シリーズも、今回を含めて、残り2回となりました!

ちなみに前回は、Brainfuck の実装にあたり、大枠を作っていきました。

今回は、Brainfuck インタプリタの核となる部分を、実装していきましょう!

こちらの記事もオススメ!


メモリ操作命令「+ / - / > /<」の実装

まずは、比較的実装が簡単な、「+ / - / > / <」の命令から実装していきましょう。

値の加算命令「+」

すごくシンプルですね!

今ポインタが指しているメモリの値を、インクリメントしているだけです。

Braunfuck では、値が255を超えた (オーバーフローした) 場合は、値を「0」にする必要があります。

ですが unsigned char は、もともと「0~255」の範囲しか取りません。

つまり、オーバーフローした場合は勝手に「0」になるので、そういった処理は書かなくても OK ですね!

値の減算命令「-」

コードは「+」とほとんど同様です。

こちらもアンダーフローした場合、勝手に「255」になります。

ポインタの加算「>」

こちらは、オーバーフローの処理を、しっかりと記述してあげましょう。

今回の実装では、三項演算子「?」を使用した形で書いています。

これは、以下のコードと同様です。

ポインタの減算「<」

こちらも同様です。

MEMORY_SIZE-1 は、セグメンテーション違反に気をつけましょう。

入出力命令「 . / , 」の実装

次に、入出力命令を実装していきます。

C / C++ では、 #include <cstdio> を使えば、とてもシンプルに書けます。

ここまででデバッグをしてみよう

ここまで実装が終わると、ループを使わずに、Brainfuck コードを実行できるようになります。

例えば、「A」を出力するコード。

そして、アンダーフローを使った「z」の出力もできると思います。

他にも、ポインタの移動や入力も、自身で試してみると良いですね!

例えば、入力された文字をそのまま出力するコードは、

です。

ループ命令 [ ] の実装

ここが、Brainfuck インタプリタ実装において、もっとも難しいところです。

まずは実装する中で、考慮すべき点を列挙してみましょう。

  1. " [ " が来たら、それがあるコードポインタを保持しておく。
  2. " [ " の時点で、ポインタの指す値が0かどうかを確認する。
    → 0ならば、対応する " ] " の一つ後ろへ飛ぶ。
    → 0でなければ、そのままコードポインタを進める。
  3. " ] " が来たら、対応する " [ " へ飛ぶ。

以上の3点です。

ここで、ひと工夫が必要な部分は、ループのネストです。

" [ " と " ] "の対応関係を上手く実装する必要があります。

まずは、"[" のコードポインタを保持する配列を作りましょう。

大枠を作る

今回は、 std::stack<> を使用します。

その名の通り、LIFO (Last-In First-Out) なコンテナです。

そうしたら、命令に対応した処理を実装していきましょう。

ひとまず、「ポインタの値が0のとき」以外を作ります。

つまり実装するのは、「 " ] " が来たら対応する " [ " に飛ぶ 」です。

" [ " から " ] "に飛ぶ処理を実装する

先ほどの if 文の中身を、ここでは実装していきましょう。

" [ " と " ] " の対応関係は、ループの深さを保持する、 depth という変数を用いて実装していきます。

やっていることは、じっくりコード中のコメントを読むと、理解できるかと思います。

あとは、もう一度ビルドして完成です!

Brainfuck インタプリタが完成!

お疲れ様でした!

これにて、Brainfuck インタプリタが完成しました。

「意外と簡単!」と感じたのではないでしょうか?

最後に、動作確認もしてみましょう!

Hello, world!

以下のコードを、インタプリタに与えてみます。

上手くいきましたね!

皆さんはどうでしょうか?

他にも、いろいろ試してみましょう!

最短のHello, World!

最短の「Hello, Wolrd!」コードです。

アンダーフローへの対応と、多重ループの対応が上手くできていないと、しっかりと出力されないサンプルです。

さらに、走査回数が17,896ステップと、比較的難解な Brainfuck コードでもあります。

どうでしょうか?

上手く実装できていれば、C++ なので、かなり高速に所望の出力が得られると思います!

FizzBuzz

おまけとして、有名な言葉遊びも。

フィボナッチ数を延々と出力するコード

メモリがオーバフローするまで、出力してくれるコードはこちら。

番外編へつづく!

お疲れ様でした!

今回で、連載「Brainfuck を実装しながら学ぶ C++」のメインは、ひとまず終了になります。

次回最後となる番外編では、「出来上がったコードを改造」してみたいと思います!

本連載を通して少しでも、C / C++ に、そし て Brainfuck をはじめとする、Esolang にも興味を持っていただけたら幸いです。

本コードは、最初に定数として宣言していた命令を少し変えるだけで、オリジナル Esolang が作れますよ

ぜひ遊んでみてくださいね!

では、次回もお楽しみ!

最終コード

番外編はこちら!

第1回目はこちら!

記事を書いた人

\ 3度のメシより技術が好き /
(株)ライトコードは、WEB・アプリ・ゲーム開発に強い「好きを仕事にするエンジニア集団」です。
システム開発依頼・お見積もりはこちらまでお願いします。
また、WEB・スマホ系エンジニアを積極採用中です!
※現在、多数のお問合せを頂いており、返信に、多少お時間を頂く場合がございます。

こちらの記事もオススメ!


ライトコードよりお知らせ

にゃんこ師匠にゃんこ師匠
システム開発のご相談やご依頼はこちら
ミツオカミツオカ
ライトコードの採用募集はこちら
にゃんこ師匠にゃんこ師匠
社長と一杯飲みながらお話してみたい方はこちら
ミツオカミツオカ
フリーランスエンジニア様の募集はこちら
にゃんこ師匠にゃんこ師匠
その他、お問い合わせはこちら
ミツオカミツオカ
   
お気軽にお問い合わせください!せっかくなので、別の記事もぜひ読んでいって下さいね!

一緒に働いてくれる仲間を募集しております!

ライトコードでは、仲間を募集しております!

当社のモットーは「好きなことを仕事にするエンジニア集団」「エンジニアによるエンジニアのための会社」。エンジニアであるあなたの「やってみたいこと」を全力で応援する会社です。

また、ライトコードは現在、急成長中!だからこそ、あなたにお任せしたいやりがいのあるお仕事は沢山あります。「コアメンバー」として活躍してくれる、あなたからのご応募をお待ちしております!

なお、ご応募の前に、「話しだけ聞いてみたい」「社内の雰囲気を知りたい」という方はこちらをご覧ください。

ライトコードでは一緒に働いていただける方を募集しております!

採用情報はこちら

書いた人はこんな人

ライトコードメディア編集部
ライトコードメディア編集部
「好きなことを仕事にするエンジニア集団」の(株)ライトコードのメディア編集部が書いている記事です。

関連記事

初心者が3ヶ月でどれくらいプログラミングができるようになるのか

採用情報

\ あの有名サービスに参画!? /

バックエンドエンジニア

\ クリエイティブの最前線 /

フロントエンドエンジニア

\ 世界はお前の手の中に・・・ /

モバイルエンジニア

\ サービスの守り神! /

インフラエンジニア

初心者が3ヶ月でどれくらいプログラミングができるようになるのか

初心者が3ヶ月でどれくらいプログラミングができるようになるのか