#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){ //ベースタイプが未定のとき return type; } if(!IsWholeNumberType(type)){ //整数型ではないときは暗黙の変換は必要なし return type; } if(BaseType==DEF_OBJECT){ //ベースタイプがオブジェクトのときは暗黙の変換は必要なし 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,TYPEINFO *pBaseTypeInfo,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 PARAMETER_INFO *ppi = (PARAMETER_INFO *)HeapAlloc(hHeap,0,sizeof(PARAMETER_INFO)*3); int iParmNum=0; if(bTwoTerm){ ppi[iParmNum].bArray=0; ppi[iParmNum].bByVal=0; ppi[iParmNum].name=0; ppi[iParmNum].type=type[sp-1]; ppi[iParmNum].u.index=index_stack[sp-1]; ppi[iParmNum].SubScripts[0]=-1; iParmNum++; } //オーバーロードを解決 char temporary[255]; if(idCalc==CALC_EQUAL) lstrcpy(temporary,"=="); else GetCalcName(idCalc,temporary); SUBINFO *psi; psi=OverloadSolution(temporary,subs,ppi,iParmNum,pBaseTypeInfo); if(!psi){ HeapDefaultFree(ppi); return 0; } else{ //オーバーロードされていないが、パラメータ個数が一致しないとき if(iParmNum!=psi->ParmNum){ HeapDefaultFree(ppi); return 0; } } HeapDefaultFree(ppi); sp--; type[sp-1]=psi->ReturnType; index_stack[sp-1]=psi->u.ReturnIndex; return 1; } int Operator_New_GetType(const char *Parameter,LONG_PTR *plpIndex,const TYPEINFO &baseTypeInfo ){ 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 0; } break; } TypeName[i2]=Parameter[i]; if(Parameter[i]=='\0'){ CreateParameter[0]=0; break; } } int type; type=GetTypeFixed(TypeName,plpIndex); if( baseTypeInfo.type == DEF_OBJECT ){ return DEF_OBJECT; } return DEF_PTR_OBJECT; } int NumOpe_GetType(char *Command,TYPEINFO *pBaseType,LONG_PTR *plpIndex){ extern int cp; int i,i2,i3,i4; char temporary[1024],temp2[1024],temp3[1024]; if(Command[0]=='\0'){ SetError(1,NULL,cp); return 0; } if(Command[0]==1&& Command[1]==ESC_NEW ){ //New演算子(オブジェクト生成) return Operator_New_GetType(Command+2,plpIndex, *pBaseType ); } ///////////////////////////////// // 式要素を逆ポーランド式で取得 ///////////////////////////////// char *values[255]; long calc[255]; long stack[255]; int pnum; if(!GetNumOpeElements(Command,&pnum,values,calc,stack)){ for(i=0;itype==DEF_OBJECT){ if(IsStringObjectType(*pBaseType)){ //要求タイプがオブジェクトであり、Stringの受け入れが可能な場合 extern CClass *pobj_StringClass; type[sp]=DEF_OBJECT; index_stack[sp]=(LONG_PTR)pobj_StringClass; bLiteralCalculation=0; sp++; break; } } } type[sp]=DEF_PTR_CHAR; bLiteralCalculation=0; } else if((term[0]=='e'||term[0]=='E')&& (term[1]=='x'||term[1]=='X')&& term[2]=='\"'){ //拡張版リテラル文字列(エスケープシーケンス可能) goto StrLiteral; } else if(IsVariableTopChar(term[0])|| term[0]=='*'|| (term[0]=='.'&&IsVariableTopChar(term[1]))){ ////////////////// // 何らかの識別子 ////////////////////////////////////// // 関数(DLL、ユーザー定義、組み込み) ////////////////////////////////////// i2=GetCallProcName(term,temporary); if(term[i2]=='('){ i4=GetStringInPare_RemovePare(temp2,term+i2+1); int idProc; void *pInfo; idProc=GetProc(temporary,&pInfo); if(idProc){ //閉じカッコ")"に続く文字がNULLでないとき if(term[i2+1+i4+1]!='\0'){ if( term[i2+1+i4+1] == '.' || term[i2+1+i4+1] == 1 && term[i2+1+i4+2] == ESC_PSMEM ){ goto NonProc; } else{ SetError(42,NULL,cp); } } //////////////// // 呼び出し //////////////// i2=GetReturnTypeOfProc(idProc,pInfo,temporary,temp2,&index_stack[sp]); if(i2==-1){ //戻り値が存在しないとき goto error; } type[sp]=i2; bLiteralCalculation=0; sp++; break; } else if(GetConstCalcBuffer(temporary,temp2,temp3)){ ///////////////////////// // マクロ関数 ///////////////////////// //閉じカッコ")"に続く文字がNULLでないときはエラーにする if(term[i2+1+i4+1]!='\0') SetError(42,NULL,cp); //マクロ関数の場合 i2=NumOpe_GetType(temp3,NULL,&index_stack[sp]); if(!IS_LITERAL(index_stack[sp])){ //リテラル値ではなかったとき bLiteralCalculation=0; } type[sp]=i2; sp++; break; } } NonProc: //インデクサ(getアクセサ) char VarName[VN_SIZE],ArrayElements[VN_SIZE]; GetArrayElement(term,VarName,ArrayElements); if(ArrayElements[0]){ CClass *pobj_c; i2=GetVarType(VarName,(LONG_PTR *)&pobj_c,0); if(i2==DEF_OBJECT){ TYPEINFO RetTypeInfo; if( !GetReturnTypeOfIndexerGetterProc(pobj_c,RetTypeInfo) ){ SetError(1,NULL,cp); goto error; } type[sp]=RetTypeInfo.type; index_stack[sp]=RetTypeInfo.u.lpIndex; bLiteralCalculation=0; sp++; break; } } // Nothing if( lstrcmp( term, "Nothing" ) == 0 ){ type[sp] = DEF_OBJECT; if( pBaseType && pBaseType->type == DEF_OBJECT ){ index_stack[sp] = pBaseType->u.lpIndex; } else{ index_stack[sp] = (LONG_PTR)pobj_DBClass->GetObjectClass(); } bLiteralCalculation = 0; sp++; break; } i2=GetVarType(term,&index_stack[sp],0); if(i2!=-1){ ////////// // 変数 ////////// if(i2&FLAG_PTR){ //配列ポインタ type[sp]=GetPtrType(i2^FLAG_PTR,index_stack[sp]); } else{ type[sp]=i2; } bLiteralCalculation=0; sp++; break; } ////////////// // 定数の場合 ////////////// i3 = CDBConst::obj.GetType(term); if(i3){ type[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[sp]=i3|FLAG_CAST; index_stack[sp]=lp; sp++; break; } ///////////////////////////////// // プロパティ用のメソッド ///////////////////////////////// //配列要素を排除 GetArrayElement(term,VarName,ArrayElements); if(GetSubHash(VarName,0)){ TYPEINFO RetTypeInfo; GetReturnTypeOfPropertyMethod(term,NULL,&RetTypeInfo); //大きな型への暗黙の変換 type[sp]=RetTypeInfo.type; index_stack[sp]=RetTypeInfo.u.lpIndex; bLiteralCalculation=0; sp++; break; } //該当する識別子が見当たらないときはエラー扱いにする bError=1; SetError(3,term,cp); type[sp]=DEF_DOUBLE; } else{ //リテラル値 int base_type; base_type=0; if(pBaseType) base_type=pBaseType->type; type[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[sp-1]=NeutralizationType(type[sp-1],index_stack[sp-1],type[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[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[sp-1]=NeutralizationType(type[sp-1],index_stack[sp-1],type[sp],index_stack[sp]); break; case CALC_MOD: //values[sp-2]%=values[sp-1] //剰余演算 sp--; type[sp-1]=NeutralizationType(type[sp-1],index_stack[sp-1],type[sp],index_stack[sp]); break; case CALC_QUOTIENT: //values[sp-2]/=values[sp-1]; //除算 sp--; type[sp-1]=NeutralizationType(type[sp-1],index_stack[sp-1],type[sp],index_stack[sp]); break; case CALC_INTQUOTIENT: //values[sp-2]/=values[sp-1] //整数除算 sp--; type[sp-1]=NeutralizationType(type[sp-1],index_stack[sp-1],type[sp],index_stack[sp]); break; case CALC_MINUSMARK: //values[sp-1]=-values[sp-1] //符号反転 break; case CALC_POWER: //べき乗演算(浮動小数点演算のみ) sp--; //未完成 break; case CALC_AS: //キャスト type[sp-2]=type[sp-1]&(~FLAG_CAST); index_stack[sp-2]=index_stack[sp-1]; sp--; break; case CALC_BYVAL: //ポインタ型→参照型 if( PTR_LEVEL( type[sp-1] ) <= 0 ){ //ポインタ型ではないとき SetError( 3, NULL, cp ); goto error; } type[sp-1] = PTR_LEVEL_DOWN( type[sp-1] ); break; } } if(bError) goto error; if(sp!=1){ SetError(1,NULL,cp); goto error; } if(bLiteralCalculation){ //右辺値が数値の定数式の場合 LONG_PTR lpCalcIndex; int base_type=0; if(pBaseType) base_type=pBaseType->type; i2=StaticCalculation(true, Command,base_type,&i64data,&lpCalcIndex); type[0]=i2; index_stack[0]=lpCalcIndex; } else{ //右辺値が数値の定数式ではないとき if(IS_LITERAL(index_stack[0])) index_stack[0]=-1; } if(plpIndex) *plpIndex=index_stack[0]; int RetType; RetType=type[0]; goto finish; ////////////////// // エラー処理 ////////////////// error: RetType=-1; goto finish; finish: for(i=0;i