source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/hash.cpp@ 652

Last change on this file since 652 was 598, checked in by dai_9181, 17 years ago

SplitMemberNameの依存関係を排除。

File size: 4.4 KB
RevLine 
[206]1#include "stdafx.h"
2
[193]3#include <Compiler.h>
4
[4]5#include "../BasicCompiler_Common/common.h"
6
7#ifdef _AMD64_
[485]8#include "../compiler_x64/opcode.h"
[4]9#else
[484]10#include "../compiler_x86/opcode.h"
[4]11#endif
12
[509]13using namespace ActiveBasic::Compiler;
14
[75]15int hash_default(const char *name){
[4]16 int key;
17
18 for(key=0;*name!='\0';name++){
19 key=((key<<8)+ *name )%MAX_HASH;
20 }
21
22 return key;
23}
24
[209]25DllProc *GetDeclareHash(const char *fullName){
26 char namespaceStr[VN_SIZE]; //オブジェクト変数
27 char simpleName[VN_SIZE]; //入れ子メンバ
28 bool isObjectMember = SplitMemberName( fullName, namespaceStr, simpleName );
[113]29
[209]30 ///////////////////////////
31 // グローバル関数を検索
32 ///////////////////////////
[4]33
[209]34 // ハッシュ値を取得
[265]35 DllProc *pDllProc = compiler.GetObjectModule().meta.GetDllProcs().GetHashArrayElement( simpleName );
[75]36 while(pDllProc){
[509]37 if( pDllProc->IsEqualSymbol( LexicalAnalyzer::FullNameToSymbol( fullName ) ) ){
[209]38 return pDllProc;
[75]39 }
[4]40
[209]41 pDllProc=pDllProc->GetChainNext();
[4]42 }
43
[209]44 return NULL;
[4]45}
46
[206]47void GetOverloadSubHash( const char *lpszName, std::vector<const UserProc *> &subs ){
[4]48 char name[VN_SIZE];
49
50 if(lpszName[0]=='.'){
51 GetWithName(name);
52 lstrcat(name,lpszName);
53 }
54 else lstrcpy(name,lpszName);
55
56 char ObjName[VN_SIZE]; //オブジェクト変数
57 char NestMember[VN_SIZE]; //入れ子メンバ
[206]58 bool isObjectMember = SplitMemberName( name, ObjName, NestMember );
[4]59
[28]60 if(isObjectMember){
[4]61 //オブジェクトのメンバ関数の場合
62
[27]63 bool isStatic = false;
[75]64 const CClass *pobj_c = NULL;
[304]65 if(lstrcmpi(ObjName,"Super")==0)
66 {
[27]67 //クラスメンバ関数内から基底クラスの呼び出し
[536]68 pobj_c=&compiler.GetCompilingClass().GetSuperClass();
[27]69 }
[304]70 else
71 {
[47]72 //"->"によってオブジェクトを指定する通常のメンバ関数呼び出し
[75]73 Type type;
[415]74 if( GetTermType(ObjName,type) )
75 {
76 if( type.IsObject() )
77 {
78 pobj_c = &type.GetClass();
79 }
[100]80 }
[415]81
82 if( !pobj_c )
83 {
[598]84 pobj_c = compiler.GetObjectModule().meta.FindClassSupportedTypeDef(
85 LexicalAnalyzer::FullNameToSymbol( ObjName )
86 );
[47]87 if( pobj_c ){
88 isStatic = true;
89 }
[28]90 }
[4]91 }
92
[101]93 if( pobj_c && pobj_c != (CClass *)-1 ){
[100]94 if( isStatic ){
95 // 静的メソッドから列挙
[136]96 pobj_c->GetStaticMethods().Enum( NestMember, subs );
[100]97 }
98 else{
99 //動的メソッドから列挙
[350]100 pobj_c->EnumDynamicMethodsOrInterfaceMethods( NestMember, subs );
[100]101 }
[304]102
[100]103 return;
[4]104 }
105 }
106
107
[536]108 if( compiler.IsCompilingClass() ){
[100]109 //自身のオブジェクトのメンバ関数を検索
[4]110
[100]111 // 静的メソッド
[536]112 compiler.GetCompilingClass().GetStaticMethods().Enum( name, subs );
[4]113
[100]114 // 動的メソッド
[536]115 compiler.GetCompilingClass().EnumDynamicMethodsOrInterfaceMethods( name, subs );
[100]116 }
[27]117
118
[100]119 // グローバル関数を検索
[576]120 compiler.GetObjectModule().meta.GetUserProcs().EnumGlobalProcs( NestMember, LexicalAnalyzer::FullNameToSymbol( name ), subs );
[4]121}
122
123//オーバーロードされていない関数を取得(昔のコンパイラソースコードとの互換性保持)
[206]124const UserProc *GetSubHash(const char *lpszName,BOOL bError){
125 std::vector<const UserProc *> subs;
[50]126 GetOverloadSubHash(lpszName,subs);
[4]127
128 //関数が存在しないとき
[50]129 if(subs.size() == 0){
[75]130 if(bError){
[465]131 compiler.errorMessenger.Output(3,lpszName,cp);
[75]132 }
[4]133 return 0;
134 }
135
136 //一つ以上の関数が存在するときは内部エラー(デバッグ用)
[50]137 if(subs.size() > 1){
[465]138 if(bError) compiler.errorMessenger.Output(300,NULL,cp);
[4]139 }
140
[206]141 const UserProc *pUserProc = subs[0];
[4]142
[75]143 return pUserProc;
[5]144}
[206]145const UserProc *GetMethodHash(const char *ObjectName,const char *MethodName,const char *Parameter,BOOL bError){
[5]146 char temporary[VN_SIZE];
147 sprintf(temporary,"%s.%s",ObjectName,MethodName);
148
[206]149 std::vector<const UserProc *> subs;
[50]150 GetOverloadSubHash(temporary,subs);
[5]151
152 //関数が存在しないとき
[50]153 if(subs.size() == 0){
[5]154 return 0;
155 }
156
157 //オーバーロードを解決
[206]158 const UserProc *pUserProc = OverloadSolutionWithStrParam(temporary,subs,Parameter,ObjectName);
[5]159
[75]160 return pUserProc;
[5]161}
[95]162
[206]163const UserProc *GetClassMethod( const char *className, const char *methodName ){
[598]164 const CClass *pClass = compiler.GetObjectModule().meta.FindClassSupportedTypeDef(
165 LexicalAnalyzer::FullNameToSymbol( className )
166 );
[95]167 if( pClass ){
[523]168 std::vector<const UserProc *> userProcs;
[350]169 pClass->EnumDynamicMethodsOrInterfaceMethods( methodName, userProcs );
[95]170 if( userProcs.size() == 1 ){
171 return userProcs[0];
172 }
173 }
174
175 char temporary[VN_SIZE];
176 sprintf( temporary, "%s.%s", className, methodName );
[465]177 compiler.errorMessenger.Output(3, temporary, -1 );
[95]178
179 return NULL;
180}
Note: See TracBrowser for help on using the repository browser.