Brainfuck + ちょっと拡張
今回は、Brainfuck について...
Brinfuck は8つしか命令がないチューリング完全な難解プログラミング言語です。
8つとは、< > + - , . [ ] のことです。それぞれ,ポインタ移動、加減、1文字入力、1文字出力、ループとか... になっています。詳しくは Brainfuck - Wikipediaなどを参考にしてください。
今回は、Brainfuck の interpreter を作りました。+少し拡張して、# という命令を入れました。
# はポインタの指す値を、.では、文字(ASCIIとか)で表示しますが、# では、数字として表示します。
要するに、
-
-
-
-
-
-
-
- [>++++++++<-]>+.
-
-
-
-
-
-
とすると
A
と表示されますが、
-
-
-
-
-
-
-
- [>++++++++<-]>+#
-
-
-
-
-
-
とすると
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のコードを実行時します。 */