#include "stdafx.h" #include #include "../BasicCompiler_Common/common.h" #include "Opcode.h" void SetVariableFromRax( const Type &varType, int CalcType,RELATIVE_VAR *pRelativeVar){ ///////////////////////////////////////////////// // raxの内容を変数にコピーするコードを抽出 ///////////////////////////////////////////////// if( varType.IsBoolean() ) { //bool SetBooleanVariable(CalcType,pRelativeVar); } else if( varType.IsReal() ) { // Double/Single型変数へレジスタの値を代入 SetRealVariable(varType.GetBasicType(), CalcType, pRelativeVar); } else if( varType.IsWhole() || varType.IsObject() ) { //整数変数へraxの値を格納する SetWholeVariable( varType.GetSize(), CalcType, pRelativeVar ); } else{ compiler.errorMessenger.Output(300,NULL,cp); } } void OpcodeCalc(const char *Command){ int i,i2,i3; char variable[VN_SIZE]; ////////////////////////////////////// // インクリメント・デクリメント ////////////////////////////////////// for(i=0;;i++){ if(Command[i]=='\"'){ //ダブルクォートは不正なのでエラー扱い variable[i]=0; compiler.errorMessenger.Output(3,variable,cp); return; } if(Command[i]=='('){ i2=GetStringInPare(variable+i,Command+i); i+=i2-1; continue; } if(Command[i]=='['){ i2=GetStringInBracket(variable+i,Command+i); i+=i2-1; continue; } if(Command[i]=='\0'){ /////////////////////////////////// // インクリメント・デクリメント /////////////////////////////////// if(i>2){ if(Command[i-2]=='+'&&Command[i-1]=='+'){ //インクリメント variable[i-2]=0; IncDec(CALC_ADDITION,variable,"1"); return; } else if(Command[i-2]=='-'&&Command[i-1]=='-'){ //デクリメント variable[i-2]=0; IncDec(CALC_SUBTRACTION,variable,"1"); return; } } //先端部分の識別子をエラーキーワードにする for(i=0;;i++){ if(!IsVariableChar(Command[i])){ variable[i]=0; break; } variable[i]=Command[i]; } if(GetVarType(variable,Type(),0)){ //変数リストに該当したとき compiler.errorMessenger.Output(1,NULL,cp); } else{ if( compiler.GetObjectModule().meta.GetGlobalConsts().IsExistDuplicationKeyName(variable) || compiler.GetObjectModule().meta.GetGlobalConstMacros().IsExistDuplicationKeyName(variable) ) { //定数リストに該当したとき compiler.errorMessenger.Output(1,NULL,cp); } else{ //変数リスト、定数リストに該当しないとき compiler.errorMessenger.Output(3,variable,cp); } } return; } i2=GetCalcId(Command+i,&i3); if(i2){ variable[i]=0; if(Command[i]=='=') break; if(Command[i+1+i3]=='='){ IncDec(i2,variable,Command+i+1+i3+1); return; } } variable[i]=Command[i]; } if(Command[i+1]=='\0'){ compiler.errorMessenger.Output(1,NULL,cp); return; } /////////////////////////////////////////////////////////////// // インデクサのsetアクセサ([]=演算子のオーバーロードに対応) /////////////////////////////////////////////////////////////// char ObjName[VN_SIZE],array_element[VN_SIZE]; GetArrayElement(variable,ObjName,array_element); if(array_element[0]){ Type varType; if( GetVarType(ObjName,varType,0) && varType.IsObject() ){ char temporary[VN_SIZE]; sprintf(temporary,"%s.%c%c%c",ObjName,1,ESC_OPERATOR,CALC_ARRAY_SET); char temp2[VN_SIZE]; sprintf(temp2,"%s,%s",array_element,Command+i+1); int idProc; void *pProc; idProc=GetProc(temporary,(void **)&pProc); if( idProc ) { CallProc( idProc, pProc, temporary, temp2, Type(), // ベースタイプはなし Type() ); return; } } } if( lstrcmpi( variable, "This" ) == 0 ){ compiler.errorMessenger.Output(133,NULL,cp); return; } //////////////////////////////////////// // 変数のタイプ型を識別して、演算を行う //////////////////////////////////////// Type varType; //型を識別 if( !GetTermTypeOnlyVariable(variable,varType) ){ // プロパティ用のメソッドを呼び出す if(!CallPropertyMethod( variable, Command+i+1, Type() )){ //エラーを表示 GetVarType(variable,varType,true); } return; } //NumOpe...(rax、またはxmm0に答えが格納される) int reg=REG_RAX; Type calcType; bool isNeedHeapFreeStructure; if( !NumOpe(®,Command+i+1,varType,calcType,&isNeedHeapFreeStructure) ){ return; } if(reg!=REG_RAX&&calcType.IsWhole()|| varType.IsNull()||calcType.IsNull()){ compiler.errorMessenger.Output(300,NULL,cp); } //結果を格納しているレジスタをブロッキング pobj_BlockReg->lock(reg); //変数アドレスを取得 RELATIVE_VAR VarRelativeVar; if( !TermOpeOnlyVariable( variable, varType, VarRelativeVar, true ) ) { compiler.errorMessenger.OutputFatalError(); return; } //レジスタのブロッキングを解除 pobj_BlockReg->clear(); if(varType.GetBasicType()&FLAG_PTR){ compiler.errorMessenger.Output(14,variable,cp); return; } if( varType.IsStruct() ){ //構造体インスタンスへの代入 SetStructVariableFromRax(varType,calcType,&VarRelativeVar,isNeedHeapFreeStructure); return; } if( calcType.IsObject() && !calcType.Equals( varType ) ){ bool isUpCast = false; if( varType.IsObject() ){ if( varType.GetClass().IsEqualsOrSubClass( &calcType.GetClass() ) ){ isUpCast = true; } } if( !isUpCast ){ //キャスト演算子のオーバーロードに対応する CallCastOperatorProc(REG_RAX,calcType,isNeedHeapFreeStructure,varType); } } if( varType.IsObject() && compiler.GetObjectModule().meta.GetBlittableTypes().IsExist( calcType ) ){ // Blittable型をオブジェクトとして扱う std::vector userProcs; compiler.GetObjectModule().meta.GetBlittableTypes().GetClass( calcType ).GetStaticMethods().Enum( "_Create", userProcs ); if( userProcs.size() != 1 ){ compiler.errorMessenger.OutputFatalError(); return; } const UserProc *pUserProc = userProcs[0]; // mov rcx, rax compiler.codeGenerator.op_mov_RR( REG_RCX, REG_RAX ); // call System.[TypeClass]._Create compiler.codeGenerator.op_call( pUserProc ); calcType = pUserProc->ReturnType(); } ///////////////////////////////// // 右辺、左辺の型チェックを行う ///////////////////////////////// CheckDifferentType(varType,calcType,0,0); ///////////////////////////////////////////////// // rax(実数はxmm0)の内容を変数にコピー ///////////////////////////////////////////////// SetVariableFromRax(varType,calcType.GetBasicType(),&VarRelativeVar); // コード生成過程で発生した構造体の一時メモリを破棄する compiler.codeGenerator.op_FreeTempStructure(); }