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