#include "../BasicCompiler_Common/common.h" #ifdef _AMD64_ #include "../BasicCompiler64/opcode.h" #else #include "../BasicCompiler32/opcode.h" #endif int hash_default(char *name){ int key; for(key=0;*name!='\0';name++){ key=((key<<8)+ *name )%MAX_HASH; } return key; } CONSTINFO *GetConstHash(char *name){ //ハッシュ値を取得 int key; key=hash_default(name); //格納位置を取得 extern CONSTINFO **ppConstHash; CONSTINFO *pci; pci=ppConstHash[key]; while(pci){ if(lstrcmp(pci->name,name)==0) break; pci=pci->pNextData; } return pci; } DECLAREINFO *GetDeclareHash(char *name){ //ハッシュ値を取得 int key; key=hash_default(name); //格納位置を取得 extern DECLAREINFO **ppDeclareHash; DECLAREINFO *pdi; pdi=ppDeclareHash[key]; while(pdi){ if(lstrcmp(pdi->name,name)==0) break; pdi=pdi->pNextData; } return pdi; } SUBINFO **GetOverloadObjectSubHash(char *name,CClass *pobj_c, int *pNum){ int i; //格納のための構造体配列を用意 extern HANDLE hHeap; SUBINFO **ppArray_si; int num=0; ppArray_si=(SUBINFO **)HeapAlloc(hHeap,0,sizeof(SUBINFO *)*1024); //オブジェクトのメンバ関数の場合 //※オーバーライドされた関数を先にサーチする必要があるため、バックサーチを行う for(i=pobj_c->iMethodNum-1;i>=0;i--){ if(lstrcmp(name,pobj_c->ppobj_Method[i]->psi->name)==0){ ppArray_si[num]=pobj_c->ppobj_Method[i]->psi; num++; } } *pNum=num; return ppArray_si; } SUBINFO **GetOverloadSubHash(char *lpszName,int *pNum){ extern SUBINFO *pSubInfo; extern int SubInfoNum; extern int cp; int i; char name[VN_SIZE]; if(lpszName[0]=='.'){ GetWithName(name); lstrcat(name,lpszName); } else lstrcpy(name,lpszName); //格納のための構造体配列を用意 extern HANDLE hHeap; SUBINFO **ppArray_si; int num=0; ppArray_si=(SUBINFO **)HeapAlloc(hHeap,0,sizeof(SUBINFO *)*1024); char ObjName[VN_SIZE]; //オブジェクト変数 char NestMember[VN_SIZE]; //入れ子メンバ bool isObjectMember = SplitMemberName( name, ObjName, NestMember ); if( !isObjectMember ) lstrcpy(ObjName,name); if(isObjectMember){ //オブジェクトのメンバ関数の場合 bool isStatic = false; CClass *pobj_c; if(lstrcmpi(ObjName,"Super")==0){ //クラスメンバ関数内から基底クラスの呼び出し pobj_c=pobj_CompilingClass; } else{ pobj_c=pobj_DBClass->check(ObjName); if( pobj_c ){ isStatic = true; } else{ //"->"によってオブジェクトを指定する通常のメンバ関数呼び出し int type = GetVarType(ObjName,(LONG_PTR *)&pobj_c,0); if(!(NATURAL_TYPE(type)==DEF_OBJECT)) goto finish; } } if( isStatic ){ // 静的メソッドから取得 for(i=0;iiStaticMethodNum;i++){ if(lstrcmp(NestMember,pobj_c->ppobj_StaticMethod[i]->psi->name)==0){ ppArray_si[num]=pobj_c->ppobj_StaticMethod[i]->psi; num++; } } } else{ //動的メソッドから取得 //※オーバーライドされた関数を先にサーチする必要があるため、バックサーチを行う for(i=pobj_c->iMethodNum-1;i>=0;i--){ if(lstrcmp(NestMember,pobj_c->ppobj_Method[i]->psi->name)==0){ ppArray_si[num]=pobj_c->ppobj_Method[i]->psi; num++; } } } } else{ //オブジェクトが明示的に指定されていないとき if(pobj_CompilingClass){ //自身のオブジェクトのメンバ関数を検索 ////////////////////////////////////////////// // 静的メソッド ////////////////////////////////////////////// CClass *pobj_c = pobj_CompilingClass; for(i=0;iiStaticMethodNum;i++){ if(lstrcmp(name,pobj_c->ppobj_StaticMethod[i]->psi->name)==0){ ppArray_si[num]=pobj_c->ppobj_StaticMethod[i]->psi; num++; } } /////////////////////// // 動的メソッド(一般) /////////////////////// for(i=0;iiMethodNum;i++){ //オーバーライドされた関数を飛び越す if(pobj_CompilingClass->ppobj_Method[i]->pobj_InheritsClass==0) break; } for(;iiMethodNum;i++){ if(lstrcmp(name,pobj_CompilingClass->ppobj_Method[i]->psi->name)==0){ ppArray_si[num]=pobj_CompilingClass->ppobj_Method[i]->psi; num++; } } //オーバーライドされたメンバ関数 for(i=0;iiMethodNum;i++){ //オーバーライドされた関数を飛び越す if(pobj_CompilingClass->ppobj_Method[i]->pobj_InheritsClass){ if(lstrcmp(name,pobj_CompilingClass->ppobj_Method[i]->psi->name)==0){ ppArray_si[num]=pobj_CompilingClass->ppobj_Method[i]->psi; num++; } } } } /////////////////////////// // グローバル関数を検索 /////////////////////////// //ハッシュ値を取得 int key; key=hash_default(name); //格納位置を取得 extern SUBINFO **ppSubHash; SUBINFO *psi; psi=ppSubHash[key]; while(psi){ if(!psi->pobj_ParentClass){ if(lstrcmp(psi->name,name)==0){ ppArray_si[num]=psi; num++; } } psi=psi->pNextData; } } finish: *pNum=num; return ppArray_si; } //オーバーロードされていない関数を取得(昔のコンパイラソースコードとの互換性保持) SUBINFO *GetSubHash(char *lpszName,BOOL bError){ int num; SUBINFO **ppsi,*psi; ppsi = GetOverloadSubHash(lpszName,&num); //関数が存在しないとき if(num == 0){ HeapDefaultFree(ppsi); return 0; } //一つ以上の関数が存在するときは内部エラー(デバッグ用) if(num > 1){ if(bError) SetError(300,NULL,cp); } psi = ppsi[0]; HeapDefaultFree(ppsi); return psi; } SUBINFO *GetMethodHash(char *ObjectName,char *MethodName,char *Parameter,BOOL bError){ char temporary[VN_SIZE]; sprintf(temporary,"%s.%s",ObjectName,MethodName); int num; SUBINFO **ppsi,*psi; ppsi = GetOverloadSubHash(temporary,&num); //関数が存在しないとき if(num == 0){ HeapDefaultFree(ppsi); return 0; } //オーバーロードを解決 psi=OverloadSolutionWithStrParam(temporary,ppsi,num,Parameter,ObjectName,NULL); HeapDefaultFree(ppsi); return psi; }