#include "../BasicCompiler_Common/common.h" #include "Opcode.h" void OpcodeOthers(char *Command){ int i,i2; char buffer[8192]; SUBINFO *psi; for(i=0;;i++){ if(Command[i]=='['){ i2=GetStringInBracket(buffer+i,Command+i); i+=i2-1; continue; } if(Command[i]==1&&Command[i+1]==ESC_PSMEM){ buffer[i]=Command[i]; i++; buffer[i]=Command[i]; continue; } if(!IsVariableChar(Command[i])){ buffer[i]=0; break; } buffer[i]=Command[i]; } if(!( IsVariableTopChar(buffer[0])|| buffer[0]=='.'|| (buffer[0]==1&&buffer[1]==ESC_PSMEM) )){ SetError(1,NULL,cp); return; } if(Command[i]=='\0'){ ////////////////////////////// // パラメータ無しのマクロ検索 ////////////////////////////// psi=GetSubHash(Command); //GetSubHash内でエラー提示が行われた場合 if(psi==(SUBINFO *)-1) return; if(psi==0){ char temporary[VN_SIZE]; lstrcpy(temporary,Command); CharUpper(temporary); psi=GetSubHash(temporary); //GetSubHash内でエラー提示が行われた場合 if(psi==(SUBINFO *)-1) return; } if(psi){ if(psi->dwType!=SUBTYPE_MACRO) SetError(10,Command,cp); Opcode_CallProc("",psi,0,"",0); return; } } else if(IsNumCalcMark(Command,i)){ //代入演算 OpcodeCalc(Command); return; } int idProc; void *pInfo; idProc=GetProc(buffer,&pInfo); int i4; char temp2[VN_SIZE]; if(idProc){ if(Command[i]!='('){ SetError(10,buffer,cp); return; } i4=GetStringInPare_RemovePare(temp2,Command+i+1); //閉じカッコ")"に続く文字がNULLでないときはエラーにする if(Command[i+1+i4+1]!='\0') SetError(42,NULL,cp); //////////////// // 呼び出し //////////////// LONG_PTR lp; i2=CallProc(idProc,pInfo,buffer,temp2,&lp); ///////////////////// // 戻り値の処理 ///////////////////// if(i2==DEF_DOUBLE||i2==DEF_SINGLE){ //fstp st(0) OpBuffer[obp++]=(char)0xDD; OpBuffer[obp++]=(char)0xD8; } if(i2==DEF_OBJECT){ CClass *pobj_Class; pobj_Class=(CClass *)lp; if(pobj_Class->DestructorMemberSubIndex!=-1){ //デストラクタの呼び出し //push eax op_push(REG_EAX); //push eax op_push(REG_EAX); //call destructor int i5; i5=pobj_Class->DestructorMemberSubIndex; op_call(pobj_Class->ppobj_Method[i5]->psi); } else{ //push eax op_push(REG_EAX); } //call free extern SUBINFO *pSub_free; op_call(pSub_free); } return; } ////////////////////////// // その他は代入演算を行う ////////////////////////// OpcodeCalc(Command); } void OpcodeIf(char *Parameter){ int i,i2,i3,i4,type; 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; } } type=NumOpe(Parameter,0,0,0); if(type==-1){ //NumOpe内でエラー i3=-1; //ダミー } else if(type==DEF_DOUBLE){ //fld qword ptr[esp] op_fld_ptr_esp(DEF_DOUBLE); //push 0 op_push_value(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(type==DEF_SINGLE){ //fld dword ptr[esp] op_fld_ptr_esp(DEF_SINGLE); //push 0 op_push_value(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(type==DEF_INT64||type==DEF_QWORD){ //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; extern char *basbuf; 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,0,0,0); //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,0,0,0); //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,0,0,0); //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,type; 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=NumOpe(temporary,0,0,0); if(type==DEF_DOUBLE){ //fld qword ptr[esp] op_fld_ptr_esp(DEF_DOUBLE); //push 0 op_push_value(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(type==DEF_SINGLE){ //fld dword ptr[esp] op_fld_ptr_esp(DEF_SINGLE); //push 0 op_push_value(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(type==DEF_INT64||type==DEF_QWORD){ //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; extern BOOL bCompilingGlobal; if(bCompilingGlobal){ 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(char *Parameter){ extern DWORD *pCaseSchedule; extern int CaseScheduleNum; extern int NowCaseSchedule; extern int CaseTypeSize; extern HANDLE hHeap; extern char *basbuf; int i,i2,i3,sw,type1,type2,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; LONG_PTR lpIndex; type1=NumOpe(Parameter,0,0,&lpIndex); if(type1==DEF_INTEGER|| type1==DEF_WORD|| type1==DEF_CHAR|| type1==DEF_BYTE) CaseTypeSize=sizeof(long); else{ CaseTypeSize=GetTypeSize(type1,lpIndex); if(type1==DEF_OBJECT) CaseTypeSize=PTR_SIZE; } 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; LONG_PTR lpIndex2; type2=NumOpe(temporary,type1,lpIndex,&lpIndex2); cp=i2; if(type1==DEF_OBJECT){ CClass *pobj_c; pobj_c=(CClass *)lpIndex; SUBINFO **ppsi; int num; ppsi=pobj_c->GetOperatorSubInfo(CALC_EQUAL,num); if(num==0){ HeapDefaultFree(ppsi); return; } PARAMETER_INFO *ppi = (PARAMETER_INFO *)HeapAlloc(hHeap,0,sizeof(PARAMETER_INFO)*3); int iParmNum=0; ppi[iParmNum].bArray=0; ppi[iParmNum].bByVal=0; ppi[iParmNum].name=0; ppi[iParmNum].type=type2; ppi[iParmNum].u.index=lpIndex2; ppi[iParmNum].SubScripts[0]=-1; iParmNum++; //オーバーロードを解決 SUBINFO *psi; psi=OverloadSolution("==",ppsi,num,ppi,iParmNum,NULL); HeapDefaultFree(ppsi); HeapDefaultFree(ppi); if(!psi){ //エラー 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(psi); //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==DEF_DOUBLE){ ChangeTypeToDouble(type2); //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==DEF_SINGLE){ ChangeTypeToSingle(type2); //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;iname[0]==1&&pCompilingSubInfo->name[1]==ESC_OPERATOR) temp="_System_ReturnValue"; else temp=pCompilingSubInfo->name; char temporary[VN_SIZE]; sprintf(temporary,"%s=%s",temp,Parameter); OpcodeCalc(temporary); } //プロシージャを抜け出す(C言語のreturnと同様の処理を行う) OpcodeExitSub(); } } void Opcode_Input(char *Parameter){ extern int cp; int i2,i3,i4,i5,type; BOOL bFile; char temporary[VN_SIZE],temp2[VN_SIZE],buffer[VN_SIZE]; KillStringSpaces(Parameter); if(Parameter[0]=='#'){ bFile=1; for(i2=0,i3=1;;i2++,i3++){ buffer[i2]=Parameter[i3]; if(Parameter[i3]==','||Parameter[i3]=='\0') break; } buffer[i2+1]=0; i2=i3+1; } else{ bFile=0; i2=0; buffer[0]=0; //表示用文字列パラメータをセット if(Parameter[0]=='\"'){ buffer[0]='\"'; for(i2=1;;i2++){ if(Parameter[i2]=='\"'){ buffer[i2]=0; break; } buffer[i2]=Parameter[i2]; } if(Parameter[i2+1]==';') lstrcpy(buffer+i2,"? \""); else if(Parameter[i2+1]==',') lstrcpy(buffer+i2,"\""); else SetError(10,"Input",cp); i2+=2; } else if((Parameter[0]=='e'||Parameter[0]=='E')&& (Parameter[1]=='x'||Parameter[1]=='X')&& Parameter[2]=='\"'){ memcpy(buffer,Parameter,3); for(i2=3;;i2++){ if(Parameter[i2]=='\"'){ buffer[i2]=0; break; } buffer[i2]=Parameter[i2]; } if(Parameter[i2+1]==';') lstrcpy(buffer+i2,"? \""); else if(Parameter[i2+1]==',') lstrcpy(buffer+i2,"\""); else SetError(10,"Input",cp); i2+=2; } else{ lstrcpy(buffer,"\"? \""); i2=0; } } //変数ポインタ、変数のタイプをセット i4=0; while(1){ for(i3=0;;i2++,i3++){ if(Parameter[i2]=='('){ i5=GetStringInPare(temporary+i3,Parameter+i2); i2+=i5-1; i3+=i5-1; } if(Parameter[i2]=='['){ i5=GetStringInBracket(temporary+i3,Parameter+i2); i2+=i5-1; i3+=i5-1; } if(Parameter[i2]==','){ temporary[i3]=0; i2++; break; } temporary[i3]=Parameter[i2]; if(Parameter[i2]=='\0') break; } if(temporary[0]=='\0'){ SetError(10,"Input",cp); return; } LONG_PTR lpIndex; type = GetVarType(temporary,&lpIndex,1); sprintf(temp2,"_System_InputDataPtr[%d]=VarPtr(%s)",i4,temporary); OpcodeCalc(temp2); if(type==DEF_LONG) type=DEF_DWORD; else if(type==DEF_INTEGER) type=DEF_WORD; else if(type==DEF_OBJECT){ CClass *pobj_Class=(CClass *)lpIndex; if(lstrcmp(pobj_Class->name,"String")==0) type=DEF_STRING; } sprintf(temp2,"_System_InputDataType[%d]=%d",i4,type); OpcodeCalc(temp2); i4++; if(Parameter[i2]=='\0') break; } sprintf(temp2,"_System_InputDataPtr[%d]=0",i4); OpcodeCalc(temp2); SUBINFO *psi; if(bFile) psi=GetSubHash("INPUT_FromFile"); else psi=GetSubHash("INPUT_FromPrompt"); if(!psi){ SetError(3,"Input",cp); return; } Opcode_CallProc(buffer,psi,0,"",0); } void Opcode_PrintUsing(char *Parameter,char *buffer,BOOL bFile){ extern int cp; int i2,i3,i4,i5; char temporary[VN_SIZE],temp2[8192]; BOOL bReturnLine; i2=lstrlen(Parameter); if(Parameter[i2-1]==';'){ bReturnLine=0; Parameter[i2-1]=0; } else bReturnLine=1; i3=lstrlen(buffer); for(i2=0;;i2++,i3++){ if(Parameter[i2]==';'){ buffer[i3]=0; break; } buffer[i3]=Parameter[i2]; if(Parameter[i2]=='\0') break; } if(Parameter[i2]==';') i2++; if(bReturnLine) lstrcat(buffer,"+Ex\"\\r\\n\""); //データポインタ、データのタイプをセット i4=0; while(1){ for(i3=0;;i2++,i3++){ if(Parameter[i2]=='\"'){ temporary[i3]=Parameter[i2]; for(i2++,i3++;;i2++,i3++){ temporary[i3]=Parameter[i2]; if(Parameter[i2]=='\"') break; } continue; } if(Parameter[i2]=='('){ i5=GetStringInPare(temporary+i3,Parameter+i2); i2+=i5-1; i3+=i5-1; continue; } if(Parameter[i2]=='['){ i5=GetStringInBracket(temporary+i3,Parameter+i2); i2+=i5-1; i3+=i5-1; continue; } if(Parameter[i2]==','){ temporary[i3]=0; i2++; break; } temporary[i3]=Parameter[i2]; if(Parameter[i2]=='\0') break; } if(temporary[0]=='\0'){ SetError(10,"Print",cp); return; } int iResult; iResult=IsStrCalculation(temporary); if(iResult==1){ //文字列 sprintf(temp2,"_System_UsingStrData[%d]=%s",i4,temporary); OpcodeCalc(temp2); sprintf(temp2,"_System_UsingDataType[%d]=%d",i4,DEF_STRING); OpcodeCalc(temp2); } else if(iResult==0){ //数値 sprintf(temp2,"_System_UsingDblData[%d]=%s",i4,temporary); OpcodeCalc(temp2); sprintf(temp2,"_System_UsingDataType[%d]=%d",i4,DEF_DOUBLE); OpcodeCalc(temp2); } //else if(iResult==-1) エラー i4++; if(Parameter[i2]=='\0') break; } sprintf(temp2,"_System_UsingDataType[%d]=-1",i4); OpcodeCalc(temp2); SUBINFO *psi; if(bFile) psi=GetSubHash("PRINTUSING_ToFile"); else psi=GetSubHash("PRINTUSING_ToPrompt"); if(!psi){ SetError(3,"Print",cp); return; } Opcode_CallProc(buffer,psi,0,"",0); } void Opcode_Print(char *Parameter,BOOL bWrite){ int i2,i3,i4,sw; char temporary[VN_SIZE],buffer[VN_SIZE]; BOOL bFile; KillStringSpaces(Parameter); if(Parameter[0]=='#'){ bFile=1; for(i2=0,i3=1;;i2++,i3++){ buffer[i2]=Parameter[i3]; if(Parameter[i3]==','||Parameter[i3]=='\0') break; } buffer[i2+1]=0; if(Parameter[i3]==',') i3++; i2=i3; } else{ bFile=0; i2=0; buffer[0]=0; } if(Parameter[i2]==1&&Parameter[i2+1]==ESC_USING){ Opcode_PrintUsing(Parameter+i2+2,buffer,bFile); return; } lstrcat(buffer,"_System_DummyStr+"); sw=1; while(1){ for(i3=0;;i2++,i3++){ if(Parameter[i2]=='\"'){ temporary[i3]=Parameter[i2]; for(i2++,i3++;;i2++,i3++){ temporary[i3]=Parameter[i2]; if(Parameter[i2]=='\"') break; } continue; } if(Parameter[i2]=='('){ i4=GetStringInPare(temporary+i3,Parameter+i2); i2+=i4-1; i3+=i4-1; continue; } if(Parameter[i2]=='['){ i4=GetStringInBracket(temporary+i3,Parameter+i2); i2+=i4-1; i3+=i4-1; continue; } if(Parameter[i2]==','||Parameter[i2]==';'){ temporary[i3]=0; break; } temporary[i3]=Parameter[i2]; if(Parameter[i2]=='\0') break; } if(temporary[0]=='\0') lstrcat(buffer,"\"\""); else{ int iResult; iResult=IsStrCalculation(temporary); if(iResult==-1){ //エラー lstrcat(buffer,"\"\""); } else if(iResult){ //文字列 lstrcat(buffer,temporary); } else{ //数値 sprintf(buffer+lstrlen(buffer),"Str$(%s)",temporary); } } if(Parameter[i2]==','){ if(bWrite) lstrcat(buffer,"+\",\"+"); else lstrcat(buffer,"+\"\t\"+"); } else if(Parameter[i2]==';'){ if(Parameter[i2+1]=='\0'){ sw=0; break; } if(bWrite) lstrcat(buffer,"+\",\"+"); else lstrcat(buffer,"+\" \"+"); } else if(Parameter[i2]=='\0') break; i2++; } if(sw) lstrcat(buffer,"+Ex\"\\r\\n\""); SUBINFO *psi; if(bFile) psi=GetSubHash("PRINT_ToFile"); else psi=GetSubHash("PRINT_ToPrompt"); if(!psi){ SetError(3,"Print",cp); return; } Opcode_CallProc(buffer,psi,0,"",0); } //////////// // ポインタ void OpcodeCallPtr(char *Parameter){ extern HANDLE hHeap; int i,i2,i3,num,types[255]; BOOL bCdecl; char szFuncPtr[VN_SIZE],temporary[VN_SIZE],*Parms[255]; //関数ポインタを取得 i=GetOneParameter(Parameter,0,szFuncPtr); if(lstrcmpi(szFuncPtr,"cdecl")==0){ //cdeclが指定された場合は、第2パラメータを関数ポインタとして扱う bCdecl=1; i=GetOneParameter(Parameter,i,szFuncPtr); } else bCdecl=0; if(Parameter[0]=='\0'){ SetError(10,"CallPtr",cp); } num=0; while(Parameter[i]){ i=GetOneParameter(Parameter,i,temporary); types[num]=DEF_LONG; for(i2=0;;i2++){ if(temporary[i2]=='\0') break; if(temporary[i2]==1&&temporary[i2+1]==ESC_AS){ LONG_PTR lp; types[num]=GetTypeFixed(temporary+i2+2,&lp); if(types[num]==DEF_OBJECT){ SetError(11,temporary+i2+2,cp); } temporary[i2]=0; break; } } Parms[num]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1); lstrcpy(Parms[num],temporary); num++; } int ParmSize=0; for(i=num-1;i>=0;i--){ //スタックへプッシュ i3=NumOpe(Parms[i],0,0,0); switch(types[i]){ case DEF_INT64: case DEF_QWORD: ChangeTypeToInt64(i3); break; case DEF_SINGLE: ChangeTypeToSingle(i3); break; case DEF_DOUBLE: ChangeTypeToDouble(i3); break; default: ChangeTypeToLong(i3); break; } ParmSize+=GetTypeSize(types[i],0); HeapDefaultFree(Parms[i]); } i3=NumOpe(szFuncPtr,0,0,0); ChangeTypeToLong(i3); //pop eax op_pop(REG_EAX); //call eax OpBuffer[obp++]=(char)0xFF; OpBuffer[obp++]=(char)0xD0; if(bCdecl){ //スタックを戻す //add esp,ParmSize op_add_esp(ParmSize); } } void OpcodeSetPtrData(char *Parameter,int type){ int i,i2; char temporary[VN_SIZE]; if(Parameter[0]=='('){ i=JumpStringInPare(Parameter,1); if(Parameter[i+1]=='\0'){ for(i=0;;i++){ Parameter[i]=Parameter[i+1]; if(Parameter[i]=='\0') break; } Parameter[i-1]=0; } } //第1パラメータを取得 i=GetOneParameter(Parameter,0,temporary); if(!Parameter[i]){ SetError(1,NULL,cp); return; } i2=NumOpe(temporary,0,0,0); ChangeTypeToLong(i2); //第2パラメータを取得 i=GetOneParameter(Parameter,i,temporary); if(Parameter[i]){ SetError(1,NULL,cp); return; } i2=NumOpe(temporary,0,0,0); if(type==DEF_DOUBLE){ ChangeTypeToDouble_ToFpuReg(i2); //pop eax op_pop(REG_EAX); //fstp qword ptr[eax] OpBuffer[obp++]=(char)0xDD; OpBuffer[obp++]=(char)0x18; } else if(type==DEF_SINGLE){ ChangeTypeToSingle(i2); //pop ebx op_pop(REG_EBX); //pop eax op_pop(REG_EAX); //mov dword ptr[eax],ebx OpBuffer[obp++]=(char)0x89; OpBuffer[obp++]=(char)0x18; } else if(type==DEF_QWORD){ ChangeTypeToInt64(i2); //pop ecx op_pop(REG_ECX); //pop ebx op_pop(REG_EBX); //pop eax op_pop(REG_EAX); //mov dword ptr[eax],ecx OpBuffer[obp++]=(char)0x89; OpBuffer[obp++]=(char)0x08; //mov dword ptr[eax+sizeof(long)],ebx OpBuffer[obp++]=(char)0x89; OpBuffer[obp++]=(char)0x58; OpBuffer[obp++]=(char)0x04; } else if(type==DEF_DWORD){ ChangeTypeToLong(i2); //pop ebx op_pop(REG_EBX); //pop eax op_pop(REG_EAX); //mov dword ptr[eax],ebx OpBuffer[obp++]=(char)0x89; OpBuffer[obp++]=(char)0x18; } else if(type==DEF_WORD){ ChangeTypeToLong(i2); //pop ebx op_pop(REG_EBX); //pop eax op_pop(REG_EAX); //mov word ptr[eax],bx OpBuffer[obp++]=(char)0x66; OpBuffer[obp++]=(char)0x89; OpBuffer[obp++]=(char)0x18; } else if(type==DEF_BYTE){ ChangeTypeToLong(i2); //pop ebx op_pop(REG_EBX); //pop eax op_pop(REG_EAX); //mov byte ptr[eax],bl OpBuffer[obp++]=(char)0x88; OpBuffer[obp++]=(char)0x18; } }