#include "common.h" int MakeWholeType(int size,int bSigned){ switch(size){ case 1: if(bSigned) return DEF_SBYTE; else return DEF_BYTE; break; case 2: if(bSigned) return DEF_INTEGER; else return DEF_WORD; break; case 4: if(bSigned) return DEF_LONG; else return DEF_DWORD; break; case 8: if(bSigned) return DEF_INT64; else return DEF_QWORD; break; } return 0; } int AutoBigCast(int BaseType,int CalcType){ int type; type=CalcType; if(BaseType==0||BaseType==-1){ //ベースタイプが未定のとき return type; } if(!IsWholeNumberType(type)){ //整数型ではないときは暗黙の変換は必要なし return type; } if(BaseType==DEF_OBJECT||BaseType==DEF_STRUCT){ //ベースタイプがオブジェクトのときは暗黙の変換は必要なし return type; } int BaseTypeSize; BaseTypeSize=GetTypeSize(BaseType,-1); if(IsRealNumberType(BaseType)){ if(GetTypeSize(CalcType,-1)<4) type=MakeWholeType(4,IsSignedType(CalcType)); } else if(BaseTypeSize>GetTypeSize(CalcType,-1)){ //要求される型のほうがサイズが大きいとき type=MakeWholeType(BaseTypeSize,IsSignedType(CalcType)); } if(!type){ extern int cp; SetError(300,NULL,cp); } return type; } BOOL CheckCalcType(int idCalc,int *type,int sp){ //演算子の右辺、左辺の型をチェック extern int cp; //演算子名を取得 char temporary[255]; GetCalcName(idCalc,temporary); switch(idCalc){ ///////////////////////////////////// // 実数に対する論理演算はエラー ///////////////////////////////////// case CALC_XOR: case CALC_OR: case CALC_AND: if(IsRealNumberType(type[sp-2])||IsRealNumberType(type[sp-1])){ //いずれかの項が実数のとき SetError(45,temporary,cp); return 0; } //As以外の演算子に型名が指定されていないかをチェック if((type[sp-2]&FLAG_CAST)||(type[sp-1]&FLAG_CAST)){ SetError(48,temporary,cp); return 0; } break; case CALC_NOT: if(IsRealNumberType(type[sp-1])){ //実数のとき SetError(45,temporary,cp); return 0; } //As以外の演算子に型名が指定されていないかをチェック if(type[sp-1]&FLAG_CAST){ SetError(48,temporary,cp); return 0; } break; ///////////////////////////////////// // 比較演算はチェック項目なし ///////////////////////////////////// case CALC_PE: case CALC_QE: case CALC_NOTEQUAL: case CALC_EQUAL: case CALC_P: case CALC_Q: //As以外の演算子に型名が指定されていないかをチェック if((type[sp-2]&FLAG_CAST)||(type[sp-1]&FLAG_CAST)){ SetError(48,temporary,cp); return 0; } break; ///////////////////////////////////// // 算術演算をチェック ///////////////////////////////////// case CALC_ADDITION: case CALC_SUBTRACTION: case CALC_PRODUCT: case CALC_QUOTIENT: case CALC_POWER: //As以外の演算子に型名が指定されていないかをチェック if((type[sp-2]&FLAG_CAST)||(type[sp-1]&FLAG_CAST)){ SetError(48,temporary,cp); return 0; } break; case CALC_SHL: case CALC_SHR: case CALC_MOD: case CALC_INTQUOTIENT: if(IsRealNumberType(type[sp-2])||IsRealNumberType(type[sp-1])){ //いずれかの項が実数のとき SetError(45,temporary,cp); return 0; } //As以外の演算子に型名が指定されていないかをチェック if((type[sp-2]&FLAG_CAST)||(type[sp-1]&FLAG_CAST)){ SetError(48,temporary,cp); return 0; } break; case CALC_AS: if((type[sp-1]&FLAG_CAST)==0){ //型名が指定されていないときはエラー SetError(47,NULL,cp); return 0; } break; case CALC_BYVAL: if(type[sp-1]&FLAG_CAST){ //型名が指定されていないときはエラー SetError(47,NULL,cp); return 0; } break; case CALC_MINUSMARK: //As以外の演算子に型名が指定されていないかをチェック if(type[sp-1]&FLAG_CAST){ SetError(48,temporary,cp); return 0; } break; } return 1; } int GetReturnType_OperatorProc(int idCalc,const Type &baseType,int *type,LONG_PTR *index_stack,int &sp){ //オーバーロードされたオペレータ関数の戻り値を取得 CClass *pobj_c; pobj_c=(CClass *)index_stack[sp-2]; std::vector subs; pobj_c->EnumMethod( idCalc, subs ); if( subs.size() == 0 ){ return 0; } //項の数 BOOL bTwoTerm=1; if(idCalc==CALC_AS) bTwoTerm=0; ///////////////////////////////////////////// // オーバーロード解決用のパラメータを設定 ///////////////////////////////////////////// //_System_LocalThis Parameters params; if(bTwoTerm){ params.push_back( new Parameter( "", Type( type[sp-1], index_stack[sp-1] ) ) ); } //オーバーロードを解決 char temporary[255]; if(idCalc==CALC_EQUAL) lstrcpy(temporary,"=="); else GetCalcName(idCalc,temporary); UserProc *pUserProc = OverloadSolution( temporary, subs, params, baseType ); if(bTwoTerm){ delete params[0]; } if(!pUserProc){ return 0; } else{ //オーバーロードされていないが、パラメータ個数が一致しないとき if(params.size()!=pUserProc->Params().size()){ return 0; } } sp--; type[sp-1]=pUserProc->ReturnType().GetBasicType(); index_stack[sp-1]=pUserProc->ReturnType().GetIndex(); return 1; } bool Operator_New_GetType(const char *Parameter,const Type &baseType, Type &resultType ){ char TypeName[VN_SIZE],CreateParameter[VN_SIZE],objectSizeStr[VN_SIZE]; int i,i2; i=0; if(Parameter[0]=='['){ i=GetStringInBracket(objectSizeStr,Parameter); SlideString(objectSizeStr+1,-1); objectSizeStr[i-2]=0; } else objectSizeStr[0]=0; for(i2=0;;i++,i2++){ if(Parameter[i]=='('){ TypeName[i2]=0; //コンストラクタに渡すパラメータを取得 i2=GetStringInPare(CreateParameter,Parameter+i); RemoveStringPare(CreateParameter); i+=i2; if(Parameter[i]!='\0'){ SetError(42,NULL,cp); return false; } break; } TypeName[i2]=Parameter[i]; if(Parameter[i]=='\0'){ CreateParameter[0]=0; break; } } if( !Type::StringToType( TypeName, resultType ) ){ return false; } if( baseType.IsObject() ){ resultType.SetBasicType( DEF_OBJECT ); } else{ resultType.SetBasicType( DEF_PTR_OBJECT ); } return true; } bool NumOpe_GetType( const char *expression, const Type &baseType, Type &resultType ){ extern int cp; int i,i2,i3,i4; char temporary[1024],temp2[1024],temp3[1024]; if(expression[0]=='\0'){ SetError(1,NULL,cp); return false; } if(expression[0]==1&& expression[1]==ESC_NEW ){ //New演算子(オブジェクト生成) return Operator_New_GetType(expression+2,baseType, resultType ); } ///////////////////////////////// // 式要素を逆ポーランド式で取得 ///////////////////////////////// char *values[255]; long calc[255]; long stack[255]; int pnum; if(!GetNumOpeElements(expression,&pnum,values,calc,stack)){ for(i=0;iGetObjectClass(); } bLiteralCalculation = 0; sp++; break; } Type varType; if( GetVarType(term,varType,0) ){ ////////// // 変数 ////////// if( varType.GetBasicType() & FLAG_PTR ){ //配列ポインタ type_stack[sp]=GetPtrType( varType.GetBasicType()^FLAG_PTR ); } else{ type_stack[sp]=varType.GetBasicType(); } index_stack[sp] = varType.GetIndex(); bLiteralCalculation=0; sp++; break; } ////////////// // 定数の場合 ////////////// i3 = CDBConst::obj.GetType(term); if(i3){ type_stack[sp]=i3; if(IsRealNumberType(i3)){ //実数 goto Literal; } else if(IsWholeNumberType(i3)){ //整数 goto Literal; } else if(Is64Type(i3)){ //64ビット整数値 goto Literal; } else if(i3==DEF_STRING){ //リテラル文字列 goto StrLiteral; } else{ SetError(1,NULL,0); goto error; } } ////////////// // 型名の場合 ////////////// LONG_PTR lp; i3=GetTypeFixed(term,&lp); if(i3!=-1){ type_stack[sp]=i3|FLAG_CAST; index_stack[sp]=lp; sp++; break; } ///////////////////////////////// // プロパティ用のメソッド ///////////////////////////////// //配列要素を排除 GetArrayElement(term,VarName,ArrayElements); if(GetSubHash(VarName,0)){ Type tempType; GetReturnTypeOfPropertyMethod(term,NULL,tempType); //大きな型への暗黙の変換 type_stack[sp]=tempType.GetBasicType(); index_stack[sp]=tempType.GetIndex(); bLiteralCalculation=0; sp++; break; } //該当する識別子が見当たらないときはエラー扱いにする bError=1; SetError(3,term,cp); type_stack[sp]=DEF_DOUBLE; } else{ //リテラル値 int base_type = 0; if( !baseType.IsNull() ) base_type = baseType.GetBasicType(); type_stack[sp]=GetLiteralValue(term,&i64data,base_type); Literal: if((long)i64data==0&&index_stack[sp]==-1) index_stack[sp]=LITERAL_NULL; } sp++; break; //論理演算子 case CALC_XOR: case CALC_OR: case CALC_AND: sp--; type_stack[sp-1]=NeutralizationType(type_stack[sp-1],index_stack[sp-1],type_stack[sp],index_stack[sp]); break; case CALC_NOT: //values[sp-1]=Not values[sp-1] //NOT演算子 break; //比較演算子 case CALC_PE: //values[sp-2] <= values[sp-1] case CALC_QE: //values[sp-2] >= values[sp-1] case CALC_P: //values[sp-2] < values[sp-1] case CALC_Q: //values[sp-2] > values[sp-1] case CALC_NOTEQUAL: //values[sp-2] <> values[sp-1] case CALC_EQUAL: //values[sp-2] = values[sp-1] sp--; type_stack[sp-1]=DEF_LONG; break; //ビットシフト case CALC_SHL: //values[sp-2] << values[sp-1] case CALC_SHR: //values[sp-2] >> values[sp-1] sp--; break; //算術演算 case CALC_ADDITION: case CALC_SUBTRACTION: case CALC_PRODUCT: sp--; type_stack[sp-1]=NeutralizationType(type_stack[sp-1],index_stack[sp-1],type_stack[sp],index_stack[sp]); break; case CALC_MOD: //values[sp-2]%=values[sp-1] //剰余演算 sp--; type_stack[sp-1]=NeutralizationType(type_stack[sp-1],index_stack[sp-1],type_stack[sp],index_stack[sp]); break; case CALC_QUOTIENT: //values[sp-2]/=values[sp-1]; //除算 sp--; type_stack[sp-1]=NeutralizationType(type_stack[sp-1],index_stack[sp-1],type_stack[sp],index_stack[sp]); break; case CALC_INTQUOTIENT: //values[sp-2]/=values[sp-1] //整数除算 sp--; type_stack[sp-1]=NeutralizationType(type_stack[sp-1],index_stack[sp-1],type_stack[sp],index_stack[sp]); break; case CALC_MINUSMARK: //values[sp-1]=-values[sp-1] //符号反転 break; case CALC_POWER: //べき乗演算(浮動小数点演算のみ) sp--; //未完成 break; case CALC_AS: //キャスト type_stack[sp-2]=type_stack[sp-1]&(~FLAG_CAST); index_stack[sp-2]=index_stack[sp-1]; sp--; break; case CALC_BYVAL: //ポインタ型→参照型 if( PTR_LEVEL( type_stack[sp-1] ) <= 0 ){ //ポインタ型ではないとき SetError( 3, NULL, cp ); goto error; } type_stack[sp-1] = PTR_LEVEL_DOWN( type_stack[sp-1] ); break; } } if(bError) goto error; if(sp!=1){ SetError(1,NULL,cp); goto error; } if(bLiteralCalculation){ //右辺値が数値の定数式の場合 int base_type = 0; if( !baseType.IsNull() ) base_type = baseType.GetBasicType(); Type tempType; StaticCalculation(true, expression,base_type,&i64data,tempType); type_stack[0]=tempType.GetBasicType(); index_stack[0]=tempType.GetIndex(); } else{ //右辺値が数値の定数式ではないとき if(IS_LITERAL(index_stack[0])) index_stack[0]=-1; } resultType.SetType( type_stack[0], index_stack[0] ); bool isSuccessful = true; goto finish; ////////////////// // エラー処理 ////////////////// error: isSuccessful = false; goto finish; finish: for(i=0;i