1. 程式人生 > >用C語言寫PL0編譯器

用C語言寫PL0編譯器

#include<stdio.h>
/*#include"pl0.h"*/
#include"string.h"
#include <windows.h>

/*PL/0編譯系統C版本標頭檔案pl0.h*/
/*typedef enum{false,true}bool;*/
#define norw 13
#define txmax 100
#define nmax 14
#define al 10
#define amax 2047
#define levmax 3
#define cxmax 200

enum symbol{
	nul,ident,number,plus,minus,times,slash,oddsym,eql,neq,lss,leq,gtr,geq,lparen,rparen,comma,semicolon,period,
	becomes,beginsym,endsym,ifsym,thensym,whilesym,writesym,readsym,dosym,callsym,constsym,varsym,procsym,
};
#define symnum 32

enum object{
	constant,
	variable,
	procedur,
};

enum fct{
	lit,opr,lod,sto,cal,inte,jmp,jpc,
};
#define fctnum 8

struct instruction
{
	enum fct f;
	int l;
	int a;
};
FILE* fas;
FILE* fa;
FILE* fa1;
FILE* fa2;
bool listswitch;
bool tableswitch;
char ch;
enum symbol sym;
char id[al+1];
int num;
int cc,ll;
int cx;
char line[81];
char a[al+1];
struct instruction code[cxmax];
char word[norw][al];
enum symbol wsym[norw];
enum symbol ssym[256];
char mnemonic[fctnum][5];
bool declbegsys[symnum];
bool statbegsys[symnum];
bool facbegsys[symnum];

struct tablestruct
{
	char name[al];
	enum object kind;
	int val;
	int level;
	int adr;
	int size;
};
struct tablestruct table[txmax];
FILE* fin;
FILE* fout;
char fname[al];
int err;

#define getsymdo if(-1==getsym())return -1
#define getchdo if(-1==getch())return -1
#define testdo(a,b,c) if(-1==test(a,b,c))return -1
#define gendo(a,b,c) if(-1==gen(a,b,c))return -1
#define expressiondo(a,b,c) if(-1==expression(a,b,c))return -1
#define factordo(a,b,c) if(-1==factor(a,b,c))return -1
#define termdo(a,b,c) if(-1==term(a,b,c))return -1
#define conditiondo(a,b,c) if(-1==condition(a,b,c))return -1
#define statementdo(a,b,c) if(-1==statement(a,b,c))return -1
#define constdeclarationdo(a,b,c) if(-1==constdeclaration(a,b,c))return -1
#define vardeclarationdo(a,b,c) if(-1==vardeclaration(a,b,c))return -1
void error(int n);
int getsym();
int getch();
void init();
int gen(enum fct x,int y,int z);
int test(bool* s1,bool* s2,int n);
int inset(int e,bool* s);
int addset(bool* sr,bool* s1,bool* s2,int n);
int subset(bool* sr,bool* s1,bool* s2,int n);
int mulset(bool* sr,bool* s1,bool* s2,int n);
int block(int lev,int tx,bool* fsys);
void interpret();
int factor(bool* fsys,int* ptx,int lev);
int term(bool* fsys,int* ptx,int lev);
int condition(bool* fsys,int* ptx,int lev);
int expression(bool* fsys,int* ptx,int lev);
int statement(bool* fsys,int* ptx,int lev);
void listcode(int cx0);
int vardeclaration(int* ptx,int lev,int* pdx);
int constdeclaration(int* ptx,int lev,int*pdx);
int position(char* idt,int tx);
void enter(enum object k,int* ptx,int lev,int* pdx);
int base(int l,int* s,int b);








#define stacksize 500
int main()
{
	bool nxtlev[symnum];
	printf("Input pl/0 file?");
	scanf("%s",fname);
	fin=fopen(fname,"r");
	if(fin)
	{
		printf("List object code? (Y/N)");
		scanf("%s",fname);
		listswitch=(fname[0]=='y'||fname[0]=='Y');
		printf("List symbol table?(Y/N)");
		scanf("%s",fname);
		tableswitch=(fname[0]=='y'||fname[0]=='Y');
		fa1=fopen("fa1.tmp","w");
		fprintf(fa1,"Input pl/0 file?");
		fprintf(fa1,"%s\n",fname);
		init();
		err=0;
		cc=cx=ll=0;
		ch=' ';
		if(-1!=getsym())
		{
			fa=fopen("fa.tmp","w");
			fas=fopen("fas.tmp","w");
			addset(nxtlev,declbegsys,statbegsys,symnum);
			nxtlev[period]=true;
			if(-1==block(0,0,nxtlev))
			{
				fclose(fa);
				fclose(fa1);
				fclose(fas);
				fclose(fin);
				printf("\n");
				return 0;
			}
			fclose(fa);
			fclose(fa1);
			fclose(fas);
			if(sym!=period)
			{
				error(9);
			}
			if(err==0)
			{
				fa2=fopen("fa2.tmp","w");
				interpret();
				fclose(fa2);
			}
			else
			{
				printf("Errors in pl/0 program");
			}
		}
		fclose(fin);
	}
	else
	{
		printf("Can't open file!\n");
	}
	printf("\n");
	return 0;
}
void init()
{
	int i;
	for(i=0;i<=255;i++)
	{
		ssym[i]=nul;
	}
	ssym['+']=plus;
	ssym['-']=minus;
	ssym['*']=times;
	ssym['/']=slash;
	ssym['(']=lparen;
	ssym[')']=rparen;
	ssym['=']=eql;
	ssym[',']=comma;
	ssym['.']=period;
	ssym['#']=neq;
	ssym[';']=semicolon;

	strcpy(&(word[0][0]),"begin");
	strcpy(&(word[1][0]),"call");
	strcpy(&(word[2][0]),"const");
	strcpy(&(word[3][0]),"do");
	strcpy(&(word[4][0]),"end");
	strcpy(&(word[5][0]),"if");
	strcpy(&(word[6][0]),"odd");
	strcpy(&(word[7][0]),"procedure");
	strcpy(&(word[8][0]),"read");
	strcpy(&(word[9][0]),"then");
	strcpy(&(word[10][0]),"var");
	strcpy(&(word[11][0]),"while");
	strcpy(&(word[12][0]),"write");

	wsym[0]=beginsym;
	wsym[1]=callsym;
	wsym[2]=constsym;
	wsym[3]=dosym;
	wsym[4]=endsym;
	wsym[5]=ifsym;
	wsym[6]=oddsym;
	wsym[7]=procsym;
	wsym[8]=readsym;
	wsym[9]=thensym;
	wsym[10]=varsym;
	wsym[11]=whilesym;
	wsym[12]=writesym;

	strcpy(&(mnemonic[lit][0]),"lit");
	strcpy(&(mnemonic[opr][0]),"opr");
	strcpy(&(mnemonic[lod][0]),"lod");
	strcpy(&(mnemonic[sto][0]),"sto");
	strcpy(&(mnemonic[cal][0]),"cal");
	strcpy(&(mnemonic[inte][0]),"int");
	strcpy(&(mnemonic[jmp][0]),"jmp");
	strcpy(&(mnemonic[jpc][0]),"jpc");

	for(i=0;i<symnum;i++)
	{
		declbegsys[i]=false;
		statbegsys[i]=false;
		facbegsys[i]=false;
	}

	declbegsys[constsym]=true;
	declbegsys[varsym]=true;
	declbegsys[procsym]=true;

	statbegsys[beginsym]=true;
	statbegsys[callsym]=true;
	statbegsys[ifsym]=true;
	statbegsys[whilesym]=true;

	facbegsys[ident]=true;
	facbegsys[number]=true;
	facbegsys[lparen]=true;
}


int inset(int e,bool *s)
{
	return s[e];
}
int addset(bool *sr,bool *s1,bool *s2,int n)
{
	int i;
	for(i=0;i<n;i++)
	{
		sr[i]=s1[i]||s2[i];
	}
	return 0;
}
int subset(bool *sr,bool *s1,bool *s2,int n)
{
	int i;
	for(i=0;i<n;i++)
	{
		sr[i]=s1[i]&&(!s2[i]);
	}
	return 0;
}
int mulset(bool *sr,bool *s1,bool *s2,int n)
{
	int i;
	for(i=0;i<n;i++)
	{
		sr[i]=s1[i]&&s2[i];
	}
	return 0;
}


void error(int n)
{
	char space[81];
	memset(space,32,81);
	space[cc-1]=0;
	printf("****%s!%d\n",space,n);
	fprintf(fa1,"****%s!%d\n",space,n);
	err++;
}




int getch()
{
	if(cc==ll)
	{
		if(feof(fin))
		{
			printf("program incomplete");
			return -1;
		}
		ll=0;
		cc=0;
		printf("%d",cx);
		fprintf(fa1,"%d",cx);
		ch=' ';
		while(ch!=10)
		{
			if(EOF==fscanf(fin,"%c",&ch))
			{
				line[ll]=0;
				break;
			}
			printf("%c",ch);
			fprintf(fa1,"%c",ch);
			line[ll]=ch;
			ll++;
		}
		printf("\n");
		fprintf(fa1,"\n");
	}
	ch=line[cc];
	cc++;
	return 0;
}



int getsym()
{
	int i,j,k;
	while(ch==' '||ch==10||ch==9)
	{
		getchdo;
	}
	if(ch>='a'&&ch<='z')
	{
		k=0;
		do{
			if(k<al)
			{
				a[k]=ch;
				k++;
			}
			getchdo;
		}while(ch>='a'&&ch<='z'||ch>='0'&&ch<='9');
		a[k]=0;
		strcpy(id,a);
		i=0;
		j=norw-1;
		do{
			k=(i+j)/2;
			if(strcmp(id,word[k])<=0)
			{
				j=k-1;
			}
			if(strcmp(id,word[k])>=0)
			{
				i=k+1;
			}
		}while(i<=j);
		if(i-1>j)
		{
			sym=wsym[k];
		}
		else
		{
			sym=ident;
		}
	}
	else
	{
		if(ch>='0'&&ch<='9')
		{
			k=0;
			num=0;
			sym=number;
			do{
				num=10*num+ch-'0';
				k++;
				getchdo;
			}while(ch>='0'&&ch<='9');
			k--;
			if(k>nmax)
			{
				error(30);
			}
		}
		else
		{
			if(ch==':')
			{
				getchdo;
				if(ch=='=')
				{
					sym=becomes;
					getchdo;
				}
				else
				{
					sym=nul;
				}
			}
			else
			{
				if(ch=='<')
				{
					getchdo;
					if(ch=='=')
					{
						sym=leq;
						getchdo;
					}
					else
					{
						sym=lss;
					}
				}
				else
				{
					if(ch=='>')
					{
						getchdo;
						if(ch=='=')
						{
							sym=geq;
							getchdo;
						}
						else
						{
							sym=gtr;
						}
					}
					else
					{
						sym=ssym[ch];
						if(sym!=period)
						{
							getchdo;
						}
					}
				}
			}
		}
	}
	return 0;
}




int gen(enum fct x,int y,int z)
{
	if(cx>=cxmax)
	{
		printf("Program too long");
		return -1;
	}
	code[cx].f=x;
	code[cx].l=y;
	code[cx].a=z;
	cx++;
	return 0;
}



int test(bool *s1,bool *s2,int n)
{
	if(!inset(sym,s1))
	{
		error(n);
		while((!inset(sym,s1))&&(!inset(sym,s2)))
		{
			getsymdo;
		}
	}
	return 0;
}



int block(int lev,int tx,bool *fsys)
{
	int i;
	int dx;
	int tx0;
	int cx0;
	bool nxtlev[symnum];
	dx=3;
	tx0=tx;
	table[tx].adr=cx;
	gendo(jmp,0,0);
	if(lev>levmax)
	{
		error(32);
	}
	do{
		if(sym==constsym)
		{
			getsymdo;
			do{
				constdeclarationdo(&tx,lev,&dx);
				while(sym==comma)
				{
					getsymdo;
					constdeclarationdo(&tx,lev,&dx);
				}
				if(sym==semicolon)
				{
					getsymdo;
				}
				else
				{
					error(5);
				}
			}while(sym==ident);
		}
		if(sym==varsym)
		{
			getsymdo;
			do{
				vardeclarationdo(&tx,lev,&dx);
				while(sym==comma)
				{
					getsymdo;
					vardeclarationdo(&tx,lev,&dx);
				}
				if(sym==semicolon)
				{
					getsymdo;
				}
				else
				{
					error(5);
				}
			}while(sym==ident);
		}
		while(sym==procsym)
		{
			getsymdo;
			if(sym==ident)
			{
				enter(procedur,&tx,lev,&dx);
				getsymdo;
			}
			else
			{
				error(4);
			}
			if(sym==semicolon)
			{
				getsymdo;
			}
			else
			{
				error(5);
			}
			memcpy(nxtlev,fsys,sizeof(bool)* symnum);
			nxtlev[semicolon]=true;
			if(-1==block(lev+1,tx,nxtlev))
			{
				return -1;
			}
			if(sym==semicolon)
			{
				getsymdo;
				memcpy(nxtlev,statbegsys,sizeof(bool)* symnum);
				nxtlev[ident]=true;
				nxtlev[procsym]=true;
				testdo(nxtlev,fsys,6);
			}
			else
			{
				error(5);
			}
		}
		memcpy(nxtlev,statbegsys,sizeof(bool)* symnum);
		nxtlev[ident]=true;
		nxtlev[period]=true;
		testdo(nxtlev,declbegsys,7);
	}while(inset(sym,declbegsys));
	code[table[tx0].adr].a=cx;
	table[tx0].adr=cx;
	table[tx0].size=dx;

	cx0=cx;
	gendo(inte,0,dx);
	if(tableswitch)
	{
		printf("TABLE:\n");
		if(tx0+1>tx)
		{
			printf("NULL\n");
		}
		for(i=tx0+1;i<=tx;i++)
		{
			switch(table[i].kind)
			{
			case constant:
				printf(" %d const %s ",i,table[i].name);
				printf(" val=%d\n",table[i].val);
				fprintf(fas," %d const %s ",i,table[i].name);
				fprintf(fas," val=%d\n",table[i].val);
				break;
			case variable:
				printf(" %d var %s ",i,table[i].name);
				printf(" lev=%d addr=%d\n",table[i].level,table[i].adr);
				fprintf(fas," %d var %s ",i,table[i].name);
				fprintf(fas," lev=%d addr=%d\n",table[i].level,table[i].adr);
				break;
			case procedur:
				printf(" %d proc %s ",i,table[i].name);
				printf(" lev=%d addr=%d size=%d\n",table[i].level,table[i].adr,table[i].size);
				fprintf(fas," %d proc %s ",i,table[i].name);
				fprintf(fas," lev=%d addr=%d size=%d\n",table[i].level,table[i].adr,table[i].size);
				break;
			}
		}
		printf("\n");
	}
	memcpy(nxtlev,fsys,sizeof(bool)* symnum);
	nxtlev[semicolon]=true;
	nxtlev[endsym]=true;
	statementdo(nxtlev,&tx,lev);
	gendo(opr,0,0);
	memset(nxtlev,0,sizeof(bool)* symnum);
	testdo(fsys,nxtlev,8);
	listcode(cx0);
	return 0;
}




void enter(enum object k,int* ptx,int lev,int* pdx)
{
	(*ptx)++;
	strcpy(table[(*ptx)].name,id);
	table[(*ptx)].kind=k;
	switch(k)
	{
	case constant:
		if(num>amax)
		{
			error(31);
			num=0;
		}
		table[(*ptx)].val=num;
		break;
	case variable:
		table[(*ptx)].level=lev;
		table[(*ptx)].adr=(*pdx);
		(*pdx)++;
		break;
	case procedur:
		table[(*ptx)].level=lev;
		break;
	}
}




int position(char* idt,int tx)
{
	int i;
	strcpy(table[0].name,idt);
	i=tx;
	while(strcmp(table[i].name,idt)!=0)
	{
		i--;
	}
	return i;
}



int constdeclaration(int* ptx,int lev,int* pdx)
{
	if(sym==ident)
	{
		getsymdo;
		if(sym==eql||sym==becomes)
		{
			if(sym==becomes)
			{
				error(1);
			}
			getsymdo;
			if(sym==number)
			{
				enter(constant,ptx,lev,pdx);
				getsymdo;
			}
			else
			{
				error(2);
			}
		}
		else
		{
			error(3);
		}
	}
	else
	{
		error(4);
	}
	return 0;
}




int vardeclaration(int* ptx,int lev,int* pdx)
{
	if(sym==ident)
	{
		enter(variable,ptx,lev,pdx);
		getsymdo;
	}
	else
	{
		error(4);
	}
	return 0;
}




void listcode(int cx0)
{
	int i;
	if(listswitch)
	{
		for(i=cx0;i<cx;i++)
		{
			printf("%d %s %d %d\n",i,mnemonic[code[i].f],code[i].l,code[i].a);
			fprintf(fa,"%d %s %d %d\n",i,mnemonic[code[i].f],code[i].l,code[i].a);
		}
	}
}




int statement(bool* fsys,int* ptx,int lev)
{
	int i,cx1,cx2;
	bool nxtlev[symnum];
	if(sym==ident)
	{
		i=position(id,*ptx);
		if(i==0)
		{
			error(11);
		}
		else
		{
			if(table[i].kind!=variable)
			{
				error(12);
				i=0;
			}
			else
			{
				getsymdo;
				if(sym==becomes)
				{
					getsymdo;
				}
				else
				{
					error(13);
				}
				memcpy(nxtlev,fsys,sizeof(bool)* symnum);
				expressiondo(nxtlev,ptx,lev);
				if(i!=0)
				{
					gendo(sto,lev-table[i].level,table[i].adr);
				}
			}
		}
	}
	else
	{
		if(sym==readsym)
		{
			getsymdo;
			if(sym!=lparen)
			{
				error(34);
			}
			else
			{
				do{
					getsymdo;
					if(sym==ident)
					{
						i=position(id,*ptx);
					}
					else
					{
						i=0;
					}
					if(i==0)
					{
						error(35);
					}
					else
					{
						gendo(opr,0,16);
						gendo(sto,lev-table[i].level,table[i].adr);
					}
					getsymdo;
				}while(sym==comma);
			}
			if(sym!=rparen)
			{
				error(33);
				while(!inset(sym,fsys))
				{
					getsymdo;
				}
			}
			else
			{
				getsymdo;
			}
		}
		else
		{
			if(sym==writesym)
			{
				getsymdo;
				if(sym==lparen)
				{
					do{
						getsymdo;
						memcpy(nxtlev,fsys,sizeof(bool)* symnum);
						nxtlev[rparen]=true;
						nxtlev[comma]=true;
						expressiondo(nxtlev,ptx,lev);

						gendo(opr,0,14);
					}while(sym==comma);
					if(sym!=rparen)
					{
						error(33);
					}
					else
					{
						getsymdo;
					}
				}
				gendo(opr,0,15);
			}
			else
			{
				if(sym==callsym)
				{
					getsymdo;
					if(sym!=ident)
					{
						error(14);
					}
					else
					{
						i=position(id,*ptx);
						if(i==0)
						{
							error(11);
						}
						else
						{
							if(table[i].kind==procedur)
							{
								gendo(cal,lev-table[i].level,table[i].adr);
							}
							else
							{
								error(15);
							}
						}
						getsymdo;
					}
				}
				else
				{
					if(sym==ifsym)
					{
						getsymdo;
						memcpy(nxtlev,fsys,sizeof(bool)* symnum);
						nxtlev[thensym]=true;
						nxtlev[dosym]=true;
						conditiondo(nxtlev,ptx,lev);
						if(sym==thensym)
						{
							getsymdo;
						}
						else
						{
							error(16);
						}
						cx1=cx;
						gendo(jpc,0,0);
						statementdo(fsys,ptx,lev);
						code[cx1].a=cx;
					}
					else
					{
						if(sym==beginsym)
						{
							getsymdo;
							memcpy(nxtlev,fsys,sizeof(bool)* symnum);
							nxtlev[semicolon]=true;
							nxtlev[endsym]=true;

							statementdo(nxtlev,ptx,lev);
							while(inset(sym,statbegsys)||sym==semicolon)
							{
								if(sym==semicolon)
								{
									getsymdo;
								}
								else
								{
									error(10);
								}
								statementdo(nxtlev,ptx,lev);
							}
							if(sym==endsym)
							{
								getsymdo;
							}
							else
							{
								error(17);
							}
						}
						else
						{
							if(sym==whilesym)
							{
								cx1=cx;
								getsymdo;
								memcpy(nxtlev,fsys,sizeof(bool)* symnum);
								nxtlev[dosym]=true;
								conditiondo(nxtlev,ptx,lev);
								cx2=cx;
								gendo(jpc,0,0);
								if(sym==dosym)
								{
									getsymdo;
								}
								else
								{
									error(18);
								}
								statementdo(fsys,ptx,lev);
								gendo(jmp,0,cx1);
								code[cx2].a=cx;
							}
							else
							{
								memset(nxtlev,0,sizeof(bool)* symnum);
								testdo(fsys,nxtlev,19);
							}
						}
					}
				}
			}
		}
	}
	return 0;
}




int expression(bool* fsys,int* ptx,int lev)
{
	enum symbol addop;
	bool nxtlev[symnum];
	if(sym==plus||sym==minus)
	{
		addop=sym;
		getsymdo;
		memcpy(nxtlev,fsys,sizeof(bool)* symnum);
		nxtlev[plus]=true;
		nxtlev[minus]=true;
		termdo(nxtlev,ptx,lev);
		if(addop==minus)
		{
			gendo(opr,0,1);
		}
	}
	else
	{
		memcpy(nxtlev,fsys,sizeof(bool)* symnum);
		nxtlev[plus]=true;
		nxtlev[minus]=true;
		termdo(nxtlev,ptx,lev);
	}
	while(sym==plus||sym==minus)
	{
		addop=sym;
		getsymdo;
		memcpy(nxtlev,fsys,sizeof(bool)* symnum);
		nxtlev[plus]=true;
		nxtlev[minus]=true;
		termdo(nxtlev,ptx,lev);
		if(addop==plus)
		{
			gendo(opr,0,2);
		}
		else
		{
			gendo(opr,0,3);
		}
	}
	return 0;
}




int term(bool* fsys,int* ptx,int lev)
{
	enum symbol mulop;
	bool nxtlev[symnum];
	memcpy(nxtlev,fsys,sizeof(bool)* symnum);
	nxtlev[times]=true;
	nxtlev[slash]=true;
	factordo(nxtlev,ptx,lev);
	while(sym==times||sym==slash)
	{
		mulop=sym;
		getsymdo;
		factordo(nxtlev,ptx,lev);
		if(mulop==times)
		{
			gendo(opr,0,4);
		}
		else
		{
			gendo(opr,0,5);
		}
	}
	return 0;
}




int factor(bool* fsys,int* ptx,int lev)
{
	int i;
	bool nxtlev[symnum];
	testdo(facbegsys,fsys,24);
	while(inset(sym,facbegsys))
	{
		if(sym==ident)
		{
			i=position(id,*ptx);
			if(i==0)
			{
				error(11);
			}
			else
			{
				switch(table[i].kind)
				{
				case constant:
					gendo(lit,0,table[i].val);
					break;
				case variable:
					gendo(lod,lev-table[i].level,table[i].adr);
					break;
				case procedur:
					error(21);
					break;
				}
			}
			getsymdo;
		}
		else
		{
			if(sym==number)
			{
				if(num>amax)
				{
					error(31);
					num=0;
				}
				gendo(lit,0,num);
				getsymdo;
			}
			else
			{
				if(sym==lparen)
				{
					getsymdo;
					memcpy(nxtlev,fsys,sizeof(bool)* symnum);
					nxtlev[rparen]=true;
					expressiondo(nxtlev,ptx,lev);
					if(sym==rparen)
					{
						getsymdo;
					}
					else
					{
						error(22);
					}
				}
				testdo(fsys,facbegsys,23);
			}
		}
	}
	return 0;
}




int condition(bool* fsys,int* ptx,int lev)
{
	enum symbol relop;
	bool nxtlev[symnum];
	if(sym==oddsym)
	{
		getsymdo;
		expressiondo(fsys,ptx,lev);
		gendo(opr,0,6);
	}
	else
	{
		memcpy(nxtlev,fsys,sizeof(bool)* symnum);
		nxtlev[eql]=true;
		nxtlev[neq]=true;
		nxtlev[lss]=true;
		nxtlev[leq]=true;
		nxtlev[gtr]=true;
		nxtlev[geq]=true;
		expressiondo(nxtlev,ptx,lev);
		if(sym!=eql&&sym!=neq&&sym!=lss&&sym!=leq&&sym!=gtr&&sym!=geq)
		{
			error(20);
		}
		else
		{
			relop=sym;
			getsymdo;
			expressiondo(fsys,ptx,lev);
			switch(relop)
			{
			case eql:
				gendo(opr,0,8);
				break;
			case neq:
				gendo(opr,0,9);
				break;
			case lss:
				gendo(opr,0,10);
				break;
			case geq:
				gendo(opr,0,11);
				break;
			case gtr:
				gendo(opr,0,12);
				break;
			case leq:
				gendo(opr,0,13);
				break;
			}
		}
	}
	return 0;
}




void interpret()
{
	int p,b,t;
	struct instruction i;
	int s[stacksize];
	printf("start pl0\n");
	t=0;
	b=0;
	p=0;
	s[0]=s[1]=s[2]=0;
	do{
		i=code[p];
		p++;
		switch(i.f)
		{
		case lit:
			s[t]=i.a;
			t++;
			break;
		case opr:
			switch(i.a)
			{
			case 0:
				t=b;
				p=s[t+2];
				b=s[t+1];
				break;
			case 1:
				s[t-1]=-s[t-1];
				break;
			case 2:
				t--;
				s[t-1]=s[t-1]+s[t];
				break;
			case 3:
				t--;
				s[t-1]=s[t-1]-s[t];
				break;
			case 4:
				t--;
				s[t-1]=s[t-1]*s[t];
				break;
			case 5:
				t--;
				s[t-1]=s[t-1]/s[t];
				break;
			case 6:
				s[t-1]=s[t-1]%2;
				break;
			case 8:
				t--;
				s[t-1]=(s[t-1]==s[t]);
				break;
			case 9:
				t--;
				s[t-1]=(s[t-1]!=s[t]);
				break;
			case 10:
				t--;
				s[t-1]=(s[t-1]<s[t]);
				break;
			case 11:
				t--;
				s[t-1]=(s[t-1]>=s[t]);
				break;
			case 12:
				t--;
				s[t-1]=(s[t-1]>s[t]);
				break;
			case 13:
				t--;
				s[t-1]=(s[t-1]<=s[t]);
				break;
			case 14:
				printf("%d",s[t-1]);
				fprintf(fa2,"%d",s[t-1]);
				t--;
				break;
			case 15:
				printf("\n");
				fprintf(fa2,"\n");
				break;
			case 16:
				printf("?");
				fprintf(fa2,"?");
				scanf("%d",&(s[t]));
				fprintf(fa2,"%d\n",s[t]);
				t++;
				break;
			}
			break;
			case lod:
				s[t]=s[base(i.l,s,b)+i.a];
				t++;
				break;
			case sto:
				t--;
				s[base(i.l,s,b)+i.a]=s[t];
				break;
			case cal:
				s[t]=base(i.l,s,b);
				s[t+1]=b;
				s[t+2]=p;
				b=t;
				p=i.a;
				break;
			case inte:
				t+=i.a;
				break;
			case jmp:
				p=i.a;
				break;
			case jpc:
				t--;
				if(s[t]==0)
				{
					p=i.a;
				}
				break;
		}
	}while(p!=0);
}




int base(int l,int* s,int b)
{
	int b1;
	b1=b;
	while(l>0)
	{
		b1=s[b1];
		l--;
	}
	return b1;
}