www.pudn.com > Basic语言解释器.zip > Executable.cpp


// Executable.cpp: implementation of the CExecutable class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "Executable.h" 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
 
CExecutable::CExecutable(vector  Subs) 
{ 
	m_Subs=Subs; 
} 
 
CExecutable::~CExecutable() 
{ 
	m_intArray.clear(); 
	m_tokens.clear(); 
	m_Subs.clear(); 
} 
 
void CExecutable::Run(char *SubName,vector  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 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'  
	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; 
	} 
	return 0; 
} 
 
 
int CExecutable::Ai_GetVarNo(char *name,int *result,int type) 
{ 
	switch(type) 
	{ 
	case INTEGER: 
		{ 
			if(m_intArray.size()==0) 
				return 0; 
			for(int i=0;i<=m_intArray.size()-1;i++) 
				if(!_strcmpi(name,m_intArray.at(i).name)) 
					*result=i; 
				return 1; 
		} 
	default: return 0; 
	} 
	 
} 
 
int CExecutable::Ai_GetSubNo(char *name,int *result) 
{ 
    int i; 
	for(i=0;i<=m_Subs.size()-1;i++) // 在m_Subs里寻找叫SubName的过程 
		if(_strcmpi(m_Subs.at(i).name,name)==0) 
		{ 
			 
			*result=i; 
			return 1; 
		} 
		return 0; 
} 
int CExecutable::Ai_GetNextThen(int *result,int *index) 
{ 
	int if_no=1; //出现If语句的次数 
	for(int i=*index;i<=m_tokens.size()-1;i++) 
	{ 
		if(m_tokens.at(i).tok==IF) 
		{ 
			if_no++; 
			continue; 
		} 
        if(m_tokens.at(i).tok==THEN) 
		{ 
			if_no--; 
			if(if_no==0) 
			{ 
				*result=i; 
				return 1; 
			} 
		} 
	} 
	return 0; 
} 
 
 
int CExecutable::Ai_GetNextEndIf(int *result,int *index) 
{ 
	int if_no=1; //出现If语句的次数 
	for(int i=*index;i<=m_tokens.size()-1;i++) 
	{ 
		if(m_tokens.at(i).tok==IF) 
		{ 
			if_no++; 
			continue; 
		} 
        if(m_tokens.at(i).tok==END && i+1<=m_tokens.size()-1) 
			if(m_tokens.at(i+1).tok==IF) 
			{ 
				if_no--; 
				if(if_no==0) 
				{ 
					*result=i+1; 
					return 2; 
				} 
			} 
	} 
	// 没有找到匹配的End If 则默认为是没有End If的Then后的单语句 
     
	if(!Ai_GetNextThen(result,index)) // 先找Then 
	{ 
		serror(8); 
		return 0; 
	} 
	*index=*result+1; 
	 
	while(m_tokens.at(*index).token_type==ENTER) //跳过换行符 
		(*index)++; 
	if(!Ai_GetNextLine(result,index)) // 跳过Then后的一跳语句 
	{ 
		serror(0); 
		return 0; 
	} 
    *index=*result; 
	return 1; 
} 
 
//index必须指到While 
int CExecutable::Ai_GetNextLoop(int *result,int *index) 
{ 
	int do_no=1; //出现Do语句的次数 
	for(int i=*index;i<=m_tokens.size()-1;i++) 
	{ 
		if(m_tokens.at(i).tok==DO) 
		{ 
			do_no++; 
			continue; 
		} 
        if(m_tokens.at(i).tok==LOOP) 
		{ 
			do_no--; 
			if(do_no==0) 
			{ 
				*result=i; 
				return 1; 
			} 
		} 
	} 
	return 0; 
} 
 
int CExecutable::Ai_GetLastDo(int *result,int *index) 
{ 
	int loop_no=1; //出现Loop语句的次数 
	if(m_tokens.size()<1 || *index>=m_tokens.size()-1) // 如果index超出范围 
		return 0; 
	for(int i=*index;i>=0;i--) 
	{ 
		if(m_tokens.at(i).tok==LOOP) 
		{ 
			loop_no++; 
			continue; 
		} 
        if(m_tokens.at(i).tok==DO) 
		{ 
			if(i-1>=0) 
				if(m_tokens.at(i-1).tok==EXIT) // 如果是Exit Do中的Do 
					continue;  
				loop_no--; 
				if(loop_no==0) 
				{ 
					*result=i; 
					return 1; 
				} 
		} 
	} 
	return 0; 
} 
 
 
int CExecutable::Ai_GetNextLine(int *result,int *index)// result指到下一个ENTER换行符 
{ 
	for(int i=*index;i<=m_tokens.size()-1;i++) 
		if(m_tokens.at(i).token_type==ENTER) 
		{ 
			*result=i; 
			return 1; 
		} 
		return 0; 
} 
 
int CExecutable::Ai_GetNextSubarg(vector &Subarg,int *index) 
{ 
	int subno; 
	if(!Ai_GetSubNo(m_tokens.at(*index).token,&subno)) // 先把此过程的index传给subno 
	{ 
		serror(7); 
		return 0; 
	} 
	 
	(*index)++; 
	if(*m_tokens.at(*index).token=='(') 
		(*index)++; 
	else 
	{	    
		serror(16); 
		return 0; 
	} 
	int l=0,type; 
	vector  argtokens; 
	CToken *pA_Subarg; // 单个参数 
	argtokens=m_Subs.at(subno).m_argtokens; 
	if(argtokens.size()<=0)  
		return 1; 
	while(*m_tokens.at(*index).token!=')') 
	{ 
		// 先通过subno在m_Subs里找到参数的定义类型,再通过此类型 
		// 调用Ai_GetNextValue得到参数值 
		while(ltokenlength=sizeof(int); 
				pA_Subarg->token=new char[pA_Subarg->tokenlength]; 
				memcpy(pA_Subarg->token,&result,sizeof(int)); 
				break; 
			} 
		default: 
			break; 
		} 
		pA_Subarg->tok=type; 
		Subarg.push_back(*pA_Subarg); 
		delete pA_Subarg; 
		(*index)++; 
		while(*m_tokens.at(*index).token==',') // 如果参数后面一个token是','则必须跳过它 
			(*index)++; 
		 
	} 
	return 1; 
} 
 
void CExecutable::get_exp(int *result,int *index) 
{ 
    if (!*m_tokens.at(*index).token) 
	{ 
        serror(2); 
        return; 
    } 
    level2(result,index); 
     
	//putback();  /*return last token read to input stream */ 
} 
 
 
/* add or subtract two terms */ 
void CExecutable::level2(int *result,int *index) 
{ 
    register char op; 
    int hold; 
    level3(result,index); 
    while ((op = *m_tokens.at(*index).token) =='+' || op == '-')   
	{ 
        (*index)++; 
        level3(&hold,index); 
        arith(op,result,&hold); 
    } 
} 
 
 
/* multiply or divide two factors */ 
void CExecutable::level3(int *result,int *index) 
{ 
	register char op; 
    int hold; 
    level4(result,index); 
    while ((op = *m_tokens.at(*index).token) == '*' || op == '/' || op == '%')   
	{ 
        (*index)++; 
        level3(&hold,index); 
        arith(op,result,&hold); 
    } 
} 
 
 
/* process integer exponent */ 
void CExecutable::level4(int *result,int *index) 
{ 
	register char op; 
    int hold; 
    level5(result,index); 
    if ((op = *m_tokens.at(*index).token) == '^')  
	{ 
        (*index)++; 
        level5(&hold,index); 
        arith(op,result,&hold); 
    } 
} 
 
 
/* is a unary + or - */               
void CExecutable::level5(int *result,int *index) 
{ 
    register char op; 
    op = 0; 
    if ((m_tokens.at(*index).token_type==DELIMITER) &&  
		*m_tokens.at(*index).token == '+' ||  
		*m_tokens.at(*index).token == '-' )   
	{ 
        op = *m_tokens.at(*index).token; 
        (*index)++; 
    } 
    level6(result,index); 
    if (op)   
		if(op=='-') 
			*result=-(*result); 
} 
 
 
/* process parenthesized expression */                 
void CExecutable::level6(int *result,int *index) 
{ 
	if ((*m_tokens.at(*index).token == '(') && (m_tokens.at(*index).token_type == DELIMITER))   
	{ 
        (*index)++; 
        level2(result,index); 
        if (*m_tokens.at(*index).token!=')') 
            serror(1); 
        (*index)++; 
    } 
    else  
        primitive(result,index); 
} 
 
/* find value of number or variable */ 
void CExecutable::primitive(int *result,int *index) 
{ 
	int token_type=m_tokens.at(*index).token_type; 
    if(Isvar(m_tokens.at(*index).token))		 
		token_type=VARIABLE; 
    switch (token_type)   
	{ 
	case VARIABLE: 
		find_var(m_tokens.at(*index).token,result); 
		(*index)++; 
		return; 
	case NUMBER: 
		*result = atoi(m_tokens.at(*index).token); 
		(*index)++; 
		return; 
	default: 
		serror(0); 
    } 
} 
 
int CExecutable::find_var(char *var_name,void *value) 
{ 
	for(int i=0;i<=m_intArray.size()-1;i++) 
		if(!strcmp(var_name,m_intArray.at(i).name)) 
		{ 
			int *int_value=(int *)value; 
			*int_value=m_intArray.at(i).value; 
			return 1; 
		} 
		return 0; 
} 
 
int CExecutable::Isvar(char *name) 
{ 
	if(m_intArray.size()==0) 
		return 0; 
	for(int i=0;i<=m_intArray.size()-1;i++) 
		if(!strcmp(name,m_intArray.at(i).name)) 
			return INTEGER; 
		return 0; 
} 
 
/* perform the specified arithmetic */ 
void CExecutable::arith(char o,int *r,int *h) 
{ 
    /*register*/ int t,ex; 
     
    switch (o)  { 
	case '-': 
		*r = *r-*h; 
		break; 
	case '+': 
		*r = *r+*h; 
		break; 
	case '*': 
		*r = *r**h; 
		break; 
	case '/': 
		*r = (*r)/(*h); 
		break; 
	case '%': 
		*r = (*r)%(*h); 
		break; 
	case '^': 
		ex = *r; 
		if (*h==0)  { 
			*r = 1; 
			break; 
		} 
		for (t=*h-1;t>0;--t)  *r=(*r)*ex; 
		break; 
    } 
} 
 
 
void CExecutable::serror(int error) 
{ 
	char *e[] = { 
        "syntax error",          // 0 
			"unbalanced parentheses", // 1 
			"no expression present", // 2 
			"equal sign expected",  // 3 
			"not a variable",      // 4 
			"label table full",   // 5 
			"duplicate label",      // 6 
			"undefined label",     // 7 
			"THEN expected",      // 8 
			"TO expected",        // 9 
			"too many nested FOR loops", // 10 
			"NEXT without FOR",    // 11 
			"too many nested GOSUB", // 12 
			"RETURN without GOSUB",   // 13 
			"While without Do",  // 14 
			"Do without Loop", // 15 
			"'(' is not behind the call of sub" // 16 
    }; 
	 
    printf ("%s\n",e[error]); 
} 
 
void CExecutable::Debug(int i) 
{ 
	printf("Debug token:%s ,tok:%d ,index:%d \n",m_tokens.at(i).token,m_tokens.at(i).tok,i); 
}