【Programming】Brainf**kを実装してみる

ノベルゲー作りたいな、それにはスクリプトを作らなくちゃいけないな。
というわけでBrainf**kさんに練習台になってもらいました。

正直ノベルゲー作るのの練習にBrainf**k使うのってなんか盛大に間違えてる気がしますが、まぁ雰囲気をつかもうかなぁって感じです。
字句解析とか構文解析とかあんまり関係ないから流れを掴むのには最適だよ(多分)

というわけでC++で実装。

追記:
Twitterでうさぎさんからネストできてないよって指摘があったので修正しました。
あとスタックにあんまり大きい配列入れるのはよくないそうです。
あとcinでは空白がうんたらでやっぱり空白を含むコードをうまく走らせられないようですね。
まぁ・・・別にその辺はwhileあたりをなんとかすればいいのでそんな感じで。

追追記:
なんか「brainf**k 実装」とかいう割と新進気鋭のbrainf*ckerが検索しそうなワードでトップに躍り出てしまうという恐ろしい結果になるのでcin周りの話を解決しました。
ページ下部に実装してて詰まった部分があるので誰か教えてください。
参考サイト
熊本電波高専電子2年情報処理演習
http://www2.ee.knct.ac.jp/el/E2/L210/no1/p05.html

(なんだか僕の大学の演習よりつよそう)

追追追記:
普通にファイルからしか入力できないようにしました。

追追追追記:
ネスト処理がなんかアレだったので変更しました。

#include <iostream>
#include <fstream>
#include <string>
#include <stack>
#include <map>

using namespace std;

int main(int argc ,char* argv[]){

    if(argc != 2){
        cout << "usage: ./brainf**k input.bf" << endl;
        return 1;
    }

    ifstream fin;
    fin.open(argv[1]);
    if(fin.fail()){
        cout << "ifstream fin failed" << endl;
        return 1;
    }

    //file input
    string input;
    string code = "";
    while(fin >> input){
        code = code + input;
    }

    //ネストのマップを作る 
    stack <int> nest_stack;
    map<int,int> nest_map;

    for(int i = 0; i < code.length();i++){
        if(code.at(i) == '['){
            nest_stack.push(i);
        }

        if(code.at(i) == ']'){
            if(!nest_stack.empty()){
                int tmp = nest_stack.top();
                nest_stack.pop();
                nest_map[tmp] = i;
                nest_map[i] = tmp;
            }else{
                code[i] = 'a';//ここの部分そういやテストしてない
            }
        }
    }


    int code_ptr = 0;
    int ptr = 0;
    char buff[1024] = {0};

    while(code.length() > code_ptr){
        char tmp = code.at(code_ptr);

        switch(tmp){
            case '>':
                if(ptr < 1024-1)
                    ptr++;
                break;

            case '<':
                if(ptr > 0)
                    ptr--;
                break;

            case '+':
                buff[ptr]++;
                break;

            case '-':
                buff[ptr]--;
                break;

            case '.':
                cout << buff[ptr] << flush;
                break;

            case ',':
                buff[ptr] = cin.get();
                break;

            case '[':
                if(buff[ptr] == 0)
                    code_ptr = nest_map[code_ptr];
                break;

            case ']':
                if(buff[ptr] != 0)
                    code_ptr = nest_map[code_ptr] - 1;
                break;
        }
        code_ptr++;
    }
    cout << endl; 
    return 0;
}

Input

+++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++++..+++.>-.------------.<++++++++.--------.+++.------.--------.>+.

Output

Hello, world!