#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 bObjectMember; lstrcpy(ObjName,name); for(i=lstrlen(ObjName)-1;i>=0;i--){ if(ObjName[i]=='.'||(ObjName[i]==1&&ObjName[i+1]==ESC_PSMEM)) break; } if(i==-1) bObjectMember=0; else{ if(ObjName[i]=='.') lstrcpy(NestMember,ObjName+i+1); else lstrcpy(NestMember,ObjName+i+2); ObjName[i]=0; bObjectMember=1; } if(bObjectMember){ //オブジェクトのメンバ関数の場合 if(lstrcmpi(ObjName,"Super")==0){ //スーパークラス参照の場合 if(pobj_CompilingClass==0){ SetError(118,NULL,cp); goto finish; } //クラス内のメンバ関数をコンパイルしているとき //※オーバーライドされた関数をサーチする for(i=0;iiMethodNum;i++){ if(pobj_CompilingClass->ppobj_Method[i]->pobj_InheritsClass==0) continue; if(lstrcmp(NestMember,pobj_CompilingClass->ppobj_Method[i]->psi->name)==0){ ppArray_si[num]=pobj_CompilingClass->ppobj_Method[i]->psi; num++; } } if(num==0) SetError(119,NestMember,cp); goto finish; } ////////////////////////////////////////////// // 静的メソッド(クラス名が指定される場合) ////////////////////////////////////////////// CClass *pobj_c; pobj_c=pobj_DBClass->check(ObjName); if(pobj_c){ 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++; } } goto finish; } i=GetVarType(ObjName,(LONG_PTR *)&pobj_c,1); if(i==-1) goto finish; //エラーの場合 if(!(NATURAL_TYPE(i)==DEF_OBJECT)) goto finish; //※オーバーライドされた関数を先にサーチする必要があるため、バックサーチを行う 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++; } } goto finish; } 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++; } } } if(num) goto finish; } //ハッシュ値を取得 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; }