- 论坛徽章:
- 3
|
解释器又做了优化
- /*bf.c*/
- #include <stdio.h>
- #include <stdlib.h>
- char s[30000]={0};
- char code[100000];
- int len = 0;
- int stack[100];
- int stack_len=0;
- int main(int argc,char**argv)
- {
- char c;
- int i,j,k,x=0;
- int m,n;
- FILE* f;
- char* p=s+10000;
- if(argc==2) {
- f=fopen(argv[1],"r");
- if(f==NULL) {
- perror("fopen");
- return 1;
- }
- if((len=fread(code,1,sizeof(code),f))==0) {
- return 4;
- }
- } else return 2;
- /*optimization*/
- /*We can prove that n is never greater than m.So we can use the same memory*/
- for(m=0,n=0,c=0,j=0;m<len;m++) {
- switch(code[m]) {
- case '+':
- switch (j) {
- case 1:
- code[n++]='>';
- break;
- case -1:
- code[n++]='<';
- break;
- case 0:
- break;
- default:
- code[n++]='p';
- code[n++]=j;
- break;
- }
- j=0;
- c++;
- break;
- case '-':
- switch (j) {
- case 1:
- code[n++]='>';
- break;
- case -1:
- code[n++]='<';
- break;
- case 0:
- break;
- default:
- code[n++]='p';
- code[n++]=j;
- break;
- }
- j=0;
- c--;
- break;
- case '>':
- switch (c) {
- case ((char)1):
- code[n++]='+';
- break;
- case ((char)(-1)):
- code[n++]='-';
- break;
- case ((char)0):
- break;
- default:
- code[n++]='a';
- code[n++]=c;
- break;
- }
- c=0;
- j++;
- if(j==0x7f) {
- code[n++]='p';
- code[n++]=0x7f;
- j=0;
- }
- break;
- case '<':
- switch (c) {
- case ((char)1):
- code[n++]='+';
- break;
- case ((char)(-1)):
- code[n++]='-';
- break;
- case ((char)0):
- break;
- default:
- code[n++]='a';
- code[n++]=c;
- break;
- }
- c=0;
- j--;
- if(j==-128) {
- code[n++]='p';
- code[n++]=-128;
- j=0;
- }
- break;
- case '.':
- case ',':
- case '[':
- switch (c) {
- case ((char)1):
- code[n++]='+';
- break;
- case ((char)(-1)):
- code[n++]='-';
- break;
- case ((char)0):
- break;
- default:
- code[n++]='a';
- code[n++]=c;
- break;
- }
- c=0;
- switch (j) {
- case 1:
- code[n++]='>';
- break;
- case -1:
- code[n++]='<';
- break;
- case 0:
- break;
- default:
- code[n++]='p';
- code[n++]=j;
- break;
- }
- j=0;
- code[n++]=code[m];
- break;
- case ']':
- switch (c) {
- case ((char)1):
- code[n++]='+';
- break;
- case ((char)(-1)):
- code[n++]='-';
- break;
- case ((char)0):
- break;
- default:
- code[n++]='a';
- code[n++]=c;
- break;
- }
- c=0;
- switch (j) {
- case 1:
- code[n++]='>';
- break;
- case -1:
- code[n++]='<';
- break;
- case 0:
- break;
- default:
- code[n++]='p';
- code[n++]=j;
- break;
- }
- j=0;
- if(n-1>=0&&n-2>=0&&code[n-2]=='['&&(code[n-1]=='+'||code[n-2]=='-')) {
- code[n-2]='0';
- n--;
- } else {
- code[n++]=code[m];
- }
- break;
- default:
- break;
- }
- }
- len=n;
- setbuf(stdout,NULL);
- #if 0
- for(i=0;i<len;i++)
- putchar(code[i]);
- return 0;
- #endif
- i=0;
- while(i<len) {
- switch(code[i]) {
- case '0':
- *p=0;
- break;
- case 'a':
- i++;
- *p+=code[i];
- break;
- case 'p':
- i++;
- p+=code[i];
- break;
- case '+':
- (*p)++;
- break;
- case '-':
- (*p)--;
- break;
- case '>':
- p++;
- break;
- case '<':
- p--;
- break;
- case '.':
- putchar((int)(*p));
- //printf("put:%hd\n",*p);
- break;
- case ',':
- *p=getchar();
- break;
- case '[':
- if(*p) {
- stack[stack_len++]=i;
- } else {
- for(k=i,j=0;k<len;k++) {
- if(code[k]=='a'||code[k]=='p') {
- k++;
- continue;
- }
- code[k]=='['&&j++;
- code[k]==']'&&j--;
- if(j==0)break;
- }
- if(j==0)
- i=k;
- else {
- fprintf(stderr,"%s:%d\n",__FILE__,__LINE__);
- return 3;
- }
- }
- break;
- case ']':
- if(*p) {
- i=stack[stack_len - 1];
- #if 0
- if(code[i] != '[') {
- fprintf(stderr,"%s:%d\n",__FILE__,__LINE__);
- return 0;
- }
- #endif
- } else {
- stack_len--;
- }
- break;
- default:
- break;
- }
- i++;
- //x++;
- //printf("%d : i=%d\n",x,i);
- }
- return 0;
- }
复制代码
[ 本帖最后由 cjaizss 于 2008-6-7 12:38 编辑 ] |
|