#include "../BasicCompiler_Common/common.h" #include "Opcode.h" void SetVariableFromRax(int VarType,int CalcType,RELATIVE_VAR *pRelativeVar){ ///////////////////////////////////////////////// // raxの内容を変数にコピーするコードを抽出 ///////////////////////////////////////////////// if(VarType==DEF_BOOLEAN){ //bool SetBooleanVariable(CalcType,pRelativeVar); } if(VarType==DEF_CHAR||VarType==DEF_BYTE){ //8ビット変数へalレジスタの内容を格納する SetWholeVariable(sizeof(char),CalcType,pRelativeVar); } else if(VarType==DEF_INTEGER||VarType==DEF_WORD){ //16ビット変数へaxレジスタの内容を格納する SetWholeVariable(sizeof(short),CalcType,pRelativeVar); } else if(VarType==DEF_LONG||VarType==DEF_DWORD){ //32ビット変数へeaxレジスタの内容を格納する SetWholeVariable(sizeof(long),CalcType,pRelativeVar); } else if(VarType==DEF_INT64||VarType==DEF_QWORD||IsPtrType(VarType)){ //64ビット変数へraxレジスタの内容を格納する SetWholeVariable(sizeof(_int64),CalcType,pRelativeVar); } else if(VarType==DEF_DOUBLE){ //Double型変数へスタックの内容を格納する SetDoubleVariable(CalcType,pRelativeVar); } else if(VarType==DEF_SINGLE){ //Single型変数へスタックの内容を格納する SetSingleVariable(CalcType,pRelativeVar); } } void OpcodeCalc(char *Command){ int i,i2,i3; char variable[VN_SIZE]; ////////////////////////////////////// // インクリメント・デクリメント ////////////////////////////////////// for(i=0;;i++){ if(Command[i]=='\"'){ //ダブルクォートは不正なのでエラー扱い variable[i]=0; SetError(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]; } LONG_PTR lp; if(GetVarType(variable,&lp,0)!=-1){ //変数リストに該当したとき SetError(1,NULL,cp); } else{ if(GetConstHash(variable)){ //定数リストに該当したとき SetError(1,NULL,cp); } else{ //変数リスト、定数リストに該当しないとき SetError(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'){ SetError(1,NULL,cp); return; } /////////////////////////////////////////////////////////////// // インデクサのsetアクセサ([]=演算子のオーバーロードに対応) /////////////////////////////////////////////////////////////// char ObjName[VN_SIZE],array_element[VN_SIZE]; CClass *pobj_c; GetArrayElement(variable,ObjName,array_element); if(array_element[0]){ i2=GetVarType(ObjName,(LONG_PTR *)&pobj_c,0); if(i2==DEF_OBJECT){ 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 *pInfo; idProc=GetProc(temporary,&pInfo); if(idProc){ CallProc(idProc,pInfo,temporary,temp2,NULL); return; } } } //////////////////////////////////////// // 変数のタイプ型を識別して、演算を行う //////////////////////////////////////// int VarType,CalcType; LONG_PTR lpVarIndex,lpCalcIndex; BOOL bCalcUseHeap; //型を識別 VarType=GetVarType(variable,&lpVarIndex,0); if(VarType==-1){ // プロパティ用のメソッドを呼び出す if(!CallPropertyMethod(variable,Command+i+1,NULL)){ //エラーを表示 GetVarType(variable,&lpVarIndex,1); } return; } extern LONG_PTR ProcPtr_BaseIndex; if(VarType==DEF_PTR_PROC) ProcPtr_BaseIndex=lpVarIndex; else ProcPtr_BaseIndex=-1; //NumOpe...(rax、またはxmm0に答えが格納される) int reg=REG_RAX; CalcType=NumOpe(®,Command+i+1,VarType,lpVarIndex,&lpCalcIndex,&bCalcUseHeap); //結果を格納しているレジスタをブロッキング pobj_BlockReg->lock(reg); if(VarType==-1||CalcType==-1) return; //変数アドレスを取得 RELATIVE_VAR VarRelativeVar; if(!GetVarOffsetReadWrite( variable, &VarType, &VarRelativeVar, &lpVarIndex)) return; //レジスタのブロッキングを解除 pobj_BlockReg->clear(); if(VarType&FLAG_PTR){ SetError(14,variable,cp); return; } if(VarType==DEF_OBJECT){ //オブジェクトインスタンスへの代入 SetObjectVariableFromRax(lpVarIndex,CalcType,lpCalcIndex,&VarRelativeVar,bCalcUseHeap); return; } if(CalcType==DEF_OBJECT){ //キャスト演算子のオーバーロードに対応する CallCastOperatorProc(REG_RAX,CalcType,lpCalcIndex,bCalcUseHeap,VarType,lpVarIndex); } ///////////////////////////////// // 右辺、左辺の型チェックを行う ///////////////////////////////// CheckDifferentType(VarType,lpVarIndex,CalcType,lpCalcIndex,0,0); ///////////////////////////////////////////////// // rax(実数はxmm0)の内容を変数にコピー ///////////////////////////////////////////////// SetVariableFromRax(VarType,CalcType,&VarRelativeVar); }