シラミ騒動で Brainf**k

シラミ騒動ならぬ衝動的な参加表明で全然何を書いていいのか思いつかなかったのですが、ドレミファソラシ で Brainf**k 書いてみました。

※みなさんの記事がガチ過ぎて恥ずかしい気持ちでいっぱいです。。。

## 環境

本当は CLI にしたかったのですが、時間がなかったので会社でよく使う HTML/CSS/Javascript でやります。

### 依存関係
* jQuery
* Bootstrap

### 命令リスト
* ド
  * メモリポインタをインクリメント
* レ
  * メモリポインタをデクリメント
* ミ
  * メモリポインタが指す値をインクリメント
* フ
  * メモリポインタが指す値をデクリメント
* ソ
  * メモリポインタが指す値が0なら対応する「ラ」までプログラムカウンタを進める
* ラ
  * メモリポインタが指す値が0でないなら対応する「ソ」までプログラムカウンタを戻す
* シ
  * メモリポインタが指す値を出力する

※ ドレミファソラシ だと 7文字しかないため、標準入力からの読み込みは割愛しました。

## 画面

何はともあれ画面をどうぞ


![スクリーンショット 2015-12-13 19.06.11.png](https://qiita-image-store.s3.amazonaws.com/0/36620/bee61da2-5255-fe5e-8cb5-7ceb07303534.png)

textarea にコードを記述して、Run で実行です。最初に入っているのは数多くのプログラマの初めてを奪ってきた「Hello, world!」さんです。

Run を押すと。。

![スクリーンショット 2015-12-13 19.06.17.png](https://qiita-image-store.s3.amazonaws.com/0/36620/e9174d20-cac2-f3ea-eaf6-8f314b66e684.png)

Result にちゃんと出力されてますね。


## コード

~~時間がなかったので html ペライチです。~~なんか自動インデントがちゃんと動いていなくてずれるので、js だけ分けました。

css は時間がなかったのでざっくりです

``` html:index.html
<!doctype html>
<html lang="ja">
  <head>
    <meta charset="UTF-8"/>
    <title>シラミ</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
  </head>

  <body>
    <div class="container">
      <div class="row">
        <div class="col-xs-12">
          <h2>シラミで Brainf**k</h2>
        </div>
      </div>

      <div class="row">
        <div class="col-xs-10 col-xs-offset-1">
          <form id="code-form">
            <div class="form-group">
              <label for="code-area"></label>
              <textarea class="form-control" id="code-area" rows="10">ミミミミミミミミミソドミミミミミミミミドミミミミミミミミミミミドミミミミミレレレフラドシドミミシミミミミミミミシシミ
ミミシドフシフフフフフフフフフフフフシレミミミミミミミミシフフフフフフフフシミミミシフフフフフフシフフフフフフフフシドミシ</textarea>
            </div>
            <button type="submit" class="btn btn-primary pull-right" id="button-run">Run</button>
          </form>
        </div>
      </div>

      <div class="row" style="margin-top:20px;display:none;" id="panel-result">
        <div class="col-xs-10 col-xs-offset-1">
          <div class="panel panel-default">
            <div class="panel-heading">
              <h3 class="panel-title">Result</h3>
            </div>
            <div class="panel-body" id="result-area">
            </div>
          </div>
        </div>
      </div>
    </div>

    <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
    <script src="main.js"></script>
  </body>
</html>
```

```js:main.js
(function($) {
    var order = null;

    readOrder().done(function(config) {
        order = config;
        $('#button-run').removeAttr('disabled');
    });


    function readOrder() {
        var deferred = new $.Deferred();
        $.getJSON('./config.json', function(config) {
            deferred.resolve(config);
        });
        return deferred.promise();
    }

    function run(program) {
        var memory = [],
            pointer = 0;

        for (var i = 0; i < 10000; i++) {
            memory[i] = 0;
        }

        for (var pc = 0; pc < program.length; pc++) {

            switch(program[pc]) {
            case order.increment:
                pointer++;
                break;
            case order.decrement:
                pointer--;
                break;
            case order.add:
                memory[pointer]++;
                break;
            case order.subtract:
                memory[pointer]--;
                break;
            case order.begin:
                if (memory[pointer] !== 0) {
                    break;
                }

                var nest = 0;
                while (true) {
                    pc++;
                    if (program[pc] === order.begin) {
                        nest++;
                    }
                    if (program[pc] === order.end && nest === 0) {
                        break;
                    }
                    if (program[pc] === order.end) {
                        nest--;
                    }
                }
                break;
            case order.end:
                if (memory[pointer] === 0) {
                    break;
                }

                var nest2 = 0;
                while (true) {
                    pc--;
                    if (program[pc] === order.end) {
                        nest2++;
                    }
                    if (program[pc] === order.begin && nest2 === 0) {
                        break;
                    }
                    if (program[pc] === order.begin) {
                        nest2--;
                    }
                }
                break;
            case order.output:
                $('#result-area').append(String.fromCharCode(memory[pointer]));
                break;
            }
        }
    }

    $('#code-form').on('submit', function(e) {
        e.preventDefault();
        $('#result-area').empty().show();
        $('#panel-result').show();
        run($('#code-area').val().trim());
    });

})(jQuery);
```

### ちなみに。。

各命令に対応するものは連想配列で保持しているので、変更は容易になっていると思います。


## 所感

* Brainf**k って名前先行で記憶には残っていたけど、改めて実装しようとするとメモリの話とかが出てきて結構勉強になった
  * これを書くためにメモリの話とか勉強したら仕事もガリガリにチューニングしたくなったけど、怒られるのでやめました。
* 本当はプログラム自体をさださんっぽくしたかったので、「北の国から」を考えていたけど、「アウラルンー」の5文字しかなかったので断念。。
* 頭の中のイメージ先行で何かやろうとするとガチな人に囲まれて恥ずかしくなるので気をつけたほうが良い
  * とは言えいつまでも何もしないままだと成長できないのであまり気にしなくて良い気がする