📄 code.cpp
字号:
// code.cpp: implementation of the code class.
//////////////////////////////////////////////////////////////////////
#include "code.h"
void Ccode::Gen(enum fct x,int y,int z)
{
if (cx>CODE_SIZE) {
printf("error:program too long");
}
if (cx<CODE_SIZE)
{
code[cx].f=x;
code[cx].l=y;
code[cx].a=z;
cx++;
}
}
int Ccode::base(int l)
{
int b1;
b1=b;
while (l>0)
{
b1=s[b1];
l--;
}
return b1;
}
//解析code中的p-code代码并执行
void Ccode::Interpret()
{
int p,t;
fct f;
int l,a;
t=0; //p-code机的数据堆栈区
b=1; //p-code机的栈顶寄存器
p=0; //p-code机的基址寄存器
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)
{
case lit: //如果是lit指令
s[++t]=a; //把常量值放到运行栈栈顶
break;
case opr: //如果是opr指令
switch (a)
{
case 0: //0号操作为从子过程返回操作
t=b-1; //释放这段子过程占用的数据内存空间
p=s[t+3]; //把指令指针取到RA的值,指向的是返回地址
b=s[t+2]; //把数据段基址取到DL的值,指向调用前子过程的数据段基址
break;
case 1: //1号操作为栈顶数据取反
s[t]=-s[t];
break;
case 2: t--; //2号操作为栈顶两个数据加法
s[t]=s[t]+s[t+1];
break;
case 3: t--; //3号操作为栈顶两个数据减法
s[t]=s[t]-s[t+1];
break;
case 4: t--; //4号操作为栈顶两个数据乘法
s[t]=s[t]*s[t+1];
break;
case 5: t--; //5号操作为栈顶两个数据除法
s[t]=s[t]/s[t+1];
break;
case 6: //6号操作为判奇偶
s[t]=s[t]%2;
break;
case 8: t--; //8号操作为栈顶两个数据判等
s[t]=(s[t]==s[t+1]);
break;
case 9: t--; //9号操作为栈顶两个数据判不等
s[t]=(s[t]!=s[t+1]);
break;
case 10: t--; //10号操作为栈顶两个数据判小于
s[t]=(s[t]<s[t+1]);
break;
case 11: t--; //11号操作为栈顶两个数据判大于等于
s[t]=(s[t]>=s[t+1]);
break;
case 12: t--; //12号操作为栈顶两个数据判大于
s[t]=(s[t]>s[t+1]);
break;
case 13: t--; //13号操作为栈顶两个数据判小于等于
s[t]=(s[t]<=s[t+1]);
break;
case 14: //14号操作为输出栈顶值
printf("%d\t",s[t]);
break;
case 15: //15号操作为输出换行
printf("\n");
break;
case 16: //16号操作为接受键盘值输入到栈顶
t++;
printf("?");
scanf("%d",&s[t]);
break;
}
break;
case lod: //如果是lod指令:将变量放到栈顶
t++; //栈顶上移,开辟空间
s[t]=s[base(l)+a]; //通过数据区层差l和偏移地址a找到变量的数据,存入栈顶
break;
case sto: //如果是sto指令
s[base(l)+a]=s[t]; //把栈顶的值存入位置在数据区层差l偏移地址a的变量内存
t--; //栈项下移,释放空间
break;
case cal: //如果是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 intint: //如果是int指令
t+=a; //栈顶上移a个空间,即开辟a个新的内存单元
break;
case jmp: //如果是jmp指令
p=a; //把jmp指令操作数a的值作为下一次要执行的指令地址,实现无条件跳转
break;
case jpc: //如果是jpc指令
if (s[t]==0) //判断栈顶值
p=a; //如果是0就跳转,否则不跳转
t--; //释放栈顶空间
break;
}
}while (p!=0);
}
void Ccode::ListCode()
{
for (int i=0;i<cx;i++)
{
printf("%d\t",i);
switch (code[i].f)
{
case lit:printf("lit\t");break;
case lod:printf("lod\t");break;
case sto:printf("sto\t");break;
case cal:printf("cal\t");break;
case intint:printf("int\t");break;
case jmp:printf("jmp\t");break;
case jpc:printf("jpc\t");break;
case opr:printf("opr\t");break;
}
printf("%d\t%d\n",code[i].l,code[i].a);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -