⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pl0run.cpp

📁 PL/0语言编译器
💻 CPP
字号:
///////////////////////////////////////////////////////////////
//	PL/0 ASM Interpreter 0.1 (2003.12.27) [Source File]
//	Author:Dwing
///////////////////////////////////////////////////////////////
#include<stdio.h>	//For <printf> ...
#include<string.h>	//For <strcmp>
///////////////////////////////////////////////////////////////
typedef struct		//汇编指令格式
{
	char			opr;	//指令操作码
	char			lvl;	//级数
	unsigned short	adr;	//地址码/操作数
}ASM;
enum{OP_LIT,OP_LOD,OP_STO,OP_CAL,OP_INT,OP_JMP,OP_JPC,OP_OPR};
enum{
	OPR_RET,OPR_NEG,OPR_ADD,OPR_SUB,OPR_MUL,OPR_DIV,
	OPR_ODD,OPR_NUL,OPR_EQL,OPR_NE ,OPR_LT ,OPR_LGE,
	OPR_LG ,OPR_LTE,OPR_WRT,OPR_WRN,OPR_RED
};
///////////////////////////////////////////////////////////////
int getbase(short *s,int base,int lvl)	//取基址
{
	while(lvl--) base=s[base];
	return base;
}
///////////////////////////////////////////////////////////////
int _main()	//Program Entry
{
	int i,num;
	char b[4];
	ASM a[16384];
	FILE *fp;
	fp=fopen("temp.pl0","rb");
	if(!fp)
	{
		printf("PL/0 ASM Interpreter 0.1\n");
		printf("Can't open \"temp.pl0\"!\n");
		return 0;
	}
	fscanf(fp,"%u",&num);
	for(i=0;i<num;i++)
	{
		fscanf(fp,"%*4u:%s%u%u",b,&a[i].lvl,&a[i].adr);
		if(!strcmp(b,"LIT")) a[i].opr=OP_LIT;
		if(!strcmp(b,"LOD")) a[i].opr=OP_LOD;
		if(!strcmp(b,"STO")) a[i].opr=OP_STO;
		if(!strcmp(b,"CAL")) a[i].opr=OP_CAL;
		if(!strcmp(b,"INT")) a[i].opr=OP_INT;
		if(!strcmp(b,"JMP")) a[i].opr=OP_JMP;
		if(!strcmp(b,"JPC")) a[i].opr=OP_JPC;
		if(!strcmp(b,"OPR")) a[i].opr=OP_OPR;
	}
	fclose(fp);

	short s[16384]={0},bp=0,sp=3,ip=0;
	do{
		switch(a[ip].opr)
		{
		case OP_INT:sp+=a[ip].adr;								break;
		case OP_LIT:s[++sp]=a[ip].adr;							break;
		case OP_LOD:s[++sp]=s[getbase(s,bp,a[ip].lvl)+a[ip].adr];break;
		case OP_STO:s[getbase(s,bp,a[ip].lvl)+a[ip].adr]=s[sp--];break;
		case OP_JMP:ip=a[ip].adr-1;								break;
		case OP_JPC:if(!s[sp--]) ip=a[ip].adr-1;				break;
		case OP_CAL:
			s[sp++]=getbase(s,bp,a[ip].lvl);//静态链
			s[sp++]=bp;						//动态链
			s[sp++]=ip+1;						//返回地址
			bp=sp-3;
			ip=a[ip].adr-1;
			break;
		case OP_OPR:
			switch(a[ip].adr)
			{
	//过程返回
			case OPR_RET:sp=bp; ip=s[bp+2]-1; bp=s[bp+1]; break;
	//栈顶元素取负数
			case OPR_NEG:s[sp]=-s[sp];break;
	//次栈顶和栈顶相加,结果为栈顶
			case OPR_ADD:sp--;s[sp]=s[sp]+s[sp+1];break;
	//次栈顶和栈顶相减,结果为栈顶
			case OPR_SUB:sp--;s[sp]=s[sp]-s[sp+1];break;
	//次栈顶和栈顶相乘,结果为栈顶
			case OPR_MUL:sp--;s[sp]=s[sp]*s[sp+1];break;
	//次栈顶和栈顶相除,结果为栈顶
			case OPR_DIV:sp--;s[sp]=s[sp]/s[sp+1];break;
	//栈顶是否为奇数,结果入栈(0或1)
			case OPR_ODD:s[sp]=s[sp]&1;break;
	//次栈顶和栈顶是否相等,结果入栈(0或1)
			case OPR_EQL:sp--;s[sp]=(s[sp]==s[sp+1]);break;
	//次栈顶和栈顶是否不等,结果入栈(0或1)
			case OPR_NE: sp--;s[sp]=(s[sp]!=s[sp+1]);break;
	//次栈顶是否比栈顶小,结果入栈(0或1)
			case OPR_LT: sp--;s[sp]=(s[sp]<s[sp+1]);break;
	//是否次栈顶大于等于栈顶,结果入栈(0或1)
			case OPR_LGE:sp--;s[sp]=(s[sp]>=s[sp+1]);break;
	//是否次栈顶大于栈顶,结果入栈(0或1)
			case OPR_LG: sp--;s[sp]=(s[sp]>s[sp+1]);break;
	//是否次栈顶小于等于栈顶,结果入栈(0或1)
			case OPR_LTE:sp--;s[sp]=(s[sp]<=s[sp+1]);break;
	//打印栈顶元素
			case OPR_WRT:printf("%u",s[sp--]);break;
	//打印回车
			case OPR_WRN:putchar('\n');break;
	//从键盘读取数
			case OPR_RED:putchar('?');scanf("%u%*c",&s[++sp]);break;	 
			}
		}
		ip++; //得到下条指令 
	}while(ip);
	printf("\nProgram terminated!\nPress ENTER to return...");
	getchar();
	return 0;
}
///////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -