Brainfuckインタープリタを書いてみた

あまりにやる気がしないので、試しにBrainfuckインタープリタを書いてみた。バッファサイズを固定しているのでわりかし楽に書けた。とりあえず、WikipediaのHello,World!プログラムは動作を確認した。
brainfuck関数に渡している引数は、1命令バッファ 2Brainfuckバッファ 3Brainfuckバッファの現在指している位置 の三つ。
メインでは、Brainfuckプログラムを行ごとに読み込み、カッコの深さが行末でゼロになっていれば命令を実行して命令バッファをクリア、ということをやってる。
境界条件調べてないので、変なプログラムを動かそうとすると暴走する可能性があります。責任は取りません。
変数名のやる気の無さはほっといて。main関数とbrainfuck関数との変数名の統一感の無さは…、関数ごとに意味合いが違うんだよ〜とか言い訳してみるテスト。

/*
 * Brainfuck Interpreter
 * This program can keep not more than 256 pointers
 * Kihonteki ni tenuki death
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int brainfuck(char *commands, int *buffer, int *current){
	int paren_count = 0;
	char *command = commands;

	for( ; (int)*command != 0; command++ ){
		switch(*command){

		case '+':
			buffer[*current]++;
			break;
		case '-':
			buffer[*current]--; /* no error check*/
			break;

		case '.':
			putchar(buffer[*current]);
			break;
		case ',':
			buffer[*current] = getchar();
			break;

		case '>':
			(*current)++;
			break;
		case '<':
			if(*current > 0){
				(*current)--;
			}else{
				printf("buffer MODORISUGI death\n");
				exit(1);
			}
			break;

		case '[':
			if( buffer[*current] == 0 ){
				paren_count++;
				while( paren_count>0 ){
					command++;
					switch(*command){
					case '[':
						paren_count++;
						break;
					case ']':
						paren_count--;
						break;
					default:
						break;
					}
				}
			}
			break;
		case ']':
			if( buffer[*current] != 0 ){
				paren_count++;
				while( paren_count>0 ){
				command--;
				switch(*command){
					case ']':
						paren_count++;
						break;
					case '[':
						paren_count--;
						break;
					default:
						break;
					}
				}
			}
		}
	}
}

int main(int argc, char *argv[]){
	int bfbuf[256]; /* brainfuck buffer */
	int current = 0;      /* bfbuf current place */

	FILE *fp;
	char inputs[256];  /* get inputs */

	char buffer[1024]; /* bf commands buffer */
	int now_here = 0;  /* ima koko */
	int paren_count = 0; /* paren counter */
	char nextchar;     /* what is read from the input */
	
	memset((void *)bfbuf, 0, sizeof(bfbuf));
	memset((void *)inputs, 0, sizeof(inputs));
	memset((void *)buffer, 0, sizeof(buffer));

	if(argc != 2){
		printf("usage : bf [filename]\n");
		exit(0);
	}
	
	if( !(fp = fopen(argv[1], "r")) ){
		printf("Filename no good.\n");
		printf("Please input readable file name.\n");
		exit(1);
	}
	
	while( fgets(inputs, sizeof(inputs), fp) ){
		int count;
		for( count = 0; inputs[count] != 0; count++){
			switch( nextchar = inputs[count] ){
			case '+':
			case '-':
			case '.':
			case ',':
			case '>':
			case '<':
				buffer[now_here] = nextchar;
				now_here++;
				break;
			case '[':
				paren_count++;
				buffer[now_here] = nextchar;
				now_here++;
				break;
			case ']':
				paren_count--;
				if(paren_count < 0){
					printf("Too Much \']\''s.\n");
					exit(1);
				}
				buffer[now_here] = nextchar;
				now_here++;
			default:
				break;
			}
		}
		if(paren_count == 0){
			brainfuck(buffer,bfbuf, &current);
			
			/* cleanse buffer */
			memset((void *)buffer, 0, sizeof(buffer));
			now_here = 0;
		}
	}
}