?? executable.cpp
字號:
// 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 + -