www.pudn.com > Basic语言解释器.zip > Executable.cpp
// Executable.cpp: implementation of the CExecutable class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "Executable.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CExecutable::CExecutable(vectorSubs) { 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 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; } 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(l tokenlength=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); }