basic中next转为c语言,[转载]混乱c语言代码写的basic解释器
中的 國際c語言混亂代碼大賽
倫敦大學的研究生Diomidis Spinellis用一千五百多個字符寫了個basic解釋器
我抄時錯添漏字符,所以不能運行,留個標本
#define O(b,f,u,s,c,a)
b() {int o=f();switch(*p++){X u:_ o s b();X c:_ o a
b();default:p--;_o;}}
#define t(e,d,_,C)X e:f=fopen(B+d,_);C;fclose(f)
#define U(y,z) while(p=Q(s,y)*p++=z,*p=' ')
#define N for(i=0;i<11*R;i++)
m[i]&&
#define I "%d %sn", i, m[i]
#define X ;break;case
#define _ return
#define R 999
typedef char *A; int*C,E[R],L[R],M[R],P[R],l,i,j;char B[R],F[2];A
m[12*R],
malloc(),p,q,x,y,z,s,d,f,fopen();A Q(s,o)A
s,o;{for(x=s;*x,x++){for(y=x,z=
0;*z&&*y==*z;y++)z++;if(z>o&&!*z)_
x;}_0;}main(){m[11*r]="E";while(?puts
("OK"),gets(B))switch(*B){X'R':C=E;l=1;for(i=0;i
(!(s=m[1]))l++;if(!Q(s,""")){U("<>",'#');U("<=",'$');U(">=",'!');}d=B;
while(*F=*S){*s=='"'&&j++;if(j&&1||!Q("t",F))*d++=*s;s++;}*d--=j=0;if(B[1]
!='=')switch(*B){X'E':l=-lX'R':B[2]!='M'&&(l=*--C)X'I':B[1]=='N'?gets(p=B
),P[*d]=S():(*(q=Q(B,"TH"))=0,p=B+2,S()&&(p=q+4,l=s()-1)X'P':B[5]=='"'?*d=
0,puts(B+6):(p=B+5,printf("%dn",S()))X'G':p=B+4,B[2]=='S'&&(*C++=1,p++),l
=S()-1X'F':*(q=Q(B,"TO"))=0;p=B+5;p[i=B[3]]=S();p=q+2;M[i]=S();L[i]=1X'?N':
++p[*d]<=M[*d]&&(l=L[*d]);)else
p=B+2,P[*B]=S();l++;}X'L':N printf (I) X'N':
N free(m[i]),m[i]=0 X'B':_ 0 t('S',5,"w",N
fprintf(f,I))t('O',4,"r",while
(fgets(B,R,f))(*Q(B,"n")=0,G()))X0:default:G();}_0;}G(){l=atoi(B);m[l]&&free
(m[l]);(p=Q(B,""))?strcopy(m[l]=malloc(strlen(p)),p+1):(m[l]=0,0);}O(S,J
,'=',==,'#',!=)O(J,K,'',>)O(K,V,'$',<=,'!',>=)O(V,W,'+',+,'-',-)O(W,
Y,'*',*,'/',/)Y(){int
o;_*p=='-'?p++,-Y():*p>='0'&&p<='9'?strto
l(p,&p,0):
*p=='('?p++,o=S(),p++,o:P[*p++];?)}}
我把混亂代碼拆開整理一下,編譯通不過,需要調試,先運行沒有行號的直接命令:
所有的輸入必須是大寫RUN LIST NEW BYE OLD文件名 SAVE文件名
實現的順序是BYE LIST OLD SAVE NEW RUN
編譯通過,可以運行
int *C,E[999],L[999],M[999],P[999],l,i,j;
char B[999],F[2];
char *m[12000],*malloc(),*p,*q,*x,*y,*z,*s,*d,*f,*fopen();
char *Q(char *s,char *o)?匹配函數
{
for(x=s; *x; x++)
{
for(y=x,z=o;
*z && ((*y) == (*z)); y++)
z++;
if((z>o) && (!
*z))
return x;
}
return 0;
}
main()
{
m[11000]="E";?最后行設為END
while(puts("OK"),gets(B))?顯示OK , 等待輸入
switch(*B){?輸入開關
case
'R':C=E;?是RUN 暫時略,短接掉
break;
case
'L':?是LIST 顯示源代碼
for(i=0;i<11000;i++)
m[i] && printf( "%d %sn", i,
m[i]);
break;
case 'N':?是NEW
清代碼行
for(i=0;i<11000;i++)
m[i] && free(m[i]),m[i]=0 ;
break;
case 'B':?是BYE
退出
return 0 ;
case
'S':?是SAVE 存盤
f=fopen(B+5,"w");
for(i=0;i<11000;i++)
m[i] && fprintf(f,"%d %sn", i,
m[i]);
fclose(f);
break;
case 'O':?是OLD
讀盤。為何不用LOAD? 怕和LIST同名
f=fopen(B+4,"r");
while(fgets(B,999,f))?行長999字符
(*Q(B,"n") =
0,G());?回車符用0代替,輸入一行句子
fclose(f);
break;
case 0:
default:
G();?不是命令,輸入一句BASIC源代碼
}
return
0;
}
G()?輸入一行句子
{
l=atoi(B);?行號
m[l]
&&
free(m[l]);?清這行代碼
if (p = Q(B,"
"))?行號和BASIC代碼間有一空格
strcpy(m[l]=malloc(strlen(p)),p+1);?代碼存放入*M[]指針數組,共11000行
else
(m[l]=0);return 0;
行號后內容為空表示刪除該行
}
實現帶行號的命令,編譯通過,可以運行,沒有仔細測試,大概湊活
實現的順序是RUN PRINT var=exp INPUT GOTO GOSUB RETURN IF exp THEN FOR
ver=exp TO NEXT
main() 注解不見得對,有點搞糊涂了,不要當真
{
m[11000]="E";?末行設為END
while(puts("OK"),gets(B)) 顯示OK,鍵入命令
switch(*B){
case
'R':C=E;?是運行命令RUN
LL=1;?本來變量是小寫的l,容易和1搞混,大寫的L已經有了,就寫成了LL,表示行號
for(i=0;i<999;P[i++]=0);?變量初始化為0
while(LL){?行號
while(!(s = m[LL]))
LL++;?不是空行,s是BASIC源代碼本行首地址
if(!Q(s,""")){?不是冒號
while(p=Q(s,"<>")) *p++='#',*p=' ';
換碼,把不等號換成#號
while(p=Q(s,"<=")) *p++='$',*p=' ';
while(p=Q(s,">=")) *p++='!',*p=' ';
}
d=B;?是冒號,處理字符串。指針d指向B[]
while(*F=*s){?數組變量F[2]只有兩個:F[0]和F[1],先設為s,也就是本行地址
*s=='"'&&j++;?是字符串
if(j&&1||!Q("t",F))
*d++=*s;?制表符tab 。指針d的內容等于本行地址內容
s++;?}
*d--=j=0;?清0初始化j, 并用0取代冒號
if(B[1]!='=')?是變量嗎? B[0]指向變量名,B[1]是=號
switch(*B){?不是變量,B[0]是命令的第一個字母
case 'E':LL
= -1;?是END,行號設負壹,出switch后增壹,等于零,出while(LL)循環
break;
case
'R':?是RUN REM RETURN?((B[2]!='M')?第三個字母是M,是REM
注釋
&&
(LL =
*(--C))); 如果是RETURN,調整行號
break;
case
'I':?是IF INPUT
if(B[1]=='N')?是INPUT
gets(p=B),P[*d]=S();?等鍵入,存入變量
else{
(*(q=Q(B,"TH")))=0;?是IF,找THEN
p=B+3;?本來是B+2的,指向空格,總不能是IFA=123吧?
S()?表達式計算
&&
(p=q+5,LL=S()-1);?跳過THEN空格,計算地址,行號為什么要減一呢?
出switch后增
}
break;
case
'P':?打印命令PRINT
if(B[6]=='"')?如果PRINT空格,后是冒號
*d=0,?冒號用0替換
puts(B+7);?打印字符串
else
(p=B+6,printf("%dn",S()));?打印數字
break;
case
'G':?是GOTO GOSUB
p=B+5,?指向GOTO空格后的行號數字位
B[2]=='S'&&(*C++=LL,p++),
第三個字母是S,是GOSUB,C[]存RETURN返回行號
LL=S()-1;?調整行號
break;
case
'F':?是循環FOR
*(q=Q(B,"TO"))=0;?找TO地址
p=B+6;?指向FOR
X=位
P[i=B[4]]=S();?變量名存入i, 變量存入P[i]
p=q+3;?指向TO空格,后
總結
以上是生活随笔為你收集整理的basic中next转为c语言,[转载]混乱c语言代码写的basic解释器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 分布式资本沈波:未来区块链杀手级应用将出
- 下一篇: c语言枚举入门,C语言入门之枚举与位运算