📄 pl0v4.c
字号:
} else
if (sym==callsym) {
getsym();
if (sym!=ident) error(14); else
{ i=position(id, ptx);
if(i==0) error(11); else
{
getsym();
if (sym==lparen) {getsym(); aparam(lev,ptx);
if (sym==rparen) getsym(); else error(89);
}
if (table[i].kind==procedure) gen(cal,lev-table[i].level, table[i].adr);
else error(15);
}
}
} else
if (sym==ifsym) {
getsym(); condition(lev,ptx);
if (sym==thensym) getsym(); else error(16);
cx1=cx; gen(jpc,0,0);
statement(lev, ptx); code[cx1].a=cx;
} else
if (sym==beginsym) {
getsym();
statement(lev,ptx);
while((sym==semicolon)||(sym==beginsym)||
(sym==ifsym)||(sym==whilesym)||
(sym==callsym)||(sym==writesym)||
(sym==dspsym)) {
if(sym==semicolon) getsym(); else error(10);
statement(lev,ptx);
}
if (sym==endsym) getsym(); else error(17);
} else
if (sym==whilesym) {
cx1=cx; getsym(); condition(lev,ptx);
cx2=cx; gen(jpc,0,0);
if (sym==dosym) getsym(); else error(18);
statement(lev,ptx); gen(jmp,0,cx1); code[cx2].a=cx;
} else
if (sym==writesym) {
getsym();
if (sym!=lparen) error(98); else {
getsym(); expression(lev, ptx); gen(wrt,0,0);
if (sym!=rparen) error(99); else getsym();
}
}
if (sym==dspsym) {
getsym();
if (sym!=lparen) error(98); else {
getsym(); expression(lev, ptx); gen(dsp,0,0);
if (sym!=rparen) error(99); else getsym();
}
}
if (sym==colorsym) {
getsym();
if (sym!=lparen) error(98); else {
getsym(); expression(lev,ptx); gen(clr,0,0);
if (sym!=rparen) error(99); else getsym();
}
}
if (sym==drawsym) {
getsym();
if (sym!=lparen) error(98); else {
getsym(); expression(lev, ptx);
getsym(); expression(lev, ptx);
if (sym!=rparen) error(99); else getsym();
gen(drw,0,0);
}
}
if (sym==erasesym) {
getsym();
if (sym!=lparen) error(98); else {
getsym(); expression(lev, ptx);
getsym(); expression(lev, ptx);
if (sym!=rparen) error(99); else getsym();
gen(ers,0,0);
}
}
}
fparam(lev,ptx,pdx)
int lev, *ptx,*pdx;
{
if (sym==varsym) {flag=1; getsym();} else flag=0;
if(sym==ident)vardeclaration(lev,ptx,pdx); else error(81);
flag=0;
while (sym==comma){
getsym();if (sym==varsym) {flag=1; getsym();} else flag=0;
vardeclaration(lev,ptx,pdx); flag=0;
}
if(sym!=rparen) error(82);
}
aparam(lev,ptx)
int lev, *ptx;
{
int pnum=0; int adr,level;
if(sym==amper) {
getsym(); if(sym!=ident) error(70);
i=position(id,ptx); adr=table[i].adr; level=table[i].level;
gen(lda,lev-level,adr); getsym();}
else expression(lev,ptx);
pnum++;
while (sym==comma){
getsym();
if(sym==amper){
getsym(); if (sym!=ident) error(70);
i=position(id,ptx); adr=table[i].adr; level=table[i].level;
gen(lda,lev-level,adr); getsym();}
else expression(lev,ptx);
pnum++;
}
while(pnum>0){gen(stp,0,3); pnum--;}
}
block(lev, tx)
int lev;
int tx;
{
int dx, tx0, cx0;
dx=3; tx0=tx; table[tx].adr=cx; gen(jmp,0,0);
if (lev>levmax) error(32);
do {
if (sym==constsym) {
getsym();
do {
constdeclaration(lev,&tx,&dx);
while(sym==comma) {
getsym(); constdeclaration(lev,&tx,&dx);
}
if(sym==semicolon)getsym(); else error(5);
} while (sym==ident);
}
if (sym==varsym) {
getsym();
do { vardeclaration(lev,&tx,&dx);
while (sym==comma) {
getsym(); vardeclaration(lev,&tx,&dx);
}
if(sym==semicolon) getsym(); else error(5);
} while(sym==ident);
}
if (sym==lparen) {
getsym(); fparam(lev,&tx,&dx);
if (sym==rparen) getsym(); else error(88);
}
while(sym==procsym) {
getsym();
if(sym==ident){
enter(procedure,&tx,&dx,lev); getsym();
} else error(4);
if (sym==semicolon) getsym(); else if
(sym==lparen); else error(5);
block(lev+1, tx);
if(sym==semicolon) {
getsym();
} else error(5);
}
}while ((sym==constsym)||(sym==varsym)||(sym==procsym));
code[table[tx0].adr].a=cx;
table[tx0].adr=cx;
cx0=cx; gen(inc,0,dx);
statement(lev,&tx);
gen(opr,0,0);
}
int base(l,b)
int l,b;
{
int b1; //find base l levels down
b1=b;
while (l>0) {
b1=s[b1]; l--;
}
return b1;
}
interpret()
{
int stacksize=500;
int p,b,t; //program-, base-, topstack-registers
int i; // instruction register
printf("start PL/0\n");
t=0; b=1; p=0;
s[1]=0; s[2]=0; s[3]=0;
do {
i=code[p].f;
switch (i) {
case 1: t++; s[t]=code[p].a; p++; break; //lit
case 2:
switch (code[p].a) {
case 0: { /* return */ t=b-1; p=s[t+3]; b=s[t+2];
break;}
case 1: s[t]=-s[t]; p++; break;
case 2: t--; s[t]=s[t]+s[t+1]; p++; break;
case 3: t--; s[t]=s[t]-s[t+1]; p++; break;
case 4: t--; s[t]=s[t]*s[t+1]; p++; break;
case 5: t--; s[t]=s[t]/s[t+1]; p++; break;
case 6: if ((s[t]%2)==1) s[t]=1; else s[t]=0; p++; break;
case 7: p++; break;
case 8: t--; s[t]=(s[t]==s[t+1]); p++; break;
case 9: t--; s[t]=(s[t]!=s[t+1]); p++; break;
case 10: t--; s[t]=(s[t]<s[t+1]); p++; break;
case 11: t--; s[t]=(s[t]<=s[t+1]); p++; break;
case 12: t--; s[t]=(s[t]>s[t+1]); p++; break;
case 13: t--; s[t]=(s[t]>=s[t+1]); p++; break;
} break;
case 3: t++; s[t]=s[base(code[p].l,b)+code[p].a]; p++; break;
case 4: s[base(code[p].l,b)+code[p].a]=s[t];
p++; t--; break;
case 5: /* generate new block mark */
s[t+1]=base(code[p].l,b); s[t+2]=b; s[t+3]=p+1;
b=t+1; p=code[p].a; break;
case 6: t=t+code[p].a; p++; break;
case 7: p=code[p].a; break;
case 8: if (s[t]==0) p=code[p].a; else p++;
t--; break;
case 9: printf("%d\n",s[t]); t--; p++; break;
case 10: s[t+3]=s[t]; t--; p++; break;
case 11: t++; s[t]=s[s[base(code[p].l,b)+code[p].a]];p++; break;
case 12: t++; s[t]=base(code[p].l,b)+code[p].a;p++;break;
case 13: s[s[base(code[p].l,b)+code[p].a]]=s[t]; p++; t--; break;
case 14: disp(s[t],s[t]); p++; t--; break;
case 15: point(1,s[t-1],s[t]); p++; t--; t--; break;
case 16: point(-1,s[t-1],s[t]); p++; t--; t--; break;
case 17: setcolor(s[t]); p++; t--; break;
}
// printf("%d ",p);
// for(ii=1;ii<=t;ii++)printf("%d ", s[ii]);
// getchar();
} while (p!=0);
printf(" END PL/0\n");
}
disp(ix,iy)
int ix,iy;
{
d=XOpenDisplay((getenv("DISPLAY") != NULL)?getenv( "DISPLAY"):":0");
f=XLoadFont(d,"r14");
black = BlackPixel(d, 0);
white = WhitePixel(d, 0);
cmap=DefaultColormap(d,0);
XAllocNamedColor(d,cmap,"red",&red,&c0);
XAllocNamedColor(d,cmap,"green",&green,&c0);
XAllocNamedColor(d,cmap,"blue",&blue,&c0);
w=XCreateSimpleWindow(d,DefaultRootWindow(d),0,0,ix,iy,5,
black, white);
XSelectInput(d,w,ButtonPressMask|ButtonReleaseMask|ButtonMotionMask);
XMapWindow(d,w);
gc=XCreateGC(d,w,0,0);
XSetFont(d,gc,f);
XSetLineAttributes(d, gc, 2, LineSolid, CapRound, JoinRound);
// XSetForeground(d, gc, black);
XFlush(d);
}
setcolor(k)
int k;
{
original=k;
switch (k) {
case 0: XSetForeground(d,gc,white); break;
case 1: XSetForeground(d,gc,black); break;
case 2: XSetForeground(d,gc,red.pixel); break;
case 3: XSetForeground(d,gc,green.pixel); break;
case 4: XSetForeground(d,gc,blue.pixel); break;
}
XFlush(d);
};
point(k,x,y)
int k,x,y;
{
int temp;
// if (k>0) XSetForeground(d,gc,red.pixel);
// else XSetForeground(d,gc,white);
temp=original;
if (k<0) {
XSetForeground(d,gc,white);
XDrawPoint(d,w,gc,x,y);
setcolor(temp);
} else
XDrawPoint(d,w,gc,x,y);
XFlush(d);
}
main(argc,argv)
int argc;
char *argv[];
{
word[1]="begin"; word[2]="call"; word[3]="const"; word[4]="do";
word[5]="end"; word[6]="if"; word[7]="odd"; word[8]="procedure";
word[9]="then"; word[10]="var"; word[11]="while"; word[12]="write";
word[13]="display"; word[14]="draw"; word[15]="erase"; word[16]="color";
wsym[1]=beginsym; wsym[2]=callsym; wsym[3]=constsym; wsym[4]=dosym;
wsym[5]=endsym; wsym[6]=ifsym; wsym[7]=oddsym; wsym[8]=procsym;
wsym[9]=thensym; wsym[10]=varsym; wsym[11]=whilesym; wsym[12]=writesym;
wsym[13]=dspsym; wsym[14]=drawsym; wsym[15]=erasesym; wsym[16]=colorsym;
ssym['+']=plus; ssym['-']=minus; ssym['*']=mult; ssym['/']=slash;
ssym['(']=lparen; ssym[')']=rparen; ssym['=']=eql; ssym[',']=comma;
ssym['.']=period; ssym['#']=neq; ssym['<']=lss; ssym['>']=gtr;
ssym['$']=leq; ssym['%']=geq; ssym[';']=semicolon; ssym['&']=amper;
//scanf("%s",fname);
f=fopen(*++argv,"r");
kk=al;
cc=0; ll=0; ch=' '; cx=0;
getsym();
block(0,0);
getchar();
getchar();
for (i=0;i<=cx-1;i++) {
if (i<10) printf(" ");
printf("%d ",i);
switch (code[i].f) {
case 1: printf("lit "); break;
case 2: printf("opr "); break;
case 3: printf("lod "); break;
case 4: printf("sto "); break;
case 5: printf("cal "); break;
case 6: printf("inc "); break;
case 7: printf("jmp "); break;
case 8: printf("jpc "); break;
case 9: printf("wrt "); break;
case 10: printf("stp "); break;
case 11: printf("lid "); break;
case 12: printf("lda "); break;
case 13: printf("sid "); break;
case 14: printf("dsp "); break;
case 15: printf("drw "); break;
case 16: printf("ers "); break;
case 17: printf("clr "); break;
}
printf("%d ", code[i].l);
printf("%d ", code[i].a);
printf("\n");
// getchar();
}
if (sym!=period) error(9);
getchar();
interpret();
getchar();
getchar();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -