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

📄 executable.cpp

📁 Basic语言解释器.zip
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Executable.cpp: implementation of the CExecutable class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Executable.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////


CExecutable::CExecutable(vector <CSub> Subs)
{
	m_Subs=Subs;
}

CExecutable::~CExecutable()
{
	m_intArray.clear();
	m_tokens.clear();
	m_Subs.clear();
}

void CExecutable::Run(char *SubName,vector <CToken> Subarg)
{
	register int i;
	if(!Ai_GetSubNo(SubName,&i))
		return;
	// m_tokens=m_Subs.at(i).m_tokens;  先处理参数,再将找到的过程Sub里的tokens赋给CExecutable里的m_tokens
	m_argtokens=m_Subs.at(i).m_argtokens;
	// 先将参数定义argtoken装在m_token里当代码运行,然后在将Sub里m_token传到m_token
	if(m_argtokens.size()>=1) // 如果此过程有参数
	{
		m_tokens=m_argtokens;
		for(int l=0;l<=m_tokens.size()-1;l++)
		{
			if(m_tokens.at(l).token_type==COMMAND) // 如果是Basic命令
			{
				switch(m_tokens.at(l).tok) // tok表示是什么命令
				{
				case DIM:  Run_Dim(&l);
					break;
				default:   break; 
				}
				continue;
			}
		}
	}
	// 传递参数 参数值在CToken::token里,类型在CToken::tok里
	if(Subarg.size()>=1)
	{
		// 对应Subarg里的由小到大地直接赋到m_iniArray 或 变量堆栈 里
		int var_int_i=0; // 参数对应在m_intArray里的指针
		for(int l=0;l<=Subarg.size()-1;l++)
			switch(Subarg.at(l).tok)
		{
		   case INTEGER:
			   memcpy(&m_intArray.at(var_int_i).value,Subarg.at(l).token,sizeof(int));
			   var_int_i++;
			   break;
		   default: break;
		}
	}
	
	
	if(strcmp(m_Subs.at(i).name,SubName)==0)
		m_tokens=m_Subs.at(i).m_tokens;
	if(m_tokens.size()<=0)  // 如果找不到SubName的过程或过程中的token没有
		return;
	
	for(i=0;i<=m_tokens.size()-1;i++)// 注意:i是个十分重要的读取指针
	{
		//Debug(i);
		//////////////// COMMAND ////////////////////////////////
		if(m_tokens.at(i).token_type==COMMAND) // 如果是Basic命令
		{
			switch(m_tokens.at(i).tok) // tok表示是什么命令
			{
			case PRINT: Run_Print(&i);
				break;
			case DIM:   Run_Dim(&i);
				break;
			case IF:    Run_If(&i);
				break;
			case WHILE: Run_While(&i);
				break;
			case LOOP:  Run_Loop(&i);
				break;
			case EXIT:  Run_Exit(&i);
				break;
			case CALL:  Run_CallSub(&i);
			default:   break; 
			}
			continue;
		}
		
		//////////////////// Call Sub ////////////////////////////////
		if(m_tokens.at(i).token_type==STRING &&
			*m_tokens.at(i+1).token!='=') // 如果是未知String而且不是赋值语句,则当自定义的过程处理
		{
			Run_CallSub(&i);
			continue;
		}
		
		//////////////////// Assignment赋值语句 ///////////////////////
		//赋值语句一定要在最后来判断,因为这样如果是if后的条件判断就可以在
		//前面的if命令中跳过
		if(*m_tokens.at(i).token=='=') // 如果是赋值语句
			Run_Assignment(&i);
	}
}

void CExecutable::Run_If(int *index) // 条件判断 Run_While Run_If中都要用到它
{
	if(*index>=m_tokens.size()-1)
		return;
	if(m_tokens.at(*index-1).tok==END) // 避免是End If 中的If
		return;
	(*index)++;
	int result;
	if(!Ai_GetNextIfValue(&result,index)) // 判断下个条件语句的真假
	{
		serror(0);
		return;
	}
	(*index)++;
	int thenIndex=*index;
	int endifIndex=*index;
	if(!Ai_GetNextThen(&thenIndex,index))
	{
		serror(8);
		return;
	}
	if(!Ai_GetNextEndIf(&endifIndex,index))
	{
		serror(0);
		return;
	}
	if(result)  // 为真
		*index=thenIndex;
	else        // 为假
		*index=endifIndex;
	return;
}

void CExecutable::Run_While(int *index) //此时index都是指到While语句的
{
	if(*index>=m_tokens.size()-1) 
		return;
	int lastcommand=*index-1; // lastcommand是指到While前面一个Command
	while(m_tokens.at(lastcommand).token_type==ENTER)
		lastcommand--;
	if(m_tokens.at(lastcommand).tok==DO) // 如果是:  Do While [command] 形式
	{
		int loopindex,ifresult;
		(*index)++; // -> While 下一个token
		if(!Ai_GetNextLoop(&loopindex,index)) // 找到匹配的Loop语举引索
			return;
		if(!Ai_GetNextIfValue(&ifresult,index)) // 得到循环调件的真假
		{
			serror(0);
			return;
		}
		
		if(ifresult)
		{
			return;
		}
		else
		{
			*index=loopindex;
			return;
		}
	}
	else
		serror(14);
	
}

void CExecutable::Run_Loop(int *index)
{
	if(*index<m_tokens.size()-1)   
	{
		int nextcommand=(*index)+1;
		while(m_tokens.at(nextcommand).token_type==ENTER) // 跳过换行符
		{
			if(nextcommand<m_tokens.size()-1) // 如果下面一个nextcommand未出界
				nextcommand++;
			else // 如果这个token就是下界线了
				 break; /* 此时的token_type肯定是ENTER 所以下面将跳到
			Do While [command] Loop 中的Loop形式的处理中*/
		}
		
		// 如果是这种循环: Do [command] Loop While [command]
		if(m_tokens.at(nextcommand).tok==WHILE)
		{
			(*index)--;    // -> Do 前一个token
			int lastDo,ifresult;
			if(!Ai_GetLastDo(&lastDo,index)) // 找到匹配的Do语举引索
				return;
			(*index)=nextcommand+1;  // -> While后一个
			
			if(!Ai_GetNextIfValue(&ifresult,index)) // 得到循环调件的真假
			{
				serror(0);
				return;
			}
			if(ifresult)
			{
				*index=lastDo;
				return;				
			}
			else
			{
				return;
			}
			return;
		}
	}
	
	// 否则就是Do While [command] Loop 中的Loop形式
	int lastDo;
	(*index)--; // -> Do 前一个
	if(!Ai_GetLastDo(&lastDo,index))
		return;
	*index=lastDo;
	return;
}

void CExecutable::Run_Exit(int *index)
{
	if(*index>=m_tokens.size()-1) //如果超出范围
		return;
	(*index)++;
    switch(m_tokens.at(*index).tok)
	{
	case DO:
		{
			int loopindex;
			(*index)++;
			if(!Ai_GetNextLoop(&loopindex,index))
			{
				serror(15);
				return;
			}
			int nextcommand=loopindex+1;
			while(m_tokens.at(nextcommand).token_type==ENTER)
				nextcommand++;
			if(m_tokens.at(nextcommand).tok==WHILE) // Loop 后面的Command是While
			{
				*(index)=nextcommand+1;
				Ai_GetNextIfValue(&nextcommand,index);
				// 让index移到条件判断式最后一个token
				return;
			}
			*index=nextcommand-1;
			return;
		}
	default: break;
	}
}

void CExecutable::Run_Print(int *index) //*index是m_tokens里的指针
{
	if(*index<m_tokens.size()-1) // 如果下面还有token
	{   
		if(m_tokens.at((*index)+1).token_type==ENTER) //如果接下来是换行符
		{
			printf("\n");
			return;
		}
		(*index)++;			
		int token_type=m_tokens.at(*index).token_type;
		if(Isvar(m_tokens.at(*index).token)) //如果接下来是变量
			token_type=VARIABLE; 
        
		switch(token_type)
		{
		case QUOTE: // 如果是要打印字符串
			{
				printf(m_tokens.at(*index).token);
				return;
			}
		case VARIABLE:  // 打印代数式 type只要不是COMMAND就是可以当代数式处理
		case NUMBER:
		case DELIMITER:     
			{
				int result;
				Ai_GetNextValue(&result,INTEGER,index);
				printf("%d",result);
				return;
			}
		default: printf("\n");
			return;
		}
	}
	printf("\n");	
	
}

void CExecutable::Run_Dim(int *index) //~~
{
	int i=*index;
	if(i<m_tokens.size()-1)//~~
		if(m_tokens.at(i+1).token_type==STRING)
		{
			if(i<m_tokens.size()-3) //如果下面还应该有 变量名,As,类型 三个tokens
			{
				CintMember member;
				if(m_tokens.at(i+2).token_type==COMMAND && 
					m_tokens.at(i+2).tok==AS) //如果接下来的token是As
				{
					if(m_tokens.at(i+3).token_type==COMMAND)//接下来是变量类型
						switch(m_tokens.at(i+3).tok) //看看是什么变量类型
					{
					  case INTEGER: // 如果是Integer类型
						  strcpy(member.name,m_tokens.at(i+1).token);
						  member.value=0;
						  m_intArray.push_back(member);
						  (*index)+=3; // 将m_tokens里的指针跳3个
						  break;
					  default:     
						  break;
					}
				}
			}
		}
}

void CExecutable::Run_Assignment(int *index) //index必须指到'='的token
{
	int var_type=Isvar(m_tokens.at(*index - 1).token);
	if(!var_type) // 如果等号前面不是个变量
	{
		serror(0);
		return;
	}
	switch(var_type)
	{
	case INTEGER:
		{
			int Var_No,value;
			if(!Ai_GetVarNo(m_tokens.at(*index-1).token,&Var_No,INTEGER))
				break;
			(*index)++;
            if(!Ai_GetNextValue(&value,INTEGER,index))
				break;
			m_intArray.at(Var_No).value=value;
			break;
		}
	default: break;
	}
}

void CExecutable::Run_CallSub(int *index)
{
	CExecutable m_call(m_Subs); // 另外创建一个CExetutable类,使用嵌套
	vector <CToken> Subarg; // 创建空白参数表
	if(m_tokens.at(*index).tok==CALL) // 如果用 Call Sub 形式的调用
		(*index)++;
    int Oldindex=*index;
	if(!Ai_GetNextSubarg(Subarg,index))
		return;
	m_call.Run(m_tokens.at(Oldindex).token,Subarg);
}

int CExecutable::Ai_GetNextValue(void *result,int type,int *index) //index指到代数式的第一个token
{
	switch(type)
	{
	case INTEGER: get_exp((int*)result,index);
		(*index)--;
		return 1;
	default:    return 0;
	}
	
}

//调用此函数后,index指到代数式最后一个token
int CExecutable::Ai_GetNextIfValue(int *result,int *index) // index必须指到要判断的代数式第一个token的引索
{
	int result1,result2; // e.g: If result1 > result2 // op='>' 
	char op[2];
	if(!Ai_GetNextValue(&result1,INTEGER,index))
	{	
		serror(0);
		return 0;
	}
	(*index)++;
    op[0]=*m_tokens.at(*index).token;
	op[1]='\0';
	(*index)++;
	if(!Ai_GetNextValue(&result2,INTEGER,index))
	{	
		serror(0);
		return 0;
	}
	switch(op[0])
	{
	case '>':
		{
			if(result1 > result2)
				*result=1;
			else
				*result=0;
			return 1;
		}
	case '=' :
        {
			if(result1 == result2)
				*result=1;
			else
				*result=0;
			return 1;
		}
	case '<':
		{
			if(result1 < result2)
				*result=1;
			else
				*result=0;
			return 1;
		}
	default:  break;

⌨️ 快捷键说明

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