ttki's diary

プログラミング好きな人の日記です

Brainfuck + ちょっと拡張

今回は、Brainfuck について...

Brinfuck は8つしか命令がないチューリング完全な難解プログラミング言語です。
8つとは、< > + - , . [ ] のことです。それぞれ,ポインタ移動、加減、1文字入力、1文字出力、ループとか... になっています。詳しくは Brainfuck - Wikipediaなどを参考にしてください。

今回は、Brainfuckinterpreter を作りました。+少し拡張して、# という命令を入れました。
# はポインタの指す値を、.では、文字(ASCIIとか)で表示しますが、# では、数字として表示します。
要するに、

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

とすると
A
と表示されますが、

                1. [>++++++++<-]>+#

とすると
65
と表示されます。(すこしデバッグをやりやすくするために追加しました)

というわけで、今回のコードです。

#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;

class BFI
{
private:

public:
	char *s;
	int v[1024], pos;
	int loop;
	int slen;

	BFI():v(),pos(0),loop(0),s(){}; 
	~BFI(){ delete[] s; };
	int set(char *str);
	int run();
};

int BFI::set(char *str)
{
	slen = strlen(str) + 1;//\0
	s = new char[slen]();
	strcpy(s, str);
	return 0;
}


int BFI::run()
{
	for(int i=0; i < slen; i++)
	{
		switch(s[i])
		{
		case '>':
			pos++;
			break;

		case '<':
			pos--;
			break;

		case '+':
			v[pos]++;
			break;

		case '-':
			v[pos]--;
			break;

		case '.':
			printf("%c", v[pos]);
			break;

		case '#':
			cout << v[pos] << endl;
			break;

		case ',':
			v[pos] = getchar();
			break;

		case '[':
			if(v[pos] == 0)
			{
				for(i++; loop > 0 || s[i] != ']'; i++){
					if(s[i] == '[')
						loop++;
					if(s[i] == ']')
						loop--;
				}
			}
			break;

		case ']':
			if(v[pos] != 0)
			{
				for(i--; loop > 0 || s[i] != '['; i--){
					if(s[i] == ']')
							loop++;
					if(s[i] == '[')
							loop--;
					}
				i--;
			}
			break;
		}
	}
	return 0;
}

int main()
{
	BFI brainfuckinterpreter;
	char *code =	"++++++++[>+++++++++<-]>."//72 h
			"---."//69 e
			"+++++++.."//76 ll
			"+++."//79 HELLO o
			"<+++++[>---------<-]>--."//32 
			"<+++++[>+++++++++++<-]>."//87 w
			"--------."//79 o
			"+++."//82 r
			"------."// 76 l
			"<++++[>--<-]>."// 68 d
			"<+++++[>-------<-]>."//33 !
			"<+++++[>----<-]>---.";// 10 \n

	brainfuckinterpreter.set(code);
	

	brainfuckinterpreter.run();

}

/*
BFI ... Brainfuckinterpreter Object
BFI::set() ... BrainfuckのコードをBFI::sにセットします。
BFI::run() ... BFI::sのコードを実行時します。
*/