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

📄 interpret.cpp

📁 PL语言到中间代码的编译程序
💻 CPP
字号:
#include "common.h"

void Execute(int *code);

int ip=0;
//ip:指令指针

void Interpret(int *code)
{
	while(1)
	{
		//取出指令依次执行
		Execute(&code[ip++*3]);
	}
}

void Execute(int *code)
{
	//解释执行单条指令
	static int sp=3,base=0,old_base=0;
	//sp:栈顶指针   base:栈底指针
	static int stack[STACKSIZE];
	//一个运行栈
	static int display[MAXLEVELS];
	static int level=0;
	int temp;
	char *address;

#ifdef _DEBUG
	char ObjCodeScript[GE+1][50]=
	{
	"LIT	%d , %d		;装入常量",
	"LOD	%d , %d		;装入变量值",
	"ILOD	%d , %d		;间接装入",
	"LODA	%d , %d		;装入变量地址",
	"LODT			;装入栈顶值为地址的内容",
	"LODB	%d , %d		;装入长度为A的块",
	"STO			;将栈顶值存入栈顶次值所指单元",
	"CPYB	%d , %d		;传送长度为A的块",
	"JMP	%d , %d		;无条件跳转",
	"JPC	%d , %d		;栈顶值为0时跳转",
	"READ	%d , %d		;读指令",
	"WRITE	%d , %d		;写指令",
	"CALL	%d , %d		;转子",
	"RETP			;过程返回",
	"UDIS	%d , %d		;调整Display",
	"OPAC			;打开活动记录",
	"ENTP	%d , %d		;进入过程",
	"ENDP			;程序结束",
	"AND",
	"OR",
	"NOT",
	"IMOD",
	"MUS",
	"ADD",
	"SUB",
	"MULT",
	"IDIV",
	"EQ==",
	"NEQ!=",
	"LSS			;<",
	"LEQ			;<=",
	"GTR			;>",
	"GEQ			;>="
	};
	printf("Line num %d\t",ip-1);
	printf(ObjCodeScript[code[0]],code[1],code[2]);
	printf("\tSP=%d\n",sp);
#endif
	switch(code[0])
	{
	case LIT:
		stack[sp++]=code[2];
		break;
	case LOD:
		address=(char *)&stack[display[code[1]-1]]+code[2]+3*sizeof(int);
		stack[sp++]=*(int *)address;
		break;
	case ILOD:
		address=(char *)&stack[display[code[1]-1]]+code[2]+3*sizeof(int);
		stack[sp]=*(int *)address;
		stack[sp]=(*((int *)stack[sp]));
		sp++;
		break;
	case LODA:
		stack[sp++]=((int)((char *)&stack[display[code[1]-1]])+code[2]+3*sizeof(int));
		break;
	case LODT:
		stack[sp-1]=*((int *)stack[sp-1]);
		break;
	case STO:
		*((int *)stack[sp-2])=stack[sp-1];
		sp--;
		break;
	case JMP:
		ip=code[2];
		break;
	case JPC:
		if(!stack[--sp])
			ip=code[2];
		break;
	case RED:
		if(code[2]==0)
		{
			printf("Input : ");
			scanf("%d",&temp);
		}
		else
			getch();
		*((int *)(stack[--sp]))=temp;
		break;
	case WRT:
		temp=*(int *)(stack[--sp]);
		if(code[2]==0)
			printf("%d\n",temp);
		else
			printf("%c",temp);
		break;
	case CAL:
		stack[base+2]=old_base;
		stack[base+1]=display[level-1];
		stack[base]=ip;
		ip=code[2];
		level=code[1];
		break;
	case RETP:
		level--;
		sp=base;
		base=display[level];
		ip=stack[sp];
		break;
	case UDIS:
		int dynamic_link,static_link,i,current_level;
		dynamic_link=stack[display[level+1]+2];
		for(i=0,static_link=stack[dynamic_link+1];static_link;static_link=stack[static_link+1])
			i++;
		current_level=i+1;
		base=display[current_level]=dynamic_link;
		for(i=current_level-1,static_link=stack[dynamic_link+1];i>=0;i--,static_link=stack[static_link+1])
			display[i]=static_link;
		level=current_level;
		break;
	case OPAC:
		old_base=base;
		base=sp;
		sp+=3;
		break;
	case ENTP:
		display[level]=base;
		sp+=code[2]/sizeof(int)+((code[2]%sizeof(int))?1:0);
		break;
	case ENDP:
		exit(0);
	case ANDS:
		stack[sp-2]=stack[sp-2] & stack[sp-1];
		sp--;
		break;
	case ORS:
		stack[sp-2]=stack[sp-2] | stack[sp-1];
		sp--;
		break;
	case NOTS:
		stack[sp-1]=~stack[sp-1];
		break;
	case IMOD:
		stack[sp-2]=stack[sp-2] % stack[sp-1];
		sp--;
		break;
	case MUS:
		stack[sp-1]=-stack[sp-1];
		break;
	case ADD:
		stack[sp-2]=stack[sp-2] + stack[sp-1];
		sp--;
		break;
	case SUB:
		stack[sp-2]=stack[sp-2] - stack[sp-1];
		sp--;
		break;
	case MULT:
		stack[sp-2]=stack[sp-2] * stack[sp-1];
		sp--;
		break;
	case IDIV:
		stack[sp-2]=stack[sp-2] / stack[sp-1];
		sp--;
		break;
	case EQ:
		stack[sp-2]=(stack[sp-2]==stack[sp-1])?1:0;
		sp--;
		break;
	case NE:
		stack[sp-2]=(stack[sp-2]!=stack[sp-1])?1:0;
		sp--;
		break;
	case LS:
		stack[sp-2]=(stack[sp-2]<stack[sp-1])?1:0;
		sp--;
		break;
	case LE:
		stack[sp-2]=(stack[sp-2]<=stack[sp-1])?1:0;
		sp--;
		break;	
	case GT:
		stack[sp-2]=(stack[sp-2]>stack[sp-1])?1:0;
		sp--;
		break;	
	case GE:
		stack[sp-2]=(stack[sp-2]>=stack[sp-1])?1:0;
		sp--;
		break;	
	default:
		;
	}
}

⌨️ 快捷键说明

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