brainfxxkインタプリタを書いてみました。
使った言語はC、コンパイラはBCCです。
► スポイラーを表示
CODE:
#include
#include
#include
char program[4096]; //プログラム
int memory[256]; //メモリ
int* p; //ポインタ
int loop_nest; //ネストカウンタ
int loop_map[32]; //ループ始端位置記憶
int op; //命令
int nest_jump; //ループジャンプ用
int main(int argc, char* argv[]){
FILE* fp;
int i=0,er = 0;
p = memory;
//コマンドライン引数チェック
if(argc == 1){
printf("ファイルを指定してください。\n");
return -1;
}
//ファイルを開く
if ((fp = fopen(argv[1], "r")) == NULL) {
printf("ファイルを開けませんでした。。\n");
return -1;
}
//ファイルを読み取り、ネストをしらべる
while((op = getc(fp)) != EOF){
if(op > 32){
program[i++] = op;
//
if(op == '[') loop_nest++;
else if(op == ']') loop_nest--;
//ネストカウンタがマイナスになったら処理中断
if(loop_nest ': p++; break;
//ポインタをデクリメント
case '<': p--; break;
//外部への出力
case '.': putchar(*p);
break;
//外部からの入力
case ',': *p = getchar();
break;
//ループ始端
case '[':
//現在の命令位置を記憶
loop_map[loop_nest] = i;
//ネストカウンタを増分
loop_nest++;
//ポインタの参照するアドレスがNULLなら
if(!*p){
//現在のネストカウンタを記憶
nest_jump = loop_nest;
//ネストの終端がくるまでインクリメント
while(nest_jump <= loop_nest){
putchar('!');
i++;
if(program[i]=='[')loop_nest++;
if(program[i]==']')loop_nest--;
}
}
break;
//ループ終端
case ']':
i=loop_map[--loop_nest]-1;
break;
default:
printf("\nWarning : 不明な命令が検出されました。\n");
break;
}
//インクリメント
i++;
}
//printf("\n... %d chars.",i);
return 0;
}
プログラムを書くのにかけた時間は1時間半~2時間ぐらいだと思います。
"[" と "]" のネストをどう処理させるかがよく分からず、結構まわりくどい事してます…。ぐぬぬ…。
こういうアルゴリズムも勉強しないとだめですねー。
そ、その前に課題と大学の入学準備ですが…っ!
追記…
シングルクォートが二重エスケープされてます……?
よ、よくわからないですけど、'をシングルクォートに読み替えていただければ…っ