#include "../BasicCompiler_Common/common.h" #include "Opcode.h" void OpcodeOthers(char *Command){ int i,i2; UserProc *pUserProc; char leftTerm[8192]; int lastParePos = 0; for(i=0;;i++){ if(Command[i]=='\"'){ //ダブルクォートは不正なのでエラー扱い leftTerm[i]=0; SetError(3,leftTerm,cp); return; } if(Command[i]=='('){ lastParePos = i; i2=GetStringInPare(leftTerm+i,Command+i); i+=i2-1; continue; } if(Command[i]=='['){ i2=GetStringInBracket(leftTerm+i,Command+i); i+=i2-1; continue; } if(Command[i]=='\0'){ leftTerm[i] = 0; break; } if( IsNumCalcMark( Command, i ) ){ leftTerm[i] = 0; break; } leftTerm[i]=Command[i]; } if(!( IsVariableTopChar(leftTerm[0])|| leftTerm[0]=='.'|| (leftTerm[0]==1&&leftTerm[1]==ESC_PSMEM) )){ SetError(1,NULL,cp); return; } if(Command[i]=='\0' && lastParePos == 0){ ////////////////////////////// // パラメータ無しのマクロ検索 ////////////////////////////// pUserProc=GetSubHash(Command); //GetSubHash内でエラー提示が行われた場合 if(pUserProc==(UserProc *)-1) return; if(pUserProc==0){ char temporary[VN_SIZE]; lstrcpy(temporary,Command); CharUpper(temporary); pUserProc=GetSubHash(temporary); //GetSubHash内でエラー提示が行われた場合 if(pUserProc==(UserProc *)-1) return; } if(pUserProc){ if( !pUserProc->IsMacro() ){ SetError(10,Command,cp); } Opcode_CallProc("",pUserProc,0,"",0); return; } } else if(IsNumCalcMark(Command,i)){ //代入演算 OpcodeCalc(Command); return; } Type resultType; bool isLiteral; BOOL bUseHeap; bool result = TermOpe( leftTerm, Type(), resultType, isLiteral, &bUseHeap, NULL, true ); if( result ){ ///////////////////// // 戻り値の処理 ///////////////////// if( resultType.IsReal() ){ //fstp st(0) OpBuffer[obp++]=(char)0xDD; OpBuffer[obp++]=(char)0xD8; } else if( resultType.IsStruct() ){ //mov ebx,eax op_mov_RR(REG_EBX,REG_EAX); FreeTempObject(REG_EBX,&resultType.GetClass()); } //成功 return; } // 失敗 SetError(1, NULL,cp); } void OpcodeIf(char *Parameter){ int i,i2,i3,i4; Type tempType; for(i=0;;i++){ if(Parameter[i]=='\0'){ SetError(21,NULL,cp); return; } if(Parameter[i]==1&&Parameter[i+1]==ESC_THEN){ Parameter[i]=0; break; } } if( !NumOpe(Parameter,Type(),tempType) ){ //NumOpe内でエラー i3=-1; //ダミー } else if( tempType.IsDouble() ){ //fld qword ptr[esp] op_fld_ptr_esp(DEF_DOUBLE); //push 0 op_push_V(0); //fild dword ptr[esp] op_fld_ptr_esp(DEF_LONG); //add esp,sizeof(double)+sizeof(long) op_add_esp(sizeof(double)+sizeof(long)); //fcompp OpBuffer[obp++]=(char)0xDE; OpBuffer[obp++]=(char)0xD9; //fnstsw ax OpBuffer[obp++]=(char)0xDF; OpBuffer[obp++]=(char)0xE0; //test ah,40 OpBuffer[obp++]=(char)0xF6; OpBuffer[obp++]=(char)0xC4; OpBuffer[obp++]=(char)0x40; //jne (endif、または else まで) OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x85; obp+=sizeof(long); //jneの番地 i3=obp; } else if( tempType.IsSingle() ){ //fld dword ptr[esp] op_fld_ptr_esp(DEF_SINGLE); //push 0 op_push_V(0); //fild dword ptr[esp] op_fld_ptr_esp(DEF_LONG); //add esp,sizeof(float)+sizeof(long) op_add_esp(sizeof(float)+sizeof(long)); //fcompp OpBuffer[obp++]=(char)0xDE; OpBuffer[obp++]=(char)0xD9; //fnstsw ax OpBuffer[obp++]=(char)0xDF; OpBuffer[obp++]=(char)0xE0; //test ah,40 OpBuffer[obp++]=(char)0xF6; OpBuffer[obp++]=(char)0xC4; OpBuffer[obp++]=(char)0x40; //jne (endif、または else まで) OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x85; obp+=sizeof(long); //jneの番地 i3=obp; } else if( tempType.Is64() ){ //64ビット型 //pop eax op_pop(REG_EAX); //pop ebx op_pop(REG_EBX); //cmp eax,0 OpBuffer[obp++]=(char)0x83; OpBuffer[obp++]=(char)0xF8; OpBuffer[obp++]=(char)0x00; //jne OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x85; obp+=sizeof(long); i3=obp; //cmp ebx,0 OpBuffer[obp++]=(char)0x83; OpBuffer[obp++]=(char)0xFB; OpBuffer[obp++]=(char)0x00; //jne OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x85; obp+=sizeof(long); i4=obp; //jmp (endif、または else までジャンプ) OpBuffer[obp++]=(char)0xE9; obp+=sizeof(long); *((long *)(OpBuffer+i3-sizeof(long)))=obp-i3; *((long *)(OpBuffer+i4-sizeof(long)))=obp-i4; //jmpの番地 i3=obp; } else{ //32ビット型 //pop eax op_pop(REG_EAX); //cmp eax,0 OpBuffer[obp++]=(char)0x83; OpBuffer[obp++]=(char)0xF8; OpBuffer[obp++]=(char)0x00; //je (endif、または else まで条件ジャンプ) OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x84; obp+=sizeof(long); //jeの番地 i3=obp; } ///////////////////////// // If内をコード化 ///////////////////////// //レキシカルスコープをレベルアップ obj_LexScopes.Start( obp, SCOPE_TYPE_IF ); i2=CompileBuffer(ESC_ENDIF,0); //レキシカルスコープをレベルダウン obj_LexScopes.End(); if(i3==-1) return; if(i2==ESC_ELSE){ //jmp (endifまで) OpBuffer[obp++]=(char)0xE9; obp+=sizeof(long); *((long *)(OpBuffer+i3-sizeof(long)))=obp-i3; //ifからelseへのジャンプ先のオフセット値 i3=obp; ///////////////////////// // Else内をコード化 ///////////////////////// //レキシカルスコープをレベルアップ obj_LexScopes.Start( obp, SCOPE_TYPE_IF ); CompileBuffer(ESC_ENDIF,0); //レキシカルスコープをレベルダウン obj_LexScopes.End(); *((long *)(OpBuffer+i3-sizeof(long)))=obp-i3; //jmpジャンプ先のオフセット値 } else{ *((long *)(OpBuffer+i3-sizeof(long)))=obp-i3; //jeジャンプ先のオフセット値 } } int GetLabelAddress(char *LabelName,int LineNum){ extern int MaxLabelNum; extern LABEL *pLabelNames; int i; if(LabelName){ for(i=0;i=0",StepNum); NumOpe(temporary,Type(),Type()); //pop eax op_pop(REG_EAX); //cmp eax,0 OpBuffer[obp++]=(char)0x83; OpBuffer[obp++]=(char)0xF8; OpBuffer[obp++]=(char)0x00; //je [カウンタ減少の場合の判定] OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x84; i2=obp; obp+=sizeof(long); //判定(カウンタ増加の場合) sprintf(temporary,"%s<=(%s)",variable,JudgeNum); NumOpe(temporary,Type(),Type()); //pop eax op_pop(REG_EAX); //jmp [カウンタ減少の場合の判定を飛び越す] OpBuffer[obp++]=(char)0xE9; i3=obp; obp+=sizeof(long); *((long *)(OpBuffer+i2))=obp-(i2+sizeof(long)); //jeジャンプ先のオフセット値 //判定(カウンタ減少の場合) sprintf(temporary,"%s>=(%s)",variable,JudgeNum); NumOpe(temporary,Type(),Type()); //pop eax op_pop(REG_EAX); *((long *)(OpBuffer+i3))=obp-(i3+sizeof(long)); //jmpジャンプ先のオフセット値 //cmp eax,0 OpBuffer[obp++]=(char)0x83; OpBuffer[obp++]=(char)0xF8; OpBuffer[obp++]=(char)0x00; ErrorStep: //je ... OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x84; int je_schedule=obp; obp+=sizeof(long); //レキシカルスコープをレベルアップ obj_LexScopes.Start( obp, SCOPE_TYPE_FOR ); //For内をコンパイル CompileBuffer(0,COM_NEXT); obj_LexScopes.CallDestructorsOfScopeEnd(); if(szNextVariable[0]){ if(lstrcmp(szNextVariable,variable)!=0){ SetError(55,szNextVariable,cp); } } //jmp ... OpBuffer[obp++]=(char)0xE9; *((long *)(OpBuffer+obp))=dwContinueAddress-(obp+sizeof(long)); obp+=sizeof(long); //レキシカルスコープをレベルダウン obj_LexScopes.End(); *((long *)(OpBuffer+je_schedule))=obp-(je_schedule+sizeof(long)); //jeジャンプ先のオフセット値 //Continueアドレスを復元 dwContinueAddress=dwTempContinue; } void OpcodeDo(char *Parameter){ extern HANDLE hHeap; int i,i2,i3,i4; if(Parameter[0]) SetError(10,"Do",cp); //Continueアドレスのバックアップとセット extern DWORD dwContinueAddress; DWORD dwTempContinue; dwTempContinue=dwContinueAddress; dwContinueAddress=obp; //レキシカルスコープをレベルアップ obj_LexScopes.Start( obp, SCOPE_TYPE_DO ); //Do内をコンパイル CompileBuffer(0,COM_LOOP); obj_LexScopes.CallDestructorsOfScopeEnd(); extern char *basbuf; char temporary[VN_SIZE]; for(i=cp-1;;i--){ if(IsCommandDelimitation(basbuf[i])){ i+=3; if(!(basbuf[i]=='0'||basbuf[i]=='1')){ //無条件ループ break; } i3=i; for(i+=2,i2=0;;i++,i2++){ if(IsCommandDelimitation(basbuf[i])){ temporary[i2]=0; break; } temporary[i2]=basbuf[i]; } Type tempType; NumOpe(temporary,Type(),tempType); if( tempType.IsDouble() ){ //fld qword ptr[esp] op_fld_ptr_esp(DEF_DOUBLE); //push 0 op_push_V(0); //fild dword ptr[esp] op_fld_ptr_esp(DEF_LONG); //add esp,sizeof(double)+sizeof(long) op_add_esp(sizeof(double)+sizeof(long)); //fcompp OpBuffer[obp++]=(char)0xDE; OpBuffer[obp++]=(char)0xD9; //fnstsw ax OpBuffer[obp++]=(char)0xDF; OpBuffer[obp++]=(char)0xE0; //test ah,40 OpBuffer[obp++]=(char)0xF6; OpBuffer[obp++]=(char)0xC4; OpBuffer[obp++]=(char)0x40; if(basbuf[i3]=='0'){ //While //jne 5(ループ終了) OpBuffer[obp++]=(char)0x75; OpBuffer[obp++]=(char)0x05; } else if(basbuf[i3]=='1'){ //Until //je 5(ループ終了) OpBuffer[obp++]=(char)0x74; OpBuffer[obp++]=(char)0x05; } } else if( tempType.IsSingle() ){ //fld dword ptr[esp] op_fld_ptr_esp(DEF_SINGLE); //push 0 op_push_V(0); //fild dword ptr[esp] op_fld_ptr_esp(DEF_LONG); //add esp,sizeof(float)+sizeof(long) op_add_esp(sizeof(float)+sizeof(long)); //fcompp OpBuffer[obp++]=(char)0xDE; OpBuffer[obp++]=(char)0xD9; //fnstsw ax OpBuffer[obp++]=(char)0xDF; OpBuffer[obp++]=(char)0xE0; //test ah,40 OpBuffer[obp++]=(char)0xF6; OpBuffer[obp++]=(char)0xC4; OpBuffer[obp++]=(char)0x40; if(basbuf[i3]=='0'){ //While //jne 5(ループ終了) OpBuffer[obp++]=(char)0x75; OpBuffer[obp++]=(char)0x05; } else if(basbuf[i3]=='1'){ //Until //je 5(ループ終了) OpBuffer[obp++]=(char)0x74; OpBuffer[obp++]=(char)0x05; } } else if( tempType.Is64() ){ //64ビット型 //pop eax op_pop(REG_EAX); //pop ebx op_pop(REG_EBX); //cmp eax,0 OpBuffer[obp++]=(char)0x83; OpBuffer[obp++]=(char)0xF8; OpBuffer[obp++]=(char)0x00; //jne OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x85; obp+=sizeof(long); i2=obp; //cmp ebx,0 OpBuffer[obp++]=(char)0x83; OpBuffer[obp++]=(char)0xFB; OpBuffer[obp++]=(char)0x00; //jne OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x85; obp+=sizeof(long); i4=obp; if(basbuf[i3]=='0'){ //While //jmp 5(ループ終了) OpBuffer[obp++]=(char)0xEB; OpBuffer[obp++]=(char)0x05; *((long *)(OpBuffer+i2-sizeof(long)))=obp-i2; *((long *)(OpBuffer+i4-sizeof(long)))=obp-i4; } else if(basbuf[i3]=='1'){ //Until //jmp 2(ループを続ける) OpBuffer[obp++]=(char)0xEB; OpBuffer[obp++]=(char)0x02; *((long *)(OpBuffer+i2-sizeof(long)))=obp-i2; *((long *)(OpBuffer+i4-sizeof(long)))=obp-i4; //jmp 5(ループ終了) OpBuffer[obp++]=(char)0xEB; OpBuffer[obp++]=(char)0x05; } } else{ //pop eax op_pop(REG_EAX); //cmp eax,0 OpBuffer[obp++]=(char)0x83; OpBuffer[obp++]=(char)0xF8; OpBuffer[obp++]=(char)0x00; if(basbuf[i3]=='0'){ //While //je 5(ループ終了) OpBuffer[obp++]=(char)0x74; OpBuffer[obp++]=(char)0x05; } else if(basbuf[i3]=='1'){ //Until //jne 5(ループ終了) OpBuffer[obp++]=(char)0x75; OpBuffer[obp++]=(char)0x05; } } break; } } //jmp ... OpBuffer[obp++]=(char)0xE9; *((long *)(OpBuffer+obp))=dwContinueAddress-(obp+sizeof(long)); obp+=sizeof(long); //jmp ... OpBuffer[obp++]=(char)0xE9; int je_schedule=obp; obp+=sizeof(long); //レキシカルスコープをレベルダウン obj_LexScopes.End(); *((long *)(OpBuffer+je_schedule))=obp-(je_schedule+sizeof(long)); //jmpジャンプ先のオフセット値 //Continueアドレスを復元 dwContinueAddress=dwTempContinue; } void OpcodeContinue(void){ extern DWORD dwContinueAddress; if(dwContinueAddress==-1){ SetError(12,"Continue",cp); return; } //jmp ...(Continue addr) OpBuffer[obp++]=(char)0xE9; *((long *)(OpBuffer+obp))=dwContinueAddress-(obp+sizeof(long)); obp+=sizeof(long); } void OpcodeExitSub(void){ extern DWORD *pExitSubSchedule; extern int ExitSubScheduleNum; extern HANDLE hHeap; if( UserProc::IsGlobalAreaCompiling() ){ SetError(12,"Exit Sub/Function",cp); return; } //未解放のローカルオブジェクトのデストラクタを呼び出す obj_LexScopes.CallDestructorsOfReturn(); //jmp ...(End Sub/Function) OpBuffer[obp++]=(char)0xE9; pExitSubSchedule=(DWORD *)HeapReAlloc(hHeap,0,pExitSubSchedule,(ExitSubScheduleNum+1)*sizeof(DWORD)); pExitSubSchedule[ExitSubScheduleNum]=obp; ExitSubScheduleNum++; obp+=sizeof(long); } void AddCaseSchedule(void){ extern DWORD *pCaseSchedule; extern int CaseScheduleNum; extern HANDLE hHeap; pCaseSchedule=(DWORD *)HeapReAlloc(hHeap,0,pCaseSchedule,(CaseScheduleNum+1)*sizeof(DWORD)); pCaseSchedule[CaseScheduleNum]=obp; CaseScheduleNum++; } int CaseTypeSize; void OpcodeSelect(const char *lpszParms){ extern DWORD *pCaseSchedule; extern int CaseScheduleNum; extern int NowCaseSchedule; extern int CaseTypeSize; extern HANDLE hHeap; extern char *basbuf; int i,i2,i3,sw,NowCaseCp; char temporary[VN_SIZE]; DWORD *temp_pCaseSchedule; int temp_CaseScheduleNum; int temp_NowCaseSchedule; int temp_CaseTypeSize; temp_pCaseSchedule=pCaseSchedule; temp_CaseScheduleNum=CaseScheduleNum; temp_NowCaseSchedule=NowCaseSchedule; temp_CaseTypeSize=CaseTypeSize; pCaseSchedule=(DWORD *)HeapAlloc(hHeap,0,1); CaseScheduleNum=0; NowCaseSchedule=0; Type type1; if( !NumOpe(lpszParms,Type(), type1 ) ){ return; } CaseTypeSize = type1.GetSize(); if( CaseTypeSize < sizeof(long) ){ CaseTypeSize=sizeof(long); } for(i=cp,sw=0;;i++){ if(basbuf[i]=='\0'){ HeapDefaultFree(pCaseSchedule); pCaseSchedule=temp_pCaseSchedule; CaseScheduleNum=temp_CaseScheduleNum; NowCaseSchedule=temp_NowCaseSchedule; CaseTypeSize=temp_CaseTypeSize; SetError(22,"Select",cp); return; } if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE){ for(i2=0;;i++){ if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE) i2++; if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT){ i2--; if(i2==0) break; } } continue; } if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT){ if(sw==0){ //add esp,CaseTypeSize op_add_esp(CaseTypeSize); } break; } if(basbuf[i]==1&&basbuf[i+1]==ESC_CASE){ NowCaseCp=i; i++; while(1){ for(i++,i2=0;;i++,i2++){ if(basbuf[i]=='\"'){ i3=GetStringInQuotation(temporary+i2,basbuf+i); i+=i3-1; i2+=i3-1; continue; } if(basbuf[i]=='('){ i3=GetStringInPare(temporary+i2,basbuf+i); i+=i3-1; i2+=i3-1; continue; } if(basbuf[i]=='['){ i3=GetStringInBracket(temporary+i2,basbuf+i); i+=i3-1; i2+=i3-1; continue; } if(IsCommandDelimitation(basbuf[i])){ temporary[i2]=0; break; } if(basbuf[i]==','){ temporary[i2]=0; break; } temporary[i2]=basbuf[i]; } //エラー用 i2=cp; cp=NowCaseCp; Type type2; if( !NumOpe(temporary,type1,type2) ){ return; } cp=i2; if(type1.IsObject()){ std::vector subs; type1.GetClass().EnumMethod( CALC_EQUAL, subs ); if( subs.size() == 0 ){ return; } Parameters params; params.push_back( new Parameter( "", Type( type2 ) ) ); //オーバーロードを解決 UserProc *pUserProc; pUserProc=OverloadSolution("==",subs, params, NULL); delete params[0]; if(!pUserProc){ //エラー return; } //pop edx op_pop(REG_EDX); //mov ecx,dword ptr[esp] op_mov_RM(sizeof(long),REG_ECX,REG_ESP,0,MOD_BASE); //push edx op_push(REG_EDX); //push ecx op_push(REG_ECX); //call operator_proc ※ ==演算子 op_call(pUserProc); //test eax,eax op_test(REG_EAX,REG_EAX); //jne ... OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x85; AddCaseSchedule(); obp+=sizeof(long); } else if(type1.IsDouble()){ ChangeTypeToDouble(type2.GetBasicType()); //fld qword ptr[esp] op_fld_ptr_esp(DEF_DOUBLE); //add esp,CaseTypeSize op_add_esp(CaseTypeSize); //fld qword ptr[esp] op_fld_ptr_esp(DEF_DOUBLE); //fcompp OpBuffer[obp++]=(char)0xDE; OpBuffer[obp++]=(char)0xD9; //fnstsw ax OpBuffer[obp++]=(char)0xDF; OpBuffer[obp++]=(char)0xE0; //test ah,40 OpBuffer[obp++]=(char)0xF6; OpBuffer[obp++]=(char)0xC4; OpBuffer[obp++]=(char)0x40; //jne ... OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x85; AddCaseSchedule(); obp+=sizeof(long); } else if(type1.IsSingle()){ ChangeTypeToSingle(type2.GetBasicType()); //fld dword ptr[esp] op_fld_ptr_esp(DEF_SINGLE); //add esp,CaseTypeSize op_add_esp(CaseTypeSize); //fld dword ptr[esp] op_fld_ptr_esp(DEF_SINGLE); //fcompp OpBuffer[obp++]=(char)0xDE; OpBuffer[obp++]=(char)0xD9; //fnstsw ax OpBuffer[obp++]=(char)0xDF; OpBuffer[obp++]=(char)0xE0; //test ah,40 OpBuffer[obp++]=(char)0xF6; OpBuffer[obp++]=(char)0xC4; OpBuffer[obp++]=(char)0x40; //jne ... OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x85; AddCaseSchedule(); obp+=sizeof(long); } else{ //その他整数型 //pop ebx op_pop(REG_EBX); //mov eax,dword ptr[esp] OpBuffer[obp++]=(char)0x8B; OpBuffer[obp++]=(char)0x04; OpBuffer[obp++]=(char)0x24; //cmp eax,ebx OpBuffer[obp++]=(char)0x3B; OpBuffer[obp++]=(char)0xC3; //je ... OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x84; AddCaseSchedule(); obp+=sizeof(long); } if(basbuf[i]!=',') break; } } if(basbuf[i]==1&&basbuf[i+1]==ESC_CASEELSE){ sw=1; //jmp ... OpBuffer[obp++]=(char)0xE9; AddCaseSchedule(); obp+=sizeof(long); } } //レキシカルスコープをレベルアップ obj_LexScopes.Start( obp, SCOPE_TYPE_SELECT ); //Select Case内をコンパイル CompileBuffer(ESC_ENDSELECT,0); //jmp EndSelect OpBuffer[obp++]=(char)0xE9; AddCaseSchedule(); obp+=sizeof(long); //最終スケジュール for(i=NowCaseSchedule;i