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

📄 main.cpp

📁 一个类c语言的解释器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <stack>
#include <cstdlib>
using namespace std;

//运行时数据栈的每一项的类型
//type为该项的类型,value为该项的值
//type=0时为int
//type=1时为real
typedef struct st 
{
	int type;
	union v{
		int ivalue;
		float fvalue;
	} value;
} data_type;

//运行时的代码栈
vector<string>* codeStack;
//运行时的数据栈
vector<data_type>* dataStack;
//保存下一条代码的地址
//初始化为0表示从第一条开始执行
int eip=0;
//保存数据栈中当前函数记录的第一项地址
int sp=0;
//保存初始化全局变量代码的长度
int init_length = 0;

//执行一条中间代码
void execute(){
	//读取将要执行的一条中间代码
	string code = codeStack->at(eip+init_length);
	//查找第一个空格
	int i = code.find_first_of(' ');
	//查找操作符
	//如果没有找到空格,则为一元操作符
	if (i==string::npos)
	{
		//操作符为RET
		//函数调用返回
		if (code=="RET")
		{
			//保存函数的返回值
			data_type d = dataStack->at(dataStack->size()-1);
			dataStack->pop_back();
			int top = dataStack->size()-1;
			//弹出局部变量和参数
			while(sp<top-1){
				dataStack->pop_back();
				top--;
			}
			//恢复eip
			eip = dataStack->at(dataStack->size()-1).value.ivalue;
			dataStack->pop_back();
			//恢复SP
			sp = dataStack->at(dataStack->size()-1).value.ivalue;
			dataStack->pop_back();
			//把函数的返回值压到数据栈中
			dataStack->push_back(d);
		}
		//操作符为OUT
		//输出语句
		else if (code=="OUT")
		{
			//获取将要输出的值
			data_type d = dataStack->at(dataStack->size()-1);
			//判断输出值的类型
			//如果为int型
			if (d.type==0)
			{
				//输出int型的值
				cout<<d.value.ivalue<<endl;
			}
			//如果是real型
			else{
				//输出real型的值
				cout<<d.value.fvalue<<endl;
			}
			//弹出输出的数
			dataStack->pop_back();
			//调整eip,使之指向下一句执行代码的地址
			eip++;
		}
		//操作符为POP
		//弹出数据栈顶的值
		else if (code=="POP")
		{
			//弹出数据栈顶
			dataStack->pop_back();
			//调整eip,使之指向下一句执行代码的地址
			eip++;
		}
		//操作符为NEG
		//对栈顶值取反
		else if (code=="NEG")
		{
			//获取栈顶的值
			data_type d = dataStack->at(dataStack->size()-1);
			//如果类型为int,则对int value取反 
			if(d.type==0){
				d.value.ivalue = -d.value.ivalue;
			}
			//如果为real型,则对real value取反
			else{
				d.value.fvalue = -d.value.fvalue;
			}
			//弹出原来的值
			dataStack->pop_back();
			//把取反后的值压入数据栈中
			dataStack->push_back(d);
			//调整eip,使之指向下一句执行代码的地址
			eip++;
		}
		//操作符为EXIT
		//退出
		else if (code=="EXIT")
		{
			//暂停
			system("pause");
			//退出
			exit(0);
		}
	}
	//操作符为2元或者三元
	else{
		//获取操作符
		string temp = code.substr(0,i);
		//操作符为LOD
		//把指定地址的值存到栈顶
		if (temp=="LOD")
		{
			//获取地址
			string s = code.substr(i+1,code.size()-i);
			//设置初始地址为0
			int address = 0;
			//看地址中是否有+
			int i = s.find_first_of('+');
			//地址中有+
			if (i!=string::npos)
			{
				//地址为SP+偏移
				//局部变量
				if(s.at(0)=='S'){
					//设置地址为sp
					address+=sp;
					//查找是否还有+
					int k = s.find_first_of('+',i+1);
					//还有+
					//地址为SP+偏移+[TOP]类型
					//数组赋值
					if (k!=string::npos)
					{
						//地址+数组下标的偏移
						//栈顶值为数组下标
						address+=dataStack->at(dataStack->size()-1).value.ivalue;
						dataStack->pop_back();
						//局部变量的偏移
						address+=atoi(s.substr(i+1,k-i-1).c_str());
					}
					//没有+ 地址为 SP+偏移 类型
					else{
						//局部变量的偏移
						address+=atoi(s.substr(i+1,s.size()-i-1).c_str());
					}
				}
				//全局数组变量
				else{
					//地址+数组下标的偏移
					//栈顶值为数组下标
					address+=dataStack->at(dataStack->size()-1).value.ivalue;
					dataStack->pop_back();
					//地址
					address+=atoi(s.substr(0,i).c_str());
				}
			}
			//地址中没有+
			else{
				//地址就是一个数字,直接转换
				address = atoi(s.c_str());
			}
			//获取要保存地址的类型
			int type = dataStack->at(address).type;
			//
			data_type d;
			d.type = type;
			//把该地址的值保存在栈顶
			if (type==0)
			{
				d.value.ivalue = (dataStack->at(address)).value.ivalue;
			}
			else{
				d.value.fvalue = (dataStack->at(address)).value.fvalue;
			}
			dataStack->push_back(d);
			//调整eip,使之指向下一句执行代码的地址
			eip++;
		}
		//把栈顶的值保存在指定的地址中
		else if (temp == "STO")
		{
			//获取要保存的值
			data_type d = dataStack->at(dataStack->size()-1);
			dataStack->pop_back();
			//获取地址
			string s = code.substr(i+1,code.size()-i);
			//设置初始的地址为0
			int address = 0;
			//查找是否有+
			int i = s.find_first_of('+');
			//如果有+
			if (i!=string::npos)
			{
				//如果是S开头的,是SP+偏移类型
				if(s.at(0)=='S'){

					address+=sp;
					//如果还有+
					int k = s.find_first_of('+',i+1);
					//类型为SP+偏移+[TOP]
					//把栈顶值保存在数组的一个项中
					if (k!=string::npos)
					{
						//数组的下标
						address+=dataStack->at(dataStack->size()-1).value.ivalue;
						dataStack->pop_back();
						address+=atoi(s.substr(i+1,k-i-1).c_str());
					}
					//sp+偏移 类型
					else{
						address+=atoi(s.substr(i+1,s.size()-i-1).c_str());
					}
				}
				//全局数组赋值
				else{
					//栈顶值为数组下标
					address+=dataStack->at(dataStack->size()-1).value.ivalue;
					dataStack->pop_back();
					address+=atoi(s.substr(0,i).c_str());
				}
			}
			//全局变量,非数组
			else{
				address = atoi(s.c_str());
			}
			//获取要保存的类型
			int type = dataStack->at(address).type;
			//要保存的位置的类型为int,只能保存int
			if (type==0)
			{
				(dataStack->at(address)).value.ivalue = d.value.ivalue;
			}
			//要保存的位置类型为real
			else{
				//栈顶值为real型
				if(d.type==1)
					(dataStack->at(address)).value.fvalue = d.value.fvalue;
				//栈顶值为int
				else
					(dataStack->at(address)).value.fvalue = d.value.ivalue;
			}
			//dataStack->pop_back();
			eip++;
		}
		//定义int变量
		else if (temp=="INT")
		{
			int count = atoi(code.substr(i+1,code.size()-i).c_str());
			for (int k=0;k<count;k++)
			{
				data_type d;
				d.type=0;
				dataStack->push_back(d);
			}
			eip++;
		}
		//定义real型变量
		else if (temp=="REAL")
		{
			int count = atoi(code.substr(i+1,code.size()-i).c_str());
			for (int k=0;k<count;k++)
			{
				data_type d;
				d.type=1;
				dataStack->push_back(d);
			}
			eip++;
		}
		//无条件跳转
		else if (temp=="JMP")
		{
			int address = atoi(code.substr(i+1,code.size()-i).c_str());
			eip=address;
			//dataStack->pop_back();
		}
		//条件跳转
		else if (temp=="JPC")
		{
			int address = atoi(code.substr(i+1,code.size()-i).c_str());
			int type = (dataStack->at(dataStack->size()-1)).type;
			if(type==0){
				if ((dataStack->at(dataStack->size()-1)).value.ivalue==0)
				{
					eip=address;
				}
				else{
					eip++;
				}
			}
			if(type==1){
				if ((dataStack->at(dataStack->size()-1)).value.fvalue==0)
				{
					eip=address;
				}
				else{
					eip++;
				}
			}
			dataStack->pop_back();
		}
		//函数调用
		else if (temp=="CALL")
		{
			int address=atoi(code.substr(i,code.size()-i).c_str());
			stack<data_type> args;
			//获取参数个数
			int arg_count = dataStack->at(dataStack->size()-1).value.ivalue;
			dataStack->pop_back();
			//保存参数
			for(int  index = 0;index<arg_count;index++){
				args.push(dataStack->at(dataStack->size()-1));
				dataStack->pop_back();
			}
			//保存SP
			data_type d_sp;
			d_sp.value.ivalue = sp;
			d_sp.type = 0;
			dataStack->push_back(d_sp);
			sp = dataStack->size()-1;
			//保存eip

⌨️ 快捷键说明

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