#include "stdafx.h" #include #include "../BasicCompiler_Common/common.h" #include "Opcode.h" void OpcodeOthers(const char *Command){ int i,i2; char leftTerm[8192]; int lastParePos = 0; for(i=0;;i++){ if(Command[i]=='\"'){ //ダブルクォートは不正なのでエラー扱い leftTerm[i]=0; compiler.errorMessenger.Output(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) )){ compiler.errorMessenger.Output(1,NULL,cp); return; } if(Command[i]=='\0' && lastParePos == 0){ ////////////////////////////// // パラメータ無しのマクロ検索 ////////////////////////////// const UserProc *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() ){ compiler.errorMessenger.Output(10,Command,cp); } Opcode_CallProc("",pUserProc,0,""); return; } } else if(IsNumCalcMark(Command,i)){ //代入演算 OpcodeCalc(Command); return; } if( pobj_reg ){ compiler.errorMessenger.OutputFatalError(); } pobj_reg=new CRegister(REG_RAX); Type resultType; bool isLiteral, isNeedHeapFreeStructure = false; bool result = TermOpe( leftTerm, Type(), resultType, isLiteral, isNeedHeapFreeStructure, NULL, true ); delete pobj_reg; pobj_reg = NULL; if( result ){ ///////////////////// // 戻り値の処理 ///////////////////// if( resultType.IsStruct() ){ //mov r14,rax compiler.codeGenerator.op_mov_RR(REG_R14,REG_RAX); FreeTempObject(REG_R14,&resultType.GetClass()); } return; } // どこにも当てはまらなかったため、失敗 compiler.errorMessenger.Output(1,NULL,cp); } void Judgment(char *buffer){ int reg=REG_RAX; Type resultType; bool isNeedHeapFreeStructure; if( !NumOpe(®,buffer,Type(DEF_BOOLEAN),resultType, &isNeedHeapFreeStructure) ){ return; } if( resultType.IsObject() ) { // Boolean型にキャストする Type booleanType( DEF_BOOLEAN ); CallCastOperatorProc( reg, resultType, isNeedHeapFreeStructure, booleanType ); resultType = booleanType; } int offset; if(resultType.IsDouble()){ double dbl=0; offset=compiler.GetObjectModule().dataTable.Add( dbl ); //comisd xmm0,qword ptr[data table offset] compiler.codeGenerator.PutOld( (char)0x66, (char)0x0F, (char)0x2F, (char)0x04, (char)0x25 ); compiler.codeGenerator.PutOld( (long)offset, Schedule::DataTable ); } else if(resultType.IsSingle()){ float flt=0; offset=compiler.GetObjectModule().dataTable.Add( flt ); //comiss xmm0,dword ptr[data table offset] compiler.codeGenerator.PutOld( (char)0x0F, (char)0x2F, (char)0x04, (char)0x25 ); compiler.codeGenerator.PutOld( (long)offset, Schedule::DataTable ); } else{ //整数型 //cmp rax,0 compiler.codeGenerator.op_cmp_value(resultType.GetSize(),REG_RAX,0); } } void OpcodeIf(char *Parameter){ for(int i=0;;i++){ if(Parameter[i]=='\0'){ compiler.errorMessenger.Output(21,NULL,cp); return; } if(Parameter[i]==1&&Parameter[i+1]==ESC_THEN){ Parameter[i]=0; break; } } //条件式を実行してフラグをセット Judgment(Parameter); //je (endif、または else まで条件ジャンプ) const PertialSchedule *pIfPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true ); ///////////////////////// // If内をコード化 ///////////////////////// //レキシカルスコープをレベルアップ compiler.codeGenerator.lexicalScopes.Start( compiler.codeGenerator.GetNativeCodeSize(), LexicalScope::SCOPE_TYPE_IF ); int i2=CompileBuffer(ESC_ENDIF,0); //レキシカルスコープをレベルダウン compiler.codeGenerator.lexicalScopes.End(); if(i2==ESC_ELSE){ //jmp (endifまで) const PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true ); compiler.codeGenerator.opfix_JmpPertialSchedule( pIfPertialSchedule ); ///////////////////////// // Else内をコード化 ///////////////////////// //レキシカルスコープをレベルアップ compiler.codeGenerator.lexicalScopes.Start( compiler.codeGenerator.GetNativeCodeSize(), LexicalScope::SCOPE_TYPE_IF ); CompileBuffer(ESC_ENDIF,0); //レキシカルスコープをレベルダウン compiler.codeGenerator.lexicalScopes.End(); compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule ); } else{ compiler.codeGenerator.opfix_JmpPertialSchedule( pIfPertialSchedule ); } } int GetLabelAddress(char *LabelName,int LineNum){ if(LabelName){ BOOST_FOREACH( const GotoLabel &label, compiler.codeGenerator.gotoLabels ) { if( label.name.size() > 0 ) { if( label.name == LabelName ) { return label.address; } } } } else{ BOOST_FOREACH( const GotoLabel &label, compiler.codeGenerator.gotoLabels ) { if( label.name.size() == 0 ) { if( label.line == LineNum ) { return label.address; } } } } return -1; } void OpcodeGoto(char *Parameter){ extern HANDLE hHeap; int i,LineNum; if(Parameter[0]=='*'){ i=GetLabelAddress(Parameter+1,0); if( i == -1 ) { //jmp ...(schedule) compiler.codeGenerator.op_jmp_goto_schedule( (const std::string)(Parameter + 1), 0, cp ); } else { //jmp ... compiler.codeGenerator.op_jmp( i-compiler.codeGenerator.GetNativeCodeSize(), sizeof(long), false, true ); } } else{ LineNum=atoi(Parameter); i=GetLabelAddress(0,LineNum); if( i == -1 ) { //jmp ...(schedule) compiler.codeGenerator.op_jmp_goto_schedule( "", LineNum, cp ); } else { //jmp ... compiler.codeGenerator.op_jmp( i-compiler.codeGenerator.GetNativeCodeSize(), sizeof(long), false, true ); } } } void OpcodeWhile(char *Parameter){ extern HANDLE hHeap; //Continueアドレスのバックアップとセット compiler.codeGenerator.ContinueAreaBegin(); if(!Parameter[0]) compiler.errorMessenger.Output(10,"While",cp); //条件式を実行してフラグをセット Judgment(Parameter); //je (Wend まで) const PertialSchedule *pWhilePertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true ); //レキシカルスコープをレベルアップ compiler.codeGenerator.lexicalScopes.Start( compiler.codeGenerator.GetNativeCodeSize(), LexicalScope::SCOPE_TYPE_WHILE ); //While内をコンパイル CompileBuffer(0,COM_WEND); compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd(); //jmp ... compiler.codeGenerator.op_jmp_continue(); //レキシカルスコープをレベルダウン compiler.codeGenerator.lexicalScopes.End(); compiler.codeGenerator.opfix_JmpPertialSchedule( pWhilePertialSchedule ); //Continueアドレスを復元 compiler.codeGenerator.ContinueAreaEnd(); } char szNextVariable[VN_SIZE]; void OpcodeFor(char *Parameter){ extern HANDLE hHeap; Type resultType; int i,i2; char temporary[VN_SIZE],variable[VN_SIZE],JudgeNum[VN_SIZE],StepNum[VN_SIZE]; bool isError = false; //第1パラメータを取得 i=GetOneParameter(Parameter,0,temporary); if(!Parameter[i]){ compiler.errorMessenger.Output(12,"For",cp); isError = true; goto ErrorStep; } for(i2=0;;i2++){ if(temporary[i2]=='='){ variable[i2]=0; //カウンタ初期化 OpcodeCalc(temporary); break; } if(temporary[i2]=='\0'){ compiler.errorMessenger.Output(12,"For",cp); isError = true; goto ErrorStep; } variable[i2]=temporary[i2]; } //jmp ... const PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true ); //Continueアドレスのバックアップとセット compiler.codeGenerator.ContinueAreaBegin(); //第2パラメータを取得(to〜) i=GetOneParameter(Parameter,i,JudgeNum); //第3パラメータを取得(step〜) if(Parameter[i]){ i=GetOneParameter(Parameter,i,StepNum); if(Parameter[i]) compiler.errorMessenger.Output(12,"For",cp); } else lstrcpy(StepNum,"1"); //カウンタを増加させる sprintf(temporary,"%s=(%s)+(%s)",variable,variable,StepNum); OpcodeCalc(temporary); compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule ); //増加か減少かを区別する sprintf(temporary,"(%s)>=0",StepNum); int reg; reg=REG_RAX; if( !NumOpe(®,temporary,Type(),resultType) ){ return; } //cmp rax,0 compiler.codeGenerator.op_cmp_value(resultType.GetSize(),REG_RAX,0); //je [カウンタ減少の場合の判定] pTempPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true ); //判定(カウンタ増加の場合) sprintf(temporary,"%s<=(%s)",variable,JudgeNum); reg=REG_RAX; NumOpe(®,temporary,Type(),Type()); //jmp [カウンタ減少の場合の判定を飛び越す] const PertialSchedule *pTempPertialSchedule2 = compiler.codeGenerator.op_jmp( 0, sizeof(long), true ); //jeジャンプ先のオフセット値 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule ); //判定(カウンタ減少の場合) sprintf(temporary,"%s>=(%s)",variable,JudgeNum); reg=REG_RAX; NumOpe(®,temporary,Type(),resultType); //jmpジャンプ先のオフセット値 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule2 ); //cmp rax,0 compiler.codeGenerator.op_cmp_value(resultType.GetSize(),REG_RAX,0); ErrorStep: //je ... pTempPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true ); //レキシカルスコープをレベルアップ compiler.codeGenerator.lexicalScopes.Start( compiler.codeGenerator.GetNativeCodeSize(), LexicalScope::SCOPE_TYPE_FOR ); //For内をコンパイル CompileBuffer(0,COM_NEXT); compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd(); if(szNextVariable[0]){ if(lstrcmp(szNextVariable,variable)!=0){ compiler.errorMessenger.Output(55,szNextVariable,cp); } } //jmp ... compiler.codeGenerator.op_jmp_continue(); //レキシカルスコープをレベルダウン compiler.codeGenerator.lexicalScopes.End(); //jeジャンプ先のオフセット値 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule ); //Continueアドレスを復元 compiler.codeGenerator.ContinueAreaEnd(); } void OpcodeForeach( const char *Parameter ) { Type resultType; char temporary[VN_SIZE],variable[VN_SIZE],collectionVar[VN_SIZE]; bool isError = false; std::string elementTypeName; //第1パラメータを取得 int i = 0; GetCustomToken( variable, Parameter, i, ESC_IN, true ); if(!Parameter[i]){ compiler.errorMessenger.Output(12,"Foreach",cp); isError = true; goto ErrorStep; } i++; //第2パラメータを取得(in〜) lstrcpy( collectionVar, Parameter + i ); Exception::TryCommand(); //Finallyで_System_ForeachEnumerator.Disposeするため //Enumeratorの取得 sprintf(temporary,"_System_ForeachEnumerator=%s.GetEnumerator()", collectionVar ); OpcodeDim(temporary,DIMFLAG_INITDEBUGVAR); //レキシカルスコープをレベルアップ compiler.codeGenerator.lexicalScopes.Start( compiler.codeGenerator.GetNativeCodeSize(), LexicalScope::SCOPE_TYPE_FOR ); { Type collectionType; if( !NumOpe_GetType( collectionVar, Type(), collectionType ) ) { isError = true; goto ErrorStep; } elementTypeName = collectionType.GetActualGenericType(0).GetClass().GetFullName(); } if( !GetVarType( variable, resultType, false ) ) { // 未定義の場合は自動的に定義する sprintf(temporary,"%s=Nothing%c%c%s", variable, 1, ESC_AS, elementTypeName.c_str() ); OpcodeDim(temporary,DIMFLAG_INITDEBUGVAR); } //Continueアドレスのバックアップとセット compiler.codeGenerator.ContinueAreaBegin(); // MoveNextメソッドを呼び出す int reg = REG_RAX; NumOpe( ®, "_System_ForeachEnumerator.MoveNext()", Type(), resultType ); //cmp rax,0 compiler.codeGenerator.op_cmp_value(resultType.GetSize(),REG_RAX,0); ErrorStep: //je ... const PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true ); if( !isError ) { // Currentプロパティから現在の値を取得 sprintf( temporary, "%s=_System_ForeachEnumerator.Current%c%c%s", variable, 1, ESC_AS, elementTypeName.c_str() ); Compile( temporary ); } //For内をコンパイル CompileBuffer(0,COM_NEXT); compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd(); if(szNextVariable[0]){ if(lstrcmp(szNextVariable,variable)!=0){ compiler.errorMessenger.Output(55,szNextVariable,cp); } } if( !isError ) { //jmp ... compiler.codeGenerator.op_jmp_continue(); } //レキシカルスコープをレベルダウン compiler.codeGenerator.lexicalScopes.End(); //jeジャンプ先のオフセット値 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule ); //Disposeを呼んでTryスコープを終える Exception::FinallyCommand(); Compile( "_System_ForeachEnumerator.Dispose()" ); Exception::EndTryCommand(); //Continueアドレスを復元 compiler.codeGenerator.ContinueAreaEnd(); } void OpcodeDo(char *Parameter){ extern HANDLE hHeap; int i,i2,i3; if(Parameter[0]) compiler.errorMessenger.Output(10,"Do",cp); //Continueアドレスのバックアップとセット compiler.codeGenerator.ContinueAreaBegin(); //レキシカルスコープをレベルアップ compiler.codeGenerator.lexicalScopes.Start( compiler.codeGenerator.GetNativeCodeSize(), LexicalScope::SCOPE_TYPE_DO ); //Do内をコンパイル CompileBuffer(0,COM_LOOP); compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd(); const PertialSchedule *pDoPertialSchedule = NULL; 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(ループ終了) pDoPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(char), true ); } else if(basbuf[i3]=='1'){ //Until //jne 5(ループ終了) pDoPertialSchedule = compiler.codeGenerator.op_jne( 0, sizeof(char), true ); } break; } } //jmp ... compiler.codeGenerator.op_jmp_continue(); if( pDoPertialSchedule ) { compiler.codeGenerator.opfix_JmpPertialSchedule( pDoPertialSchedule ); } //jmp ... const PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true ); //レキシカルスコープをレベルダウン compiler.codeGenerator.lexicalScopes.End(); //jmpジャンプ先のオフセット値 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule ); //Continueアドレスを復元 compiler.codeGenerator.ContinueAreaEnd(); } void OpcodeContinue(void){ //jmp ...(Continue addr) compiler.codeGenerator.op_jmp_continue(); } void OpcodeExitSub(void){ if( compiler.IsGlobalAreaCompiling() ){ compiler.errorMessenger.Output(12,"Exit Sub/Function",cp); return; } //未解放のローカルオブジェクトのデストラクタを呼び出す compiler.codeGenerator.lexicalScopes.CallDestructorsOfReturn(); //jmp ...(End Sub/Function) compiler.codeGenerator.op_jmp_exitsub(); } //Caseスケジュール class SelectSchedule { public: SelectSchedule( int typeSize ) : typeSize( typeSize ) , nowCaseSchedule( 0 ) { } PertialSchedules casePertialSchedules; int typeSize; int nowCaseSchedule; }; std::vector selectSchedules; void OpcodeSelect( const char *lpszParms ) { extern HANDLE hHeap; extern char *basbuf; int i,i2,i3,NowCaseCp; char temporary[VN_SIZE]; int reg1=REG_RAX; Type type1; bool result = NumOpe(®1,lpszParms,Type(), type1 ); selectSchedules.push_back( SelectSchedule( type1.GetSize() ) ); if( result ) { if( selectSchedules.back().typeSize < sizeof(long) ){ selectSchedules.back().typeSize = sizeof(long); } if(type1.IsDouble()){ //movsd qword ptr[rsp+offset],xmm_reg ※スタックフレームを利用 pobj_sf->push(reg1,sizeof(double)); } else if(type1.IsSingle()){ //movss dword ptr[rsp+offset],xmm_reg ※スタックフレームを利用 pobj_sf->push(reg1,sizeof(float)); } else{ ExtendTypeTo64(type1.GetBasicType(),reg1); //mov qword ptr[rsp+offset],reg ※スタックフレームを利用 pobj_sf->push(reg1); } for(i=cp;;i++){ if(basbuf[i]=='\0'){ selectSchedules.pop_back(); compiler.errorMessenger.Output(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; Type type2; if( !NumOpe(®2,temporary,type1,type2) ){ return; } cp=i2; if(type1.IsObject()){ std::vector subs; type1.GetClass().GetDynamicMethods().Enum( CALC_EQUAL, subs ); if( subs.size() == 0 ){ return; } Parameters params; params.push_back( new Parameter( "", Type( type2 ) ) ); //オーバーロードを解決 const UserProc *pUserProc = OverloadSolution( "==", subs, params, Type( DEF_BOOLEAN ), type1 ); delete params[0]; if(!pUserProc){ //エラー return; } //実体オブジェクト if(reg2!=REG_RDX){ //mov rdx,reg2 compiler.codeGenerator.op_mov_RR(REG_RDX,reg2); } //mov rcx,qword ptr[rsp+offset] ※スタックフレームから参照 pobj_sf->ref(REG_RCX); //call operator_proc ※ ==演算子 compiler.codeGenerator.op_call(pUserProc); //test rax,rax compiler.codeGenerator.op_test(REG_RAX,REG_RAX); //jne ... selectSchedules.back().casePertialSchedules.push_back( compiler.codeGenerator.op_jne( 0, sizeof(long), true ) ); } else{ if(type1.IsDouble()){ int xmm_reg; if(IsXmmReg(reg2)) xmm_reg=reg2; else xmm_reg=REG_XMM5; ChangeTypeToXmm_Double(type2.GetBasicType(),xmm_reg,reg2); //movsd xmm4,qword ptr[rsp+offset] ※スタックフレームから参照 pobj_sf->ref(REG_XMM4,sizeof(double)); //comiss xmm_reg1,xmm_reg2 compiler.codeGenerator.op_comisd(xmm_reg,REG_XMM4); } else if(type1.IsSingle()){ int xmm_reg; if(IsXmmReg(reg2)) xmm_reg=reg2; else xmm_reg=REG_XMM5; ChangeTypeToXmm_Single(type2.GetBasicType(),xmm_reg,reg2); //movss xmm4,dword ptr[rsp+offset] ※スタックフレームから参照 pobj_sf->ref(REG_XMM4,sizeof(float)); //comiss xmm_reg1,xmm_reg2 compiler.codeGenerator.op_comiss(xmm_reg,REG_XMM4); } else{ //その他整数型 i2=NeutralizationType(type1.GetBasicType(),-1,type2.GetBasicType(),-1); //mov r14,qword ptr[rsp+offset] ※スタックフレームから参照 pobj_sf->ref(REG_R14); //cmp reg2,r14 compiler.codeGenerator.op_cmp_reg(Type(i2).GetSize(),reg2,REG_R14); } //je ... selectSchedules.back().casePertialSchedules.push_back( compiler.codeGenerator.op_je( 0, sizeof(long), true ) ); } if(basbuf[i]!=',') break; } } if(basbuf[i]==1&&basbuf[i+1]==ESC_CASEELSE){ //jmp ... selectSchedules.back().casePertialSchedules.push_back( compiler.codeGenerator.op_jmp( 0, sizeof(long), true ) ); } } //スタックフレームを1スペースだけ解除 pobj_sf->pop(REG_NON); } //レキシカルスコープをレベルアップ compiler.codeGenerator.lexicalScopes.Start( compiler.codeGenerator.GetNativeCodeSize(), LexicalScope::SCOPE_TYPE_SELECT ); //Select Case内をコンパイル CompileBuffer(ESC_ENDSELECT,0); //jmp EndSelect selectSchedules.back().casePertialSchedules.push_back( compiler.codeGenerator.op_jmp( 0, sizeof(long), true ) ); //最終スケジュール for(i=selectSchedules.back().nowCaseSchedule;i<(int)selectSchedules.back().casePertialSchedules.size();i++){ compiler.codeGenerator.opfix_JmpPertialSchedule( selectSchedules.back().casePertialSchedules[i] ); } //レキシカルスコープをレベルダウン compiler.codeGenerator.lexicalScopes.End(); selectSchedules.pop_back(); } void OpcodeCase(char *Parameter){ int i; if(selectSchedules.back().typeSize==-1){ compiler.errorMessenger.Output(30,"Case",cp); return; } //jmp EndSelect selectSchedules.back().casePertialSchedules.push_back( compiler.codeGenerator.op_jmp( 0, sizeof(long), true ) ); i=0; while(1){ //Caseスケジュール compiler.codeGenerator.opfix_JmpPertialSchedule( selectSchedules.back().casePertialSchedules[selectSchedules.back().nowCaseSchedule] ); selectSchedules.back().nowCaseSchedule++; i=JumpOneParameter(Parameter,i); if(Parameter[i]=='\0') break; } } void OpcodeGosub(char *Parameter){ compiler.errorMessenger.Output(-1,"Gosub 〜 Returnステートメントは64ビットコンパイラで利用することはできません。",cp); } void OpcodeReturn(char *Parameter){ if( compiler.IsGlobalAreaCompiling() ){ compiler.errorMessenger.Output(62,NULL,cp); } else{ //戻り値をセット if(Parameter[0]){ const UserProc &proc = compiler.GetCompilingUserProc(); const char *temp = "_System_ReturnValue"; if(proc.GetName()[0]==1&&proc.GetName()[1]==ESC_OPERATOR) { } else{ temp=proc.GetName().c_str(); } char temporary[VN_SIZE]; sprintf(temporary,"%s=%s",temp,Parameter); OpcodeCalc(temporary); } //プロシージャを抜け出す(C言語のreturnと同様の処理を行う) OpcodeExitSub(); } } //////////// // ポインタ //////////// void OpcodeSetPtrData(char *Parameter,int type){ int i; 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]){ compiler.errorMessenger.Output(1,NULL,cp); return; } int reg_ptr=REG_RAX; Type resultType; if( !NumOpe(®_ptr,temporary,Type(),resultType) ){ return; } if(!resultType.IsWhole()){ compiler.errorMessenger.Output(11,Parameter,cp); return; } //結果を格納しているレジスタをブロッキング pobj_BlockReg->lock(reg_ptr); //第2パラメータを取得 i=GetOneParameter(Parameter,i,temporary); if(Parameter[i]){ compiler.errorMessenger.Output(1,NULL,cp); return; } int temp_reg=REG_NON; if( !NumOpe(&temp_reg,temporary,Type(),resultType) ){ return; } //レジスタのブロッキングを解除 pobj_BlockReg->clear(); if(type==DEF_DOUBLE){ ChangeTypeToXmm_Double(resultType.GetBasicType(),REG_XMM0,temp_reg); //movsd qword ptr[reg_ptr],xmm0 compiler.codeGenerator.op_movsd_MR(REG_XMM0,reg_ptr,0,MOD_BASE); } else if(type==DEF_SINGLE){ ChangeTypeToXmm_Single(resultType.GetBasicType(),REG_XMM0,temp_reg); //movss dword ptr[reg_ptr],xmm0 compiler.codeGenerator.op_movss_MR(REG_XMM0,reg_ptr,0,MOD_BASE); } else{ ChangeTypeToWhole(resultType,Type(type),REG_RCX,temp_reg); //mov ptr[reg_ptr],rcx compiler.codeGenerator.op_mov_MR(Type(type).GetSize(),REG_RCX,reg_ptr,0,MOD_BASE); } }