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

📄 code.cpp

📁 PL/0编译器
💻 CPP
字号:
#include "StdAfx.h"
#include ".\code.h"
#include <iostream>
#include <stdio.h>
#include <string.h>

using namespace std;

CCode::CCode(CPl0*p)
{
	cx = 0;
	pl=p;
}

/*目标代码生成过程gen 
  参数:x:要生成的一行代码的助记符 
  y, z:代码的两个操作数 
  本过程用于把生成的目标代码写入目标代码数组,供后面的解释器解释执行 */
void CCode::Gen(enum fct x,int y,int z)
{
	if (cx<CODE_SIZE)				//如果cx>cxmax表示当前生成的代码行号大于允许的最大代码行数
	{
		code[cx].f=x;
		code[cx].l=y;
		code[cx].a=z;
		cx++;						//移动cx指针指向下一个空位
	}
}

/* 通过静态链求出数据区基地址的函数base
   参数说明:l:要求的数据区所在层与当前层的层差
   返回值:要求的数据区基址 */
int CCode::base(int l)
{
	int b1;
	b1=b;							//首先从当前层开始
	while (l>0)
	{
		b1=s[b1];					//用当前层数据区基址中的内容(正好是静态链SL数据,为上一层的基址)
									//的作为新的当前层,即向上找了一层
		l--;						//向上了一层,l减一
	}
	return b1;						//把找到的要求的数据区基址返回
}

void CCode::Interpret()
{
	int p,t;
	fct f;
	int l,a;

	t=0;b=1;p=0;					//程序开始运行时栈顶寄存器置0,数据段基址为1,从0号代码开始执行程序
	s[1]=0;s[2]=0;s[3]=0;			//数据内存中为SL,DL,RA三个单元均为0,标识为主程序 
	do{
		f=code[p].f;l=code[p].l;a=code[p].a;	// 获取一行目标代码
		p++;						//指令指针加一,指向下一条代码
		switch (f)					//如果i的f,即指令助记符是下面的某种情况,执行不同的功能
		{
		case lit:
			s[++t]=a;				//栈顶指针上移,在栈中分配了一个单元
			break;					//该单元的内容存放i指令的a操作数,即实现了把常量值放到运行栈栈顶 
		case opr:
			switch (a)
			{
			case 0:
				t=b-1;				//释放这段子过程占用的数据内存空间
				p=s[t+3];			//把指令指针取到RA的值,指向的是返回地址
				b=s[t+2];			//把数据段基址取到DL的值,指向调用前子过程的数据段基址
				break;
			case 1:
				s[t]=-s[t];			//对栈顶数据进行取反
				break;
			case 2:	
				t--;
				s[t]=s[t]+s[t+1];	//把两单元数据相加存入栈顶
				break;
			case 3:	
				t--;
				s[t]=s[t]-s[t+1];	//把两单元数据相减存入栈顶
				break;
			case 4:	t--;
				s[t]=s[t]*s[t+1];	//把两单元数据相乘存入栈顶
				break;
			case 5:	
				t--;
				s[t]=s[t]/s[t+1];	//把两单元数据相整除存入栈顶
				break;
			case 6:
				s[t]=s[t]%2;		//数据栈顶的值是奇数则把栈顶值置1,否则置0
				break;
			case 8:	
				t--;
				s[t]=(s[t]==s[t+1]);//判等,相等栈顶置1,不等置0 
				break;
			case 9:	
				t--;
				s[t]=(s[t]!=s[t+1]);//判不等,不等栈顶置1,相等置0
				break;
			case 10: 
				t--;
				s[t]=(s[t]<s[t+1]); //判小于,如果下面的值小于上面的值,栈顶置1,否则置0
				break;
			case 11: 
				t--;
				s[t]=(s[t]>=s[t+1]);//判大于等于,如果下面的值大于等于上面的值,栈顶置1,否则置0
				break;
			case 12: 
				t--;
				s[t]=(s[t]>s[t+1]); //判大于,如果下面的值大于上面的值,栈顶置1,否则置0
				break;
			case 13: 
				t--;
				s[t]=(s[t]<=s[t+1]);//判小于等于,如果下面的值小于等于上面的值,栈顶置1,否则置0
				break;
			case 14:
				cout<<s[t]<<"\t";	//输出栈顶值
				break;
			case 15:
				cout<<"\n";			//输出换行
				break;
			case 16:
				t++;
				cout<<"?";
				cin>>s[t];			//16号操作是接受键盘值输入到栈顶
				break;
			}
			break;
		case lod:					//如果是lod指令:将变量放到栈顶
			t++;					//栈顶上移,开辟空间
			s[t]=s[base(l)+a];		//通过数据区层差l和偏移地址a找到变量的数据,存入上面开辟的新空间(即栈顶)
			break;
		case sto:
			s[base(l)+a]=s[t];		//把栈顶的值存入位置在数据区层差l偏移地址a的变量内存
			t--;					//栈项下移,释放空间
			break;
		case cal:
			//过程调用前的保护现场
			s[t+1]=base(l);			//在栈顶压入静态链SL
			s[t+2]=b;				//然后压入当前数据区基址,作为动态链DL
			s[t+3]=p;				//最后压入当前的断点,作为返回地址RA
			b=t+1;					//把当前数据区基址指向SL所在位置
			p=a;					//从a所指位置开始继续执行指令,即实现了程序执行的跳转
			break;
		case tint:
			t+=a;					//栈顶上移a个空间,即开辟a个新的内存单元
			break;
		case jmp:
			p=a;					//把jmp指令操作数a的值作为下一次要执行的指令地址,实现无条件跳转
			break;
		case jpc:
			if (s[t]==0)			//判断栈顶值
				p=a;				//如果是0就跳转,否则不跳转
			t--;					//释放栈顶空间
			break;
		}
	}while (p!=0);
}

//逐行输出代码
void CCode::ListCode()
{
	FILE *fp;
	//int i;
	char c[1];
	char *filename = pl->flnm;

	strcat(filename,".txt");

	if((fp=fopen(filename,"wb"))==NULL)
	{
		printf("cant open the file");
		exit(0);
	}

	for (int i=0;i<cx;i++)
	{
		cout<<i<<"  ";
		switch (code[i].f)
		{
		case lit:
			cout<<"lit\t";
			fwrite("lit  ",sizeof(char),strlen("lit  "),fp);
			break;
		case lod:
			cout<<"lod\t";
			fwrite("lod  ",sizeof(char),strlen("lod  "),fp);
			break;
		case sto:
			cout<<"sto\t";
			fwrite("sto  ",sizeof(char),strlen("sto  "),fp);
			break;
		case cal:
			cout<<"cal\t";
			fwrite("cal  ",sizeof(char),strlen("cal  "),fp);
			break;
		case tint:
			cout<<"int\t";
			fwrite("int  ",sizeof(char),strlen("int  "),fp);
			break;
		case jmp:
			cout<<"jmp\t";
			fwrite("jmp  ",sizeof(char),strlen("jmp  "),fp);
			break;
		case jpc:
			cout<<"jpc\t";
			fwrite("jpc  ",sizeof(char),strlen("jpc  "),fp);
			break;
		case opr:
			cout<<"opr\t";
			fwrite("opr  ",sizeof(char),strlen("opr  "),fp);
			break;
		}
		cout<<code[i].l<<"\t"<<code[i].a<<endl;
		c[0] = static_cast<char>('0'+ code[i].l);
		fwrite(c,sizeof(char),1,fp);
		fwrite("  ",sizeof(char),strlen("  "),fp);
		if(code[i].a >= 10)
		{
			c[0] = static_cast<char>('0'+ code[i].a / 10);
			fwrite(c,sizeof(char),1,fp);
		}
		c[0] = static_cast<char>('0'+ code[i].a%10);
		fwrite(c,sizeof(char),1,fp);
		fwrite("\t\t",sizeof(char),strlen("\t\t"),fp);
	}
}

CCode::~CCode(void)
{
}

⌨️ 快捷键说明

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