Neko mimi f**k♥ インタプリタ

defineを書き換えれば前回のTsun dere Fu**♥でも動作する.
東大の実践的プログラミングのwikiにあったソースを元につくりました.
http://www.graco.c.u-tokyo.ac.jp/icpc-challenge/

−−−

#include <stdio.h> 
#include <string.h> 
#define RIGHT "ネコミミ!" 
#define LEFT "ネコミミモード" 
#define PLUS "おにいさま" 
#define MINUS "私のしもべー" 
#define OUT "や・く・そ・く・よ" 
#define IN "フルフルフルムーン" 
#define JP "キスキス…" 
#define LB "キス…したくなっちゃった…" 
#define COMMENT "な・い・しょ・だ・よ" 

unsigned char *a; 

struct data{ 
char s[30]; 
int len; 
int ope; 
}; 

#ifdef __GNUC__ 
#include <sys/stat.h> 
int filelength(int f){ 
struct stat b; 
if(fstat(f,&b)==-1)return -1; 
return b.st_size; 
} 
#endif 

int *cmp(struct data *a,struct data *b){ 
return strlen(a->s)-strlen(b->s); 
} 

void execute(char *p){ 
char *x=p,c; 
int i=0,marker; 
while(c=*(x+i)){ 
i++; 
switch(c){ 
case 1: a++;break; 
case 2: a--;break; 
case 3: (*a)++;break; 
case 4: (*a)--;break; 
case 5: putchar(*a);break; 
case 6: *a=getchar();break; 
case 7: if(*a)execute(x+i); 
marker=1; 
while(marker){ 
if(*(x+i)==7)marker++; 
if(*(x+i)==8)marker--; 
i++; 
} 
break; 
case 8: if(*a)i=0;else return;break; 
default: return; 
} 
} 
} 

int L_Change(struct data word[8],FILE *f){ 
char op[30]; 
int i,l,p=0; 
memset(op,0,sizeof(char)*30); 
for(i=0;i<9;i++){ 
for(;op[p]!=EOF&&p<word[i].len;op[p]=='\n'||op[p]==' '||op[p]=='\t'?p--:p)op[p++]=fgetc(f); 
if(strcmp(word[i].s,op)==0){ 
printf("%s\n",word[i].s); 
return word[i].ope; 
} 
} 
return -1; 
} 

int main(int argc, char **argv){ 
int c,i,l; 
unsigned char *da; 
char *p,*x; 
FILE *f; 
struct data word[9]; 
if(argc!=2){printf("Brainfuck Interpreter\nUsage: bf _.bf\n");return 1;} 
f=fopen(argv[1],"r"); 
if(!f){printf("Cannot open file: %s",argv[1]);return 2;} 

l=filelength(fileno(f)); 
x=p=malloc(l); 
memset(p,0,l); 
da=a=malloc(0x10000); 
memset(a,0,0x10000); 

strcpy(word[0].s,RIGHT); 
strcpy(word[1].s,LEFT); 
strcpy(word[2].s,PLUS); 
strcpy(word[3].s,MINUS); 
strcpy(word[4].s,OUT); 
strcpy(word[5].s,IN); 
strcpy(word[6].s,JP); 
strcpy(word[7].s,LB); 
strcpy(word[8].s,COMMENT); 
for(i=0;i<9;i++){ 
word[i].len=strlen(word[i].s); 
word[i].ope=i+1; 
} 
qsort(word,9,sizeof(struct data),cmp); 

i=0; 
while( (c=L_Change(word,f))>=0 ){ 
switch(c){ 
case 1: 
case 2: 
case 3: 
case 4: 
case 5: 
case 6: *(x++)=c;break; 
case 7: i++;*(x++)=c;break; 
case 8: i--;*(x++)=c;break; 
case 9: while( (c=fgetc(f))!='\n' )if(c==EOF)break;break; 
} 
} 

fclose(f); 
i ? printf("COMPILE ERROR\n") : (execute(p),printf("\n")); 
free(p);free(da); 
return 0; 
} 

−−−−−−−−−−−−−−−−−−−−−−−−−−−−

改行コードを気にしないと動作しないのはご愛嬌。
スペース、タブを無視することをしようと思ったけど、文字コードの壁に阻まれ、うまく動作しない。マルチバイトのスペース、タブってどんな扱いなのだろうか。