#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,"",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_OBJECT){ CClass *pobj_Class; pobj_Class=(CClass *)lp; //mov r14,rax op_mov_RR(REG_R14,REG_RAX); FreeTempObject(REG_R14,pobj_Class); } return; } ////////////////////////// // その他は代入演算を行う ////////////////////////// OpcodeCalc(Command); } void Judgment(char *buffer){ int reg=REG_RAX,type; type=NumOpe(®,buffer,0,0,0); int offset; if(type==DEF_DOUBLE){ double dbl=0; offset=AddDataTable((char *)&dbl,sizeof(double)); //comisd xmm0,qword ptr[data table offset] OpBuffer[obp++]=(char)0x66; OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x2F; OpBuffer[obp++]=(char)0x04; OpBuffer[obp++]=(char)0x25; *((long *)(OpBuffer+obp))=offset; pobj_DataTableSchedule->add(); obp+=sizeof(long); } else if(type==DEF_SINGLE){ float flt=0; offset=AddDataTable((char *)&flt,sizeof(float)); //comiss xmm0,dword ptr[data table offset] OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x2F; OpBuffer[obp++]=(char)0x04; OpBuffer[obp++]=(char)0x25; *((long *)(OpBuffer+obp))=offset; pobj_DataTableSchedule->add(); obp+=sizeof(long); } else{ //整数型 //cmp rax,0 op_cmp_value(GetTypeSize(type,-1),REG_RAX,0); } } void OpcodeIf(char *Parameter){ int i,i2,i3; 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; } } //条件式を実行してフラグをセット Judgment(Parameter); //je (endif、または else まで条件ジャンプ) OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x84; obp+=sizeof(long); //jeの番地 i3=obp; ///////////////////////// // If内をコード化 ///////////////////////// //レキシカルスコープをレベルアップ obj_LexScopes.LevelUp(obp); i2=CompileBuffer(ESC_ENDIF,0); //レキシカルスコープをレベルダウン obj_LexScopes.LevelDown(); 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.LevelUp(obp); CompileBuffer(ESC_ENDIF,0); //レキシカルスコープをレベルダウン obj_LexScopes.LevelDown(); *((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;ilock((int *)&dwTempContinue); pobj_TempSchedule->lock((int *)&dwContinueAddress); if(!Parameter[0]) SetError(10,"While",cp); //条件式を実行してフラグをセット Judgment(Parameter); //je (Wend まで) OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x84; obp+=sizeof(long); //実行中の番地 int je_schedule=obp; pobj_TempSchedule->lock(&je_schedule); //ExitWhileスケジュールの準備 lpdwTemp=pExitWhileSchedule; TempNum=ExitWhileScheduleNum; pExitWhileSchedule=(DWORD *)HeapAlloc(hHeap,0,1); ExitWhileScheduleNum=0; //レキシカルスコープをレベルアップ obj_LexScopes.LevelUp(obp); //While内をコンパイル CompileBuffer(0,COM_WEND); CallDestrouctorsOfScope(); //jmp ... OpBuffer[obp++]=(char)0xE9; *((long *)(OpBuffer+obp))=dwContinueAddress-(obp+sizeof(long)); obp+=sizeof(long); pobj_TempSchedule->unlock(); pobj_TempSchedule->unlock(); //ExitWhileスケジュール for(i2=0;i2unlock(); //Continueアドレスを復元 dwContinueAddress=dwTempContinue; } void OpcodeExitWhile(void){ extern DWORD *pExitWhileSchedule; extern int ExitWhileScheduleNum; extern HANDLE hHeap; if(!pExitWhileSchedule){ SetError(12,"Exit While",cp); return; } //jmp ...(Wend addr) OpBuffer[obp++]=(char)0xE9; pExitWhileSchedule=(DWORD *)HeapReAlloc(hHeap,0,pExitWhileSchedule,(ExitWhileScheduleNum+1)*sizeof(DWORD)); pExitWhileSchedule[ExitWhileScheduleNum]=obp; ExitWhileScheduleNum++; obp+=sizeof(long); } char szNextVariable[VN_SIZE]; void OpcodeFor(char *Parameter){ extern DWORD *pExitForSchedule; extern int ExitForScheduleNum; extern HANDLE hHeap; DWORD *lpdwTemp; int TempNum; int i,i2,i3; char temporary[VN_SIZE],variable[VN_SIZE],JudgeNum[VN_SIZE],StepNum[VN_SIZE]; //第1パラメータを取得 i=GetOneParameter(Parameter,0,temporary); if(!Parameter[i]){ SetError(12,"For",cp); goto ErrorStep; } for(i2=0;;i2++){ if(temporary[i2]=='='){ variable[i2]=0; //カウンタ初期化 OpcodeCalc(temporary); break; } if(temporary[i2]=='\0'){ SetError(12,"For",cp); goto ErrorStep; } variable[i2]=temporary[i2]; } //jmp ... OpBuffer[obp++]=(char)0xE9; i2=obp; obp+=sizeof(long); //Continueアドレスのバックアップとセット extern DWORD dwContinueAddress; DWORD dwTempContinue; dwTempContinue=dwContinueAddress; dwContinueAddress=obp; pobj_TempSchedule->lock((int *)&dwTempContinue); pobj_TempSchedule->lock((int *)&dwContinueAddress); //第2パラメータを取得(to〜) i=GetOneParameter(Parameter,i,JudgeNum); //第3パラメータを取得(step〜) if(Parameter[i]){ i=GetOneParameter(Parameter,i,StepNum); if(Parameter[i]) SetError(12,"For",cp); } else lstrcpy(StepNum,"1"); //カウンタを増加させる sprintf(temporary,"%s=(%s)+(%s)",variable,variable,StepNum); OpcodeCalc(temporary); *((long *)(OpBuffer+i2))=obp-(i2+sizeof(long)); //増加か減少かを区別する sprintf(temporary,"(%s)>=0",StepNum); int reg,type; reg=REG_RAX; type=NumOpe(®,temporary,0,0,0); //cmp rax,0 op_cmp_value(GetTypeSize(type,-1),REG_RAX,0); //je [カウンタ減少の場合の判定] OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x84; i2=obp; obp+=sizeof(long); //判定(カウンタ増加の場合) sprintf(temporary,"%s<=(%s)",variable,JudgeNum); reg=REG_RAX; type=NumOpe(®,temporary,0,0,0); //jmp [カウンタ減少の場合の判定を飛び越す] OpBuffer[obp++]=(char)0xE9; i3=obp; obp+=sizeof(long); *((long *)(OpBuffer+i2))=obp-(i2+sizeof(long)); //jeジャンプ先のオフセット値 //判定(カウンタ減少の場合) sprintf(temporary,"%s>=(%s)",variable,JudgeNum); reg=REG_RAX; type=NumOpe(®,temporary,0,0,0); *((long *)(OpBuffer+i3))=obp-(i3+sizeof(long)); //jmpジャンプ先のオフセット値 //cmp rax,0 op_cmp_value(GetTypeSize(type,-1),REG_RAX,0); ErrorStep: //je ... OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x84; int je_schedule=obp; obp+=sizeof(long); pobj_TempSchedule->lock(&je_schedule); //ExitForスケジュールの準備 lpdwTemp=pExitForSchedule; TempNum=ExitForScheduleNum; pExitForSchedule=(DWORD *)HeapAlloc(hHeap,0,1); ExitForScheduleNum=0; //レキシカルスコープをレベルアップ obj_LexScopes.LevelUp(obp); //For内をコンパイル CompileBuffer(0,COM_NEXT); CallDestrouctorsOfScope(); 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); pobj_TempSchedule->unlock(); pobj_TempSchedule->unlock(); //ExitForスケジュール for(i=0;iunlock(); //Continueアドレスを復元 dwContinueAddress=dwTempContinue; } void OpcodeExitFor(void){ extern DWORD *pExitForSchedule; extern int ExitForScheduleNum; extern HANDLE hHeap; if(!pExitForSchedule){ SetError(12,"Exit For",cp); return; } //jmp ...(Next addr) OpBuffer[obp++]=(char)0xE9; pExitForSchedule=(DWORD *)HeapReAlloc(hHeap,0,pExitForSchedule,(ExitForScheduleNum+1)*sizeof(DWORD)); pExitForSchedule[ExitForScheduleNum]=obp; ExitForScheduleNum++; obp+=sizeof(long); } void OpcodeDo(char *Parameter){ extern DWORD *pExitDoSchedule; extern int ExitDoScheduleNum; extern HANDLE hHeap; int i,i2,i3; DWORD *lpdwTemp; int TempNum; if(Parameter[0]) SetError(10,"Do",cp); //ExitDoスケジュールの準備 lpdwTemp=pExitDoSchedule; TempNum=ExitDoScheduleNum; pExitDoSchedule=(DWORD *)HeapAlloc(hHeap,0,1); ExitDoScheduleNum=0; //Continueアドレスのバックアップとセット extern DWORD dwContinueAddress; DWORD dwTempContinue; dwTempContinue=dwContinueAddress; dwContinueAddress=obp; pobj_TempSchedule->lock((int *)&dwTempContinue); pobj_TempSchedule->lock((int *)&dwContinueAddress); //レキシカルスコープをレベルアップ obj_LexScopes.LevelUp(obp); //Do内をコンパイル CompileBuffer(0,COM_LOOP); CallDestrouctorsOfScope(); 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]; } //条件式を実行してフラグをセット Judgment(temporary); 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); pobj_TempSchedule->unlock(); pobj_TempSchedule->unlock(); //jmp ... OpBuffer[obp++]=(char)0xE9; int je_schedule=obp; obp+=sizeof(long); pobj_TempSchedule->lock(&je_schedule); //ExitDoスケジュール for(i=0;iunlock(); //Continueアドレスを復元 dwContinueAddress=dwTempContinue; } void OpcodeExitDo(void){ extern HANDLE hHeap; extern DWORD *pExitDoSchedule; extern int ExitDoScheduleNum; if(!pExitDoSchedule){ SetError(12,"Exit Do",cp); return; } //jmp ...(Loop addr) OpBuffer[obp++]=(char)0xE9; pExitDoSchedule=(DWORD *)HeapReAlloc(hHeap,0,pExitDoSchedule,(ExitDoScheduleNum+1)*sizeof(DWORD)); pExitDoSchedule[ExitDoScheduleNum]=obp; ExitDoScheduleNum++; obp+=sizeof(long); } 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; } //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++; } void OpcodeSelect(char *Parameter){ extern DWORD *pCaseSchedule; extern int CaseScheduleNum; extern int NowCaseSchedule; extern HANDLE hHeap; extern char *basbuf; int i,i2,i3,NowCaseCp; char temporary[VN_SIZE]; DWORD *temp_pCaseSchedule; int temp_CaseScheduleNum; int temp_NowCaseSchedule; temp_pCaseSchedule=pCaseSchedule; temp_CaseScheduleNum=CaseScheduleNum; temp_NowCaseSchedule=NowCaseSchedule; pCaseSchedule=(DWORD *)HeapAlloc(hHeap,0,1); CaseScheduleNum=0; NowCaseSchedule=0; int reg1=REG_RAX,type1; LONG_PTR lpIndex; type1=NumOpe(®1,Parameter,0,0,&lpIndex); if(type1==DEF_DOUBLE){ //movsd qword ptr[rsp+offset],xmm_reg ※スタックフレームを利用 pobj_sf->push(reg1,sizeof(double)); } else if(type1==DEF_SINGLE){ //movss dword ptr[rsp+offset],xmm_reg ※スタックフレームを利用 pobj_sf->push(reg1,sizeof(float)); } else{ ExtendTypeTo64(type1,reg1); //mov qword ptr[rsp+offset],reg ※スタックフレームを利用 pobj_sf->push(reg1); } for(i=cp;;i++){ if(basbuf[i]=='\0'){ HeapDefaultFree(pCaseSchedule); pCaseSchedule=temp_pCaseSchedule; CaseScheduleNum=temp_CaseScheduleNum; NowCaseSchedule=temp_NowCaseSchedule; 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) 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; int reg2=REG_RDX,type2; LONG_PTR lpIndex2; type2=NumOpe(®2,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; int iParmNum=0; //_System_LocalThis ppi=(PARAMETER_INFO *)HeapAlloc(hHeap,0,sizeof(PARAMETER_INFO)*3); ppi[iParmNum].bArray=0; ppi[iParmNum].bByVal=0; ppi[iParmNum].name=0; ppi[iParmNum].type=DEF_PTR_VOID; ppi[iParmNum].u.index=-1; ppi[iParmNum].SubScripts[0]=-1; iParmNum++; 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; } //実体オブジェクト if(reg2!=REG_RDX){ //mov rdx,reg2 op_mov_RR(REG_RDX,reg2); } //mov rcx,qword ptr[rsp+offset] ※スタックフレームから参照 pobj_sf->ref(REG_RCX); //call operator_proc ※ ==演算子 op_call(psi); //test rax,rax op_test(REG_RAX,REG_RAX); //jne ... OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x85; } else{ if(type1==DEF_DOUBLE){ int xmm_reg; if(IsXmmReg(reg2)) xmm_reg=reg2; else xmm_reg=REG_XMM5; ChangeTypeToXmm_Double(type2,xmm_reg,reg2); //movsd xmm4,qword ptr[rsp+offset] ※スタックフレームから参照 pobj_sf->ref(REG_XMM4,sizeof(double)); //comiss xmm_reg1,xmm_reg2 op_comisd(xmm_reg,REG_XMM4); } else if(type1==DEF_SINGLE){ int xmm_reg; if(IsXmmReg(reg2)) xmm_reg=reg2; else xmm_reg=REG_XMM5; ChangeTypeToXmm_Single(type2,xmm_reg,reg2); //movss xmm4,dword ptr[rsp+offset] ※スタックフレームから参照 pobj_sf->ref(REG_XMM4,sizeof(float)); //comiss xmm_reg1,xmm_reg2 op_comiss(xmm_reg,REG_XMM4); } else{ //その他整数型 i2=NeutralizationType(type1,-1,type2,-1); //mov r14,qword ptr[rsp+offset] ※スタックフレームから参照 pobj_sf->ref(REG_R14); //cmp reg2,r14 op_cmp_reg(GetTypeSize(i2,-1),reg2,REG_R14); } //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){ //jmp ... OpBuffer[obp++]=(char)0xE9; AddCaseSchedule(); obp+=sizeof(long); } } //スタックフレームを1スペースだけ解除 pobj_sf->pop(REG_NON); //レキシカルスコープをレベルアップ obj_LexScopes.LevelUp(obp); //Select Case内をコンパイル CompileBuffer(ESC_ENDSELECT,0); //jmp EndSelect OpBuffer[obp++]=(char)0xE9; AddCaseSchedule(); obp+=sizeof(long); //最終スケジュール for(i=NowCaseSchedule;ipush(REG_RAX); if(Parameter[0]=='*'){ i=GetLabelAddress(Parameter+1,0); //jmp ... OpBuffer[obp++]=(char)0xE9; if(i==-1){ pGotoLabelSchedule=(GOTOLABELSCHEDULE *)HeapReAlloc(hHeap,0,pGotoLabelSchedule,(GotoLabelScheduleNum+1)*sizeof(GOTOLABELSCHEDULE)); pGotoLabelSchedule[GotoLabelScheduleNum].pName=(char *)HeapAlloc(hHeap,0,lstrlen(Parameter+1)+1); lstrcpy(pGotoLabelSchedule[GotoLabelScheduleNum].pName,Parameter+1); pGotoLabelSchedule[GotoLabelScheduleNum].pos=obp; pGotoLabelSchedule[GotoLabelScheduleNum].now_cp=cp; GotoLabelScheduleNum++; } *((long *)(OpBuffer+obp))=i-(obp+sizeof(long)); obp+=sizeof(long); } else{ LineNum=atoi(Parameter); i=GetLabelAddress(0,LineNum); //jmp ... OpBuffer[obp++]=(char)0xE9; if(i==-1){ pGotoLabelSchedule=(GOTOLABELSCHEDULE *)HeapReAlloc(hHeap,0,pGotoLabelSchedule,(GotoLabelScheduleNum+1)*sizeof(GOTOLABELSCHEDULE)); pGotoLabelSchedule[GotoLabelScheduleNum].pName=0; pGotoLabelSchedule[GotoLabelScheduleNum].line=LineNum; pGotoLabelSchedule[GotoLabelScheduleNum].pos=obp; pGotoLabelSchedule[GotoLabelScheduleNum].now_cp=cp; GotoLabelScheduleNum++; } *((long *)(OpBuffer+obp))=i-(obp+sizeof(long)); obp+=sizeof(long); } *((long *)(OpBuffer+schedule2))=obp-schedule; //※スタックフレームを元に戻す pobj_sf->pop(REG_NON); SetError(-1,"Gosub 〜 Returnステートメントは64ビットコンパイラで利用することはできません。",cp); } void OpcodeReturn(char *Parameter){ extern BOOL bCompilingGlobal; if(bCompilingGlobal){ //Gosub〜Returnとして扱う //mov rax,qword ptr[rsp+offset] ※スタックフレームを利用 pobj_sf->push(REG_NON); pobj_sf->ref(REG_RAX); pobj_sf->pop(REG_NON); //jmp rax OpBuffer[obp++]=(char)0xFF; OpBuffer[obp++]=(char)0xE0; } else{ //戻り値をセット if(Parameter[0]){ extern SUBINFO *pCompilingSubInfo; char *temp; if(pCompilingSubInfo->name[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,"",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,"",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,"",0); } //////////// // ポインタ //////////// 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; } int reg_ptr=REG_RAX; i2=NumOpe(®_ptr,temporary,0,0,0); if(!IsWholeNumberType(i2)){ SetError(11,Parameter,cp); return; } //結果を格納しているレジスタをブロッキング pobj_BlockReg->lock(reg_ptr); //第2パラメータを取得 i=GetOneParameter(Parameter,i,temporary); if(Parameter[i]){ SetError(1,NULL,cp); return; } int temp_reg=REG_NON; i2=NumOpe(&temp_reg,temporary,0,0,0); //レジスタのブロッキングを解除 pobj_BlockReg->clear(); if(type==DEF_DOUBLE){ ChangeTypeToXmm_Double(i2,REG_XMM0,temp_reg); //movsd qword ptr[reg_ptr],xmm0 op_movsd_MR(REG_XMM0,reg_ptr,0,MOD_BASE); } else if(type==DEF_SINGLE){ ChangeTypeToXmm_Single(i2,REG_XMM0,temp_reg); //movss dword ptr[reg_ptr],xmm0 op_movss_MR(REG_XMM0,reg_ptr,0,MOD_BASE); } else{ ChangeTypeToWhole(i2,type,REG_RCX,temp_reg); //mov ptr[reg_ptr],rcx op_mov_MR(GetTypeSize(type,-1),REG_RCX,reg_ptr,0,MOD_BASE); } }