source: dev/BasicCompiler_Common/Class.cpp@ 102

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

名前空間機能をクラスに適用。

File size: 41.2 KB
RevLine 
[4]1#include "common.h"
2
3#ifdef _AMD64_
4#include "../BasicCompiler64/opcode.h"
5#else
[5]6#include "../BasicCompiler32/opcode.h"
[4]7#endif
8
9CDBClass *pobj_DBClass;
10
11CClass *pobj_CompilingClass;
12CClass *pobj_StringClass;
13
[18]14CMember *pCompilingMethod;
15
[4]16
17
[75]18CMember::CMember( CClass *pobj_c, DWORD access, bool isConst, bool isRef, char *buffer, int nowLine ){
[4]19 extern int cp;
20
21 //構文を解析
22 char VarName[VN_SIZE];
23 char init_buf[VN_SIZE];
24 char constract_parameter[VN_SIZE];
[75]25 GetDimentionFormat(buffer,VarName,SubScripts,*this,init_buf,constract_parameter);
[4]26
27 //重複チェック
28 if(pobj_c->DupliCheckAll(VarName)){
29 SetError(15,VarName,cp);
30 }
31
32 //メンバ名
33 name=(char *)HeapAlloc(hHeap,0,lstrlen(VarName)+1);
34 lstrcpy(name,VarName);
35
36 //アクセス権
37 dwAccess=access;
38
[17]39 //定数扱いかどうか
40 this->isConst = isConst;
41
[4]42 //初期データ
43 InitBuf=(char *)HeapAlloc(hHeap,0,lstrlen(init_buf)+1);
44 lstrcpy(InitBuf,init_buf);
45
46 //コンストラクタ用のパラメータ
47 ConstractParameter=(char *)HeapAlloc(hHeap,0,lstrlen(constract_parameter)+1);
48 lstrcpy(ConstractParameter,constract_parameter);
49
50 //ソースコードの位置
[75]51 source_code_address=nowLine;
[4]52}
[75]53CMember::CMember(CMember &member):
54 Type( member )
55{
[4]56
57 //name
[75]58 name=(char *)HeapAlloc(hHeap,0,lstrlen(member.name)+1);
59 lstrcpy(name,member.name);
[4]60
[17]61 //定数扱いかどうか
[75]62 isConst = member.isConst;
[17]63
[4]64 //SubScripts
[75]65 memcpy(SubScripts,member.SubScripts,MAX_ARRAYDIM*sizeof(int));
[4]66
67 //ソースコードの位置
[75]68 source_code_address=member.source_code_address;
[4]69}
70CMember::CMember(){
71 memset(this,0,sizeof(CMember));
72}
73CMember::~CMember(){
74 HeapDefaultFree(name);
75 if(InitBuf) HeapDefaultFree(InitBuf);
76 if(ConstractParameter) HeapDefaultFree(ConstractParameter);
77}
78
[17]79bool CMember::IsConst(){
80 return isConst;
81}
82
[4]83void CMember::InitStaticMember(void){
84 //静的メンバをグローバル領域に作成
85
86 //イテレータをリセット
87 extern CDBClass *pobj_DBClass;
88 pobj_DBClass->Iterator_Reset();
89
90 int back_cp=cp;
91
92 while(pobj_DBClass->Iterator_HasNext()){
93 CClass *pobj_c;
94 pobj_c=pobj_DBClass->Iterator_GetNext();
95
[67]96 int i=0;
[53]97 foreach( CMember *member, pobj_c->staticMembers ){
98 char temporary[VN_SIZE];
99 sprintf(temporary,"%s.%s",pobj_c->name,member->name);
[64]100 dim(
[4]101 temporary,
[53]102 member->SubScripts,
[75]103 *member,
[53]104 member->InitBuf,
105 member->ConstractParameter,
[4]106 0);
107
108 //ネイティブコードバッファの再確保
[89]109 ReallocNativeCodeBuffer();
110
[67]111 i++;
[4]112 }
113 }
114
115 cp=back_cp;
116}
117
118
119
[100]120//コピーコンストラクタ
121CMethod::CMethod(CMethod *pMethod)
122 : pUserProc( pMethod->pUserProc )
123 , dwAccess( pMethod->dwAccess )
124 , bAbstract( pMethod->bAbstract )
125 , bVirtual( pMethod->bVirtual )
126 , isConst( pMethod->isConst )
127 , isStatic( pMethod->isStatic )
128{
129}
[4]130
[100]131CMethod::CMethod( UserProc *pUserProc, DWORD dwAccess, BOOL bAbstract, BOOL bVirtual, bool isConst, bool isStatic )
132 : pUserProc( pUserProc )
133 , dwAccess( dwAccess )
134 , bAbstract( bAbstract )
135 , bVirtual( bVirtual )
136 , isConst( isConst )
137 , isStatic( isStatic )
138 , pobj_InheritsClass( NULL )
139{
[4]140}
141CMethod::~CMethod(){
142}
143
144
145
[101]146CClass::CClass( const NamespaceScopes &namespaceScopes, const char *name ):
147 namespaceScopes( namespaceScopes ),
[90]148 ConstructorMemberSubIndex( 0 ),
149 DestructorMemberSubIndex( 0 ),
150 classType( Class ),
[91]151 isUsing( false ),
[90]152 pobj_InheritsClass( NULL ),
153 ppobj_Member( NULL ),
154 iMemberNum( 0 ),
155 vtbl_num( 0 ),
156 iAlign( 0 ),
157 vtbl_offset( -1 ),
158 isCompilingConstructor( false ),
159 isCompilingDestructor( false ),
160 pobj_NextClass( NULL )
161{
[4]162 this->name=(char *)HeapAlloc(hHeap,0,lstrlen(name)+1);
163 lstrcpy(this->name,name);
164}
165CClass::~CClass(){
166 int i;
167
168 //クラス名
169 HeapDefaultFree(name);
170
171 if(ppobj_Member){
172 //メンバ
173 for(i=0;i<iMemberNum;i++){
174 delete ppobj_Member[i];
175 }
176 HeapDefaultFree(ppobj_Member);
177 ppobj_Member=0;
178 }
179
[53]180 //静的メンバ
181 foreach( CMember *member, staticMembers ){
182 delete member;
[4]183 }
184
[51]185 //メソッド
186 foreach( CMethod *method, methods ){
[50]187 delete method;
[4]188 }
[51]189
190 //静的メソッド
191 foreach( CMethod *method, staticMethods ){
192 delete method;
193 }
[4]194}
[64]195
[102]196bool CClass::IsEqualSymbol( const NamespaceScopes &namespaceScopes, const string &name ) const
[101]197{
[102]198 if( GetName() != name ){
199 return false;
200 }
201
202 return NamespaceScopes::IsSameArea( GetNamespaceScopes(), namespaceScopes );
[101]203}
[102]204bool CClass::IsEqualSymbol( const CClass &objClass ) const
205{
206 return IsEqualSymbol( objClass.GetNamespaceScopes(), objClass.GetName() );
207}
208bool CClass::IsEqualSymbol( const string &fullName ) const
209{
210 char AreaName[VN_SIZE] = ""; //オブジェクト変数
211 char NestName[VN_SIZE] = ""; //入れ子メンバ
212 bool isNest = SplitMemberName( fullName.c_str(), AreaName, NestName );
[101]213
[102]214 return IsEqualSymbol( NamespaceScopes( AreaName ), NestName );
215}
216
[91]217bool CClass::IsUsing() const
218{
219 return isUsing;
220}
221void CClass::Using(){
222 isUsing = true;
223}
224
[90]225bool CClass::IsClass() const
226{
227 return classType == CClass::Class;
228}
229bool CClass::IsInterface() const
230{
231 return classType == CClass::Interface;
232}
233bool CClass::IsEnum() const
234{
235 return classType == CClass::Enum;
236}
237bool CClass::IsDelegate() const
238{
239 return classType == CClass::Delegate;
240}
[64]241bool CClass::IsStructure() const
242{
243 return classType == CClass::Structure;
244}
245
[90]246bool CClass::Inherits( CClass &inheritsClass, int nowLine ){
[29]247
[90]248 //ループ継承でないかをチェック
249 if(pobj_LoopRefCheck->check(inheritsClass)){
250 SetError(123,inheritsClass.name,nowLine);
251 return false;
252 }
253
254 if( inheritsClass.ppobj_Member == 0 ){
255 //継承先が読み取られていないとき
256 pobj_LoopRefCheck->add(this->name);
257 pobj_DBClass->GetClass_recur(inheritsClass.name);
258 pobj_LoopRefCheck->del(this->name);
259 }
260
[29]261 //メンバをコピー
262 ppobj_Member=(CMember **)HeapReAlloc(
263 hHeap,
264 0,
265 ppobj_Member,
[90]266 ( iMemberNum + inheritsClass.iMemberNum )*sizeof(CMember *));
267 for(int i3=0;i3<inheritsClass.iMemberNum;i3++){
268 ppobj_Member[iMemberNum]=new CMember( *inheritsClass.ppobj_Member[i3] );
[29]269
270 //dwAccess
[90]271 if(inheritsClass.ppobj_Member[i3]->dwAccess==ACCESS_PRIVATE)
272 ppobj_Member[iMemberNum]->dwAccess=ACCESS_NON;
273 else ppobj_Member[iMemberNum]->dwAccess=inheritsClass.ppobj_Member[i3]->dwAccess;
274
275 iMemberNum++;
[29]276 }
277
278 //メソッドをコピー
[90]279 foreach( CMethod *baseMethod, inheritsClass.methods ){
[51]280 CMethod *method = new CMethod( baseMethod );
[29]281
282 //dwAccess
[51]283 if(baseMethod->dwAccess==ACCESS_PRIVATE)
284 method->dwAccess=ACCESS_NON;
285 else method->dwAccess=baseMethod->dwAccess;
[29]286
287 //pobj_Inherits
288 // ※継承元のClassIndexをセット(入れ子継承を考慮する)
[51]289 if(baseMethod->pobj_InheritsClass==0)
[90]290 method->pobj_InheritsClass=&inheritsClass;
[29]291 else
[51]292 method->pobj_InheritsClass=
293 baseMethod->pobj_InheritsClass;
294
295 methods.push_back( method );
[29]296 }
297
298 //仮想関数の数
[90]299 vtbl_num += inheritsClass.vtbl_num;
[29]300
301 //継承先のクラスをメンバとして保持する
[90]302 pobj_InheritsClass = &inheritsClass;
303
304 return true;
[29]305}
[90]306bool CClass::InheritsInterface( CClass &inheritsInterface, int nowLine ){
307
308 //ループ継承でないかをチェック
309 if(pobj_LoopRefCheck->check(inheritsInterface)){
310 SetError(123,inheritsInterface.name,nowLine);
311 return false;
312 }
313
314 if( inheritsInterface.ppobj_Member == 0 ){
315 //継承先が読み取られていないとき
316 pobj_LoopRefCheck->add(this->name);
317 pobj_DBClass->GetClass_recur(inheritsInterface.name);
318 pobj_LoopRefCheck->del(this->name);
319 }
320
321 //メソッドをコピー
322 foreach( CMethod *baseMethod, inheritsInterface.methods ){
323 CMethod *method = new CMethod( baseMethod );
324
325 //dwAccess
326 if(baseMethod->dwAccess==ACCESS_PRIVATE)
327 method->dwAccess=ACCESS_NON;
328 else method->dwAccess=baseMethod->dwAccess;
329
330 //pobj_Inherits
331 // ※継承元のClassIndexをセット(入れ子継承を考慮する)
332 if(baseMethod->pobj_InheritsClass==0)
333 method->pobj_InheritsClass=&inheritsInterface;
334 else
335 method->pobj_InheritsClass=
336 baseMethod->pobj_InheritsClass;
337
338 methods.push_back( method );
339 }
340
341 //仮想関数の数
342 vtbl_num += inheritsInterface.vtbl_num;
343
344 /*
345 TODO: インターフェイス向けの機構を作る
346 //継承先のクラスをメンバとして保持する
347 pobj_InheritsClass = &inheritsInterface;
348 */
349
350 return true;
351}
[40]352void CClass::AddMember( DWORD dwAccess, bool isConst, bool isRef, char *buffer ){
[17]353 ppobj_Member = (CMember **)HeapReAlloc( hHeap, 0, ppobj_Member, ( iMemberNum + 1 ) * sizeof(CMember *) );
[40]354 ppobj_Member[iMemberNum] = new CMember( this, dwAccess, isConst, isRef, buffer );
[4]355 iMemberNum++;
356}
[75]357void CClass::AddStaticMember( DWORD dwAccess, bool isConst, bool isRef, char *buffer, int nowLine ){
358 CMember *member = new CMember( this, dwAccess, isConst, isRef, buffer, nowLine );
[53]359 staticMembers.push_back( member );
[4]360}
[75]361void CClass::AddMethod( UserProc *pUserProc,DWORD dwAccess, bool isConst, BOOL bAbstract, BOOL bVirtual ){
[100]362 CMethod *method = new CMethod( pUserProc, dwAccess, bAbstract, bVirtual, isConst, false );
[4]363
[51]364 methods.push_back( method );
[75]365
366 // プロシージャオブジェクトと関連付け
367 pUserProc->SetMethod( method );
[4]368}
[75]369void CClass::AddStaticMethod(UserProc *pUserProc,DWORD dwAccess){
[100]370 CMethod *method = new CMethod( pUserProc, dwAccess, FALSE, FALSE, false, true );
[4]371
[51]372 staticMethods.push_back( method );
[75]373
374 // プロシージャオブジェクトと関連付け
375 pUserProc->SetMethod( method );
[4]376}
[46]377BOOL CClass::DupliCheckAll(const char *name){
[4]378 //重複チェック
379
380 //メンバ
381 if(DupliCheckMember(name)) return 1;
382
383 //メソッド
[51]384 foreach( CMethod *method, methods ){
[75]385 if( lstrcmp( name, method->pUserProc->GetName().c_str() ) == 0 ){
[4]386 return 1;
387 }
388 }
389
390 return 0;
391}
[46]392BOOL CClass::DupliCheckMember(const char *name){
[4]393 //重複チェック
394
395 //メンバ
[53]396 for( int i=0;i<iMemberNum;i++){
[4]397 if(lstrcmp(name,ppobj_Member[i]->name)==0){
398 return 1;
399 }
400 }
401
402 //静的メンバ
[53]403 foreach( CMember *member, staticMembers ){
404 if( lstrcmp( name, member->name ) == 0 ){
[4]405 return 1;
406 }
407 }
408
409 return 0;
410}
[75]411CMethod *CClass::GetMethodInfo( UserProc *pUserProc ) const
412{
[51]413 for( int i=(int)methods.size()-1; i>=0; i-- ){
[89]414 if( pUserProc == methods[i]->pUserProc ){
415 return methods[i];
416 }
[18]417 }
[50]418 return NULL;
[18]419}
[75]420CMethod *CClass::GetStaticMethodInfo( UserProc *pUserProc ) const
421{
[51]422 for( int i=(int)staticMethods.size()-1; i>=0; i-- ){
[75]423 if( pUserProc == staticMethods[i]->pUserProc ) return staticMethods[i];
[18]424 }
[50]425 return NULL;
[18]426}
[75]427bool CClass::IsExistMethod( const char *name ) const
428{
[51]429 foreach( CMethod *method, methods ){
[75]430 if( method->pUserProc->GetName() == name ) return true;
[27]431 }
432 return false;
433}
[75]434bool CClass::IsExistStaticMethod( const char *name ) const
435{
[51]436 foreach( CMethod *method, staticMethods ){
[75]437 if( method->pUserProc->GetName() == name ) return true;
[27]438 }
439 return false;
440}
[4]441
[100]442void CClass::EnumStaticMethod( const char *methodName, vector<UserProc *> &subs ) const
[50]443{
[51]444 foreach( CMethod *method, staticMethods ){
[75]445 if( method->pUserProc->GetName() == methodName ){
446 subs.push_back( method->pUserProc );
[50]447 }
448 }
449}
[27]450
[100]451void CClass::EnumMethod( const char *methodName, vector<UserProc *> &subs ) const
[50]452{
453 //オブジェクトのメンバ関数の場合
454 //※オーバーライドされた関数を先にサーチする必要があるため、バックサーチを行う
[51]455 for( int i=(int)methods.size()-1; i>=0; i-- ){
[75]456 if( methods[i]->pUserProc->GetName() == methodName ){
457 subs.push_back( methods[i]->pUserProc );
[50]458 }
459 }
460}
461
[100]462void CClass::EnumMethod( const BYTE idOperatorCalc, vector<UserProc *> &subs ) const
[50]463{
[51]464 //オブジェクトのメンバ関数の場合
465 //※オーバーライドされた関数を先にサーチする必要があるため、バックサーチを行う
466 for( int i=(int)methods.size()-1; i>=0; i-- ){
[75]467 UserProc *pUserProc = methods[i]->pUserProc;
468 const char *temp = pUserProc->GetName().c_str();
[50]469 if(temp[0]==1&&temp[1]==ESC_OPERATOR){
470 if((BYTE)temp[2]==idOperatorCalc){
[75]471 subs.push_back( pUserProc );
[50]472 }
473 }
474 }
475}
476
[51]477//デフォルト コンストラクタ メソッドを取得
478CMethod *CClass::GetConstructorMethod() const
479{
480 if( ConstructorMemberSubIndex == -1 ) return NULL;
481 return methods[ConstructorMemberSubIndex];
482}
[50]483
[51]484//デストラクタ メソッドを取得
485CMethod *CClass::GetDestructorMethod() const
486{
487 if( DestructorMemberSubIndex == -1 ) return NULL;
488 return methods[DestructorMemberSubIndex];
489}
490
[63]491//サイズを取得
492int CClass::GetSize() const
493{
494 return GetMemberOffset( NULL, NULL );
495}
[51]496
[63]497//メンバのオフセットを取得
498int CClass::GetMemberOffset( const char *memberName, int *pMemberNum ) const
499{
500 int i,i2,offset;
501
502 //仮想関数が存在する場合は関数リストへのポインタのサイズを追加
503 if(vtbl_num) offset=PTR_SIZE;
504 else offset=0;
505
506 int alignment;
507 if(iAlign) alignment=iAlign;
508 else alignment=1;
509
510 int iMaxAlign=0;
511 for(i=0;i<iMemberNum;i++){
512 CMember *pMember = ppobj_Member[i];
513
514 i2 = pMember->GetSize();
515
516 //アラインメントを算出
517 int member_size;
[75]518 if( pMember->IsStruct() ){
[63]519 //メンバクラスのアラインメントを取得
[75]520 member_size=pMember->GetClass().GetAlignment();
[63]521 }
522 else{
523 //メンバサイズを取得
524 member_size=i2;
525 }
526 if(iMaxAlign<member_size) iMaxAlign=member_size;
527
528 //アラインメントを考慮
529 if(iAlign&&iAlign<member_size){
530 if(offset%alignment) offset+=alignment-(offset%alignment);
531 }
532 else{
533 if(alignment<member_size) alignment=member_size;
534
535 if(member_size==0){
536 //メンバを持たないクラス
537 //※何もしない(オフセットの計算をしない)
538 }
539 else{
540 if(offset%member_size) offset+=member_size-(offset%member_size);
541 }
542 }
543
544 if(memberName){
545 //メンバ指定がある場合は、オフセットを返す
546 if(lstrcmp(pMember->name,memberName)==0){
547 if(pMemberNum) *pMemberNum=i;
548 return offset;
549 }
550 }
551
552 //配列を考慮したメンバサイズを取得
553 member_size=i2 * JumpSubScripts(pMember->SubScripts);
554
555 //メンバサイズを加算
556 offset+= member_size;
557 }
558
559 if(iMaxAlign<alignment) alignment=iMaxAlign;
560
561 //アラインメントを考慮
562 if(alignment){
563 if(offset%alignment) offset+=alignment-(offset%alignment);
564 }
565
566 if(pMemberNum) *pMemberNum=i;
567 return offset;
568}
569
570int CClass::GetAlignment() const
571{
572 int i;
573 int alignment,member_size;
574
575 if(vtbl_num) alignment=PTR_SIZE;
576 else alignment=0;
577
578 for(i=0;i<iMemberNum;i++){
579 CMember *pMember = ppobj_Member[i];
580
[75]581 if(pMember->IsStruct()){
[63]582 //メンバクラスのアラインメントを取得
[75]583 member_size=pMember->GetClass().GetAlignment();
[63]584 }
585 else{
586 //メンバサイズを取得
587 member_size = pMember->GetSize();
588 }
589
590 //アラインメントをセット
591 if(alignment<member_size) alignment=member_size;
592 }
593
594 if(alignment==0) return 0;
595
596 if(iAlign) alignment=iAlign;
597
598 return alignment;
599}
600
601
602
[75]603int CClass::GetFuncNumInVtbl( const UserProc *pUserProc ) const
[51]604{
605 int n = 0;
606 foreach( CMethod *method, methods ){
[75]607 if( method->pUserProc == pUserProc ) break;
608 if( method->bVirtual ) n++;
[51]609 }
610 return n;
611}
[4]612LONG_PTR CClass::GetVtblGlobalOffset(void){
[28]613
614 //既に存在する場合はそれを返す
[4]615 if(vtbl_offset!=-1) return vtbl_offset;
616
[28]617
[92]618
[28]619 //////////////////////////////////////
620 // 存在しないときは新たに生成する
621 //////////////////////////////////////
622
[75]623 UserProc **ppsi;
[100]624 ppsi=(UserProc **)HeapAlloc(hHeap,0,vtbl_num*sizeof(GlobalProc *));
[4]625
626 //関数テーブルに値をセット
[51]627 int i2 = 0;
628 foreach( CMethod *method, methods ){
629 if(method->bVirtual){
[75]630 method->pUserProc->Using();
[4]631
[51]632 if(method->bAbstract){
[28]633 extern int cp;
634 SetError(300,NULL,cp);
[4]635
[28]636 ppsi[i2]=0;
[4]637 }
[92]638 else{
639 ppsi[i2]=method->pUserProc;
640 }
[28]641 i2++;
[4]642 }
643 }
644
[56]645 vtbl_offset=dataTable.AddBinary((void *)ppsi,vtbl_num*sizeof(LONG_PTR));
[4]646
[28]647 for( int i=0; i < vtbl_num; i++ ){
[4]648 pobj_Reloc->AddSchedule_DataSection(vtbl_offset+i*sizeof(LONG_PTR));
649 }
650
651 HeapDefaultFree(ppsi);
652
653 return vtbl_offset;
654}
655void CClass::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){
656 if(vtbl_offset==-1) return;
657
658 LONG_PTR *pVtbl;
[56]659 pVtbl=(LONG_PTR *)((char *)dataTable.GetPtr()+vtbl_offset);
[4]660
661 int i;
662 for(i=0;i<vtbl_num;i++){
[100]663 GlobalProc *pUserProc;
664 pUserProc=(GlobalProc *)pVtbl[i];
[75]665 if(!pUserProc) continue;
666 pVtbl[i]=pUserProc->beginOpAddress+ImageBase+MemPos_CodeSection;
[4]667 }
668}
[75]669bool CClass::IsAbstract() const
670{
[96]671 // 未実装(abstract)の仮想関数を持つ場合はtrueを返す
[4]672
[51]673 foreach( CMethod *method, methods ){
674 if(method->bVirtual){
675 if(method->bAbstract){
[28]676 return true;
[4]677 }
678 }
679 }
680
[28]681 return false;
[4]682}
683
[17]684// コンストラクタのコンパイルを開始
685void CClass::NotifyStartConstructorCompile(){
686 isCompilingConstructor = true;
687}
[4]688
[17]689//コンストラクタのコンパイルを終了
690void CClass::NotifyFinishConstructorCompile(){
691 isCompilingConstructor = false;
692}
693
694//コンストラクタをコンパイル中かどうかを判別
[75]695bool CClass::IsCompilingConstructor() const
696{
[17]697 return isCompilingConstructor;
698}
699
[18]700//デストラクタのコンパイルを開始
701void CClass::NotifyStartDestructorCompile(){
702 isCompilingDestructor = true;
703}
[17]704
[18]705//デストラクタのコンパイルを終了
706void CClass::NotifyFinishDestructorCompile(){
707 isCompilingDestructor = false;
708}
709
710//デストラクタをコンパイル中かどうかを判別
[75]711bool CClass::IsCompilingDestructor() const
712{
[18]713 return isCompilingDestructor;
714}
715
716
[28]717//自身と等しいクラスかどうかを確認
[75]718bool CClass::IsEquals( const CClass *pClass ) const
719{
[28]720 if( this == pClass ) return true;
721 return false;
722}
723
724//自身の派生クラスかどうかを確認
[75]725bool CClass::IsSubClass( const CClass *pClass ) const
726{
[28]727 pClass = pClass->pobj_InheritsClass;
728 while( pClass ){
729 if( this == pClass ) return true;
730 pClass = pClass->pobj_InheritsClass;
731 }
732 return false;
733}
734
[59]735//自身と等しいまたは派生クラスかどうかを確認
[75]736bool CClass::IsEqualsOrSubClass( const CClass *pClass ) const
737{
[59]738 if( IsEquals( pClass ) ) return true;
739 return IsSubClass( pClass );
740}
[28]741
[94]742// 自身と等しいまたは派生クラス、基底クラスかどうかを確認
743bool CClass::IsEqualsOrSubClassOrSuperClass( const CClass &objClass ) const
744{
745 if( IsEquals( &objClass ) ) return true;
746 if( IsSubClass( &objClass ) ) return true;
747 if( objClass.IsSubClass( this ) ) return true;
748 return false;
749}
[28]750
[59]751
[94]752
[102]753int CDBClass::hash(const char *name) const{
[4]754 int key;
755
756 for(key=0;*name!='\0';name++){
757 key=((key<<8)+ *name )%MAX_CLASS_HASH;
758 }
759
760 return key;
761}
762
763void CDBClass::DestroyClass(CClass *pobj_c){
764 if(pobj_c->pobj_NextClass){
765 DestroyClass(pobj_c->pobj_NextClass);
766 }
767
768 delete pobj_c;
769}
770
[67]771CDBClass::CDBClass():
772 pStringClass( NULL ),
773 pObjectClass( NULL ),
774 pCompilingClass( NULL ),
775 pCompilingMethod( NULL ),
776 ppobj_IteClass( NULL ),
777 iIteMaxNum( 0 ),
778 iIteNextNum( 0 )
779{
780 memset( pobj_ClassHash, 0, MAX_CLASS_HASH * sizeof(CClass *) );
[4]781}
782CDBClass::~CDBClass(){
783 int i;
784 for(i=0;i<MAX_CLASS_HASH;i++){
785 if(pobj_ClassHash[i]) DestroyClass(pobj_ClassHash[i]);
786 }
787
788 if(ppobj_IteClass) HeapDefaultFree(ppobj_IteClass);
789}
790
791void CDBClass::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){
792 int i;
793 for(i=0;i<MAX_CLASS_HASH;i++){
794 if(pobj_ClassHash[i]){
795 CClass *pobj_c;
796 pobj_c=pobj_ClassHash[i];
797 while(1){
798 pobj_c->ActionVtblSchedule(ImageBase,MemPos_CodeSection);
799
800 if(pobj_c->pobj_NextClass==0) break;
801 pobj_c=pobj_c->pobj_NextClass;
802 }
803 }
804 }
805}
806
[102]807CClass *CDBClass::Find( const string &fullName ) const
808{
809 char AreaName[VN_SIZE] = ""; //オブジェクト変数
810 char NestName[VN_SIZE] = ""; //入れ子メンバ
811 bool isNest = SplitMemberName( fullName.c_str(), AreaName, NestName );
812
[4]813 int key;
[102]814 key=hash(NestName);
[4]815
816 if(pobj_ClassHash[key]){
817 CClass *pobj_c;
818 pobj_c=pobj_ClassHash[key];
819 while(1){
[102]820 if( pobj_c->IsEqualSymbol( fullName ) ){
821 //名前空間とクラス名が一致した
[4]822 return pobj_c;
823 }
824
825 if(pobj_c->pobj_NextClass==0) break;
826 pobj_c=pobj_c->pobj_NextClass;
827 }
828 }
[100]829 return NULL;
[4]830}
[102]831CClass *CDBClass::Find( const NamespaceScopes &namespaceScopes, const string &name ) const
832{
833 int key;
834 key=hash(name.c_str());
[4]835
[102]836 if(pobj_ClassHash[key]){
837 CClass *pobj_c;
838 pobj_c=pobj_ClassHash[key];
839 while(1){
840 if( pobj_c->IsEqualSymbol( namespaceScopes, name ) ){
841 //名前空間とクラス名が一致した
842 return pobj_c;
843 }
844
845 if(pobj_c->pobj_NextClass==0) break;
846 pobj_c=pobj_c->pobj_NextClass;
847 }
848 }
849 return NULL;
850}
851
[101]852CClass *CDBClass::AddClass( const NamespaceScopes &namespaceScopes, const char *name,int nowLine){
[4]853 //////////////////////////////////////////////////////////////////////////
854 // クラスを追加
855 // ※名前のみを登録。その他の情報はSetClassメソッドで!
856 //////////////////////////////////////////////////////////////////////////
857
858 CClass *pobj_c;
[101]859 pobj_c=new CClass(namespaceScopes, name);
[4]860
861 if(lstrcmp(name,"String")==0){
862 //Stringクラス
863 pobj_StringClass=pobj_c;
864 }
[67]865 if( lstrcmp( name, "Object" ) == 0 ){
866 pObjectClass = pobj_c;
867 }
[4]868
869
870 /////////////////////////////////
871 // ハッシュデータに追加
872 /////////////////////////////////
873
874 int key;
875 key=hash(name);
876
877 if(pobj_ClassHash[key]){
878 CClass *pobj_c2;
879 pobj_c2=pobj_ClassHash[key];
880 while(1){
[102]881 if( pobj_c2->IsEqualSymbol( namespaceScopes, name ) ){
882 //名前空間及びクラス名が重複した場合
[75]883 SetError(15,name,nowLine);
[4]884 return 0;
885 }
886
887 if(pobj_c2->pobj_NextClass==0) break;
888 pobj_c2=pobj_c2->pobj_NextClass;
889 }
890 pobj_c2->pobj_NextClass=pobj_c;
891 }
892 else{
893 pobj_ClassHash[key]=pobj_c;
894 }
895
896 return pobj_c;
897}
898
899void CDBClass::InitNames(void){
900 extern char *basbuf;
[101]901 int i, i2;
902 char temporary[VN_SIZE];
[4]903
[101]904 // 名前空間管理
905 NamespaceScopes &namespaceScopes = Smoothie::Lexical::liveingNamespaceScopes;
906 namespaceScopes.clear();
907
[4]908 for(i=0;;i++){
909 if(basbuf[i]=='\0') break;
910
[101]911 if( basbuf[i] == 1 && basbuf[i+1] == ESC_NAMESPACE ){
912 for(i+=2,i2=0;;i2++,i++){
913 if( IsCommandDelimitation( basbuf[i] ) ){
914 temporary[i2]=0;
915 break;
916 }
917 temporary[i2]=basbuf[i];
918 }
919 namespaceScopes.push_back( temporary );
920
921 continue;
922 }
923 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENDNAMESPACE ){
924 if( namespaceScopes.size() <= 0 ){
925 SetError(12, "End Namespace", i );
926 }
927 else{
928 namespaceScopes.pop_back();
929 }
930
931 i += 2;
932 continue;
933 }
934
[4]935 if(basbuf[i]==1&&(
936 basbuf[i+1]==ESC_CLASS||
937 basbuf[i+1]==ESC_TYPE||
938 basbuf[i+1]==ESC_INTERFACE
939 )){
[75]940 int nowLine;
941 nowLine=i;
[4]942
943 i+=2;
944 //アラインメント修飾子
[76]945 if(memicmp(basbuf+i,"Align(",6)==0){
[4]946 i+=6;
947 i=JumpStringInPare(basbuf,i)+1;
948 }
949
[92]950 bool isEnum = false;
951 if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENUM ){
952 // 列挙型の場合
953 isEnum = true;
954
955 i+=2;
956 }
957
[4]958 int i2;
959 char temporary[VN_SIZE];
960 for(i2=0;;i++,i2++){
961 if(!IsVariableChar(basbuf[i])){
962 temporary[i2]=0;
963 break;
964 }
965 temporary[i2]=basbuf[i];
966 }
967
968 //クラスを追加
[101]969 CClass *pClass = pobj_DBClass->AddClass(namespaceScopes, temporary,nowLine);
[64]970 if( pClass ){
[75]971 if( basbuf[nowLine+1] == ESC_CLASS ){
[92]972 if( isEnum ){
973 pClass->classType = CClass::Enum;
974 }
975 else{
976 pClass->classType = CClass::Class;
977 }
[64]978 }
[75]979 else if( basbuf[nowLine+1] == ESC_INTERFACE ){
[64]980 pClass->classType = CClass::Interface;
981 }
982 else{
983 pClass->classType = CClass::Structure;
984 }
985 }
[4]986 }
987 }
988}
989
990
[18]991void CDBClass::AddMethod(CClass *pobj_c, DWORD dwAccess, BOOL bStatic, bool isConst, BOOL bAbstract,
[75]992 BOOL bVirtual, BOOL bOverride, char *buffer, int nowLine){
[4]993 int i,i2;
994 char temporary[VN_SIZE];
995
996 i=2;
997 for(i2=0;;i++,i2++){
998 if(buffer[i]=='('||buffer[i]=='\0'){
999 temporary[i2]=0;
1000 break;
1001 }
1002 temporary[i2]=buffer[i];
1003 }
1004
1005
1006 //関数ハッシュへ登録
[100]1007 GlobalProc *pUserProc;
1008 pUserProc=AddSubData( NamespaceScopes(), buffer,nowLine,bVirtual,pobj_c, (bStatic!=0) );
[75]1009 if(!pUserProc) return;
[4]1010
1011
1012 ////////////////////////////////////////////////////////////
[18]1013 // コンストラクタ、デストラクタの場合の処理
[4]1014 ////////////////////////////////////////////////////////////
1015 BOOL fConstructor=0,bDestructor=0;
1016
1017 if(lstrcmp(temporary,pobj_c->name)==0){
[18]1018 //コンストラクタの場合
1019
1020 //標準コンストラクタ(引数なし)
[75]1021 if(pUserProc->Params().size()==0) fConstructor=1;
[18]1022
1023 //強制的にConst修飾子をつける
1024 isConst = true;
[4]1025 }
1026 else if(temporary[0]=='~'){
1027 //デストラクタの場合はその名前が正しいかチェックを行う
1028 if(lstrcmp(temporary+1,pobj_c->name)!=0)
[75]1029 SetError(117,NULL,nowLine);
[4]1030 else
1031 bDestructor=1;
1032 }
1033 if(fConstructor||bDestructor){
[18]1034 // コンストラクタ、デストラクタのアクセシビリティをチェック
1035
1036 //強制的にConst修飾子をつける
1037 isConst = true;
[4]1038 }
1039
[18]1040 if( fConstructor == 1 )
[51]1041 pobj_c->ConstructorMemberSubIndex = (int)pobj_c->methods.size();
[18]1042 else if( bDestructor )
[51]1043 pobj_c->DestructorMemberSubIndex = (int)pobj_c->methods.size();
[4]1044
1045
1046
1047 //////////////////
1048 // 重複チェック
1049 //////////////////
1050
1051 if(pobj_c->DupliCheckMember(temporary)){
[75]1052 SetError(15,temporary,nowLine);
[4]1053 return;
1054 }
1055
[51]1056 //メソッド
1057 foreach( CMethod *method, pobj_c->methods ){
[27]1058 //基底クラスと重複する場合はオーバーライドを行う
[51]1059 if(method->pobj_InheritsClass) continue;
[4]1060
[75]1061 if( method->pUserProc->GetName() == temporary ){
1062 if( Parameter::Equals( method->pUserProc->Params(), pUserProc->Params() ) ){
[4]1063 //関数名、パラメータ属性が合致したとき
[75]1064 SetError(15,pUserProc->GetName().c_str(),nowLine);
[4]1065 return;
1066 }
1067 }
1068 }
1069
1070 //仮想関数の場合
[75]1071 if(bAbstract) pUserProc->CompleteCompile();
[4]1072
[51]1073 //メソッドのオーバーライド
1074 foreach( CMethod *method, pobj_c->methods ){
[75]1075 if( method->pUserProc->GetName() == temporary ){
1076 if( Parameter::Equals( method->pUserProc->Params(), pUserProc->Params() ) ){
[4]1077
[75]1078 if(method->bVirtual){
[4]1079 //メンバ関数を上書き
[75]1080 method->pUserProc=pUserProc;
[51]1081 method->bAbstract=0;
[4]1082
1083 if(!bOverride){
[75]1084 SetError(127,NULL,nowLine);
[4]1085 }
[51]1086 if(method->dwAccess!=dwAccess){
[75]1087 SetError(128,NULL,nowLine);
[4]1088 }
[75]1089
1090 pUserProc->SetMethod( method );
[4]1091 return;
1092 }
1093 }
1094 }
1095 }
1096
[75]1097 if(bVirtual){
[4]1098 pobj_c->vtbl_num++;
1099 }
1100
1101 if(bOverride){
[75]1102 SetError(12,"Override",nowLine);
[4]1103 }
1104
1105 if(bStatic){
[75]1106 pobj_c->AddStaticMethod(pUserProc,dwAccess);
[4]1107 }
1108 else{
[75]1109 pobj_c->AddMethod(pUserProc, dwAccess, isConst, bAbstract, bVirtual);
[4]1110 }
1111}
1112
[75]1113BOOL CDBClass::MemberVar_LoopRefCheck(const CClass &objClass){
[4]1114 int i,i2,bRet=1;
[75]1115 for(i=0;i<objClass.iMemberNum;i++){
1116 const CMember *pMember = objClass.ppobj_Member[i];
[85]1117 if(pMember->IsStruct()){
[4]1118 //循環参照でないかをチェック
[90]1119 if(pobj_LoopRefCheck->check(pMember->GetClass())){
[4]1120 extern int cp;
[75]1121 SetError(124,pMember->GetClass().name,cp);
[4]1122 return 0;
1123 }
1124
[75]1125 pobj_LoopRefCheck->add(objClass.name);
[4]1126
[75]1127 i2=MemberVar_LoopRefCheck(pMember->GetClass());
[4]1128 if(bRet==1) bRet=i2;
1129
[75]1130 pobj_LoopRefCheck->del(objClass.name);
[4]1131 }
1132 }
1133
1134 return bRet;
1135}
1136
[46]1137void CDBClass::GetClass_recur(const char *lpszInheritsClass){
[4]1138 extern char *basbuf;
1139 int i,i2,i3,sub_address,top_pos;
1140 DWORD dwAccess;
1141 char temporary[8192];
1142
[102]1143 // 名前空間管理
1144 NamespaceScopes &namespaceScopes = Smoothie::Lexical::liveingNamespaceScopes;
1145 namespaceScopes.clear();
1146
[4]1147 for(i=0;;i++){
1148 if(basbuf[i]=='\0') break;
1149
1150
[102]1151 // 名前空間
1152 if( basbuf[i] == 1 && basbuf[i+1] == ESC_NAMESPACE ){
1153 for(i+=2,i2=0;;i2++,i++){
1154 if( IsCommandDelimitation( basbuf[i] ) ){
1155 temporary[i2]=0;
1156 break;
1157 }
1158 temporary[i2]=basbuf[i];
1159 }
1160 namespaceScopes.push_back( temporary );
1161
1162 continue;
1163 }
1164 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENDNAMESPACE ){
1165 if( namespaceScopes.size() <= 0 ){
1166 SetError(12, "End Namespace", i );
1167 }
1168 else{
1169 namespaceScopes.pop_back();
1170 }
1171
1172 i += 2;
1173 continue;
1174 }
1175
1176
1177
[4]1178 if(basbuf[i]==1&&basbuf[i+1]==ESC_INTERFACE){
1179 //////////////////////////
1180 // インターフェイス
1181 //////////////////////////
1182
1183 top_pos=i;
1184
1185 i+=2;
1186
1187 //インターフェイス名を取得
[17]1188 GetIdentifierToken( temporary, basbuf, i );
[4]1189
[102]1190 CClass *pobj_c=pobj_DBClass->Find(namespaceScopes, temporary);
[4]1191 if(!pobj_c) continue;
1192
1193 if(lpszInheritsClass){
1194 if(lstrcmp(lpszInheritsClass,pobj_c->name)!=0){
1195 //継承先先読み用
1196 continue;
1197 }
1198 }
1199
1200 if(pobj_c->ppobj_Member){
1201 //既に先読みされているとき
1202 continue;
1203 }
1204
1205 //メンバ用メモリを初期化
1206 pobj_c->ppobj_Member=(CMember **)HeapAlloc(hHeap,0,1);
1207 pobj_c->iMemberNum=0;
1208
1209 pobj_c->ConstructorMemberSubIndex=-1;
1210 pobj_c->DestructorMemberSubIndex=-1;
1211
1212 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS){
1213 //継承を行う場合
1214 for(i+=3,i2=0;;i++,i2++){
1215 if(IsCommandDelimitation(basbuf[i])){
1216 temporary[i2]=0;
1217 break;
1218 }
1219 temporary[i2]=basbuf[i];
1220 }
1221
1222 if(lstrcmpi(temporary,pobj_c->name)==0){
1223 SetError(105,temporary,i);
1224 goto Interface_InheritsError;
1225 }
1226
1227 //継承元クラスを取得
[102]1228 CClass *pInheritsClass = Find(temporary);
[29]1229 if( !pInheritsClass ){
[4]1230 SetError(106,temporary,i);
1231 goto Interface_InheritsError;
1232 }
1233
[90]1234 //継承させる
1235 if( !pobj_c->InheritsInterface( *pInheritsClass, i ) ){
[4]1236 goto Interface_InheritsError;
1237 }
1238 }
1239 else{
1240 //継承無し
1241 pobj_c->pobj_InheritsClass=0;
1242
1243 //仮想関数の数を初期化
1244 pobj_c->vtbl_num=0;
1245 }
1246Interface_InheritsError:
1247
1248 //メンバ変数、関数を取得
1249 while(1){
1250 i++;
1251
1252 //エラー
1253 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE||basbuf[i+1]==ESC_INTERFACE)){
1254 SetError(22,"Interface",i);
1255 i--;
1256 break;
1257 }
1258
1259 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
1260 SetError(111,NULL,i);
1261 break;
1262 }
1263
1264 sub_address=i;
1265
1266 for(i2=0;;i++,i2++){
1267 if(IsCommandDelimitation(basbuf[i])){
1268 temporary[i2]=0;
1269 break;
1270 }
1271 temporary[i2]=basbuf[i];
1272 }
1273 if(temporary[0]=='\0'){
1274 if(basbuf[i]=='\0'){
1275 i--;
1276 SetError(22,"Interface",top_pos);
1277 break;
1278 }
1279 continue;
1280 }
1281
1282 //End Interface記述の場合
1283 if(temporary[0]==1&&temporary[1]==ESC_ENDINTERFACE) break;
1284
1285 if(!(temporary[0]==1&&(
1286 temporary[1]==ESC_SUB||temporary[1]==ESC_FUNCTION
1287 ))){
1288 SetError(1,NULL,i);
1289 break;
1290 }
1291
1292 //メンバ関数を追加
[18]1293 AddMethod(pobj_c,
1294 ACCESS_PUBLIC, //Publicアクセス権
1295 0, //Static指定なし
1296 false, //Constではない
1297 1, //Abstract
1298 1, //Virtual
1299 0,
1300 temporary,
1301 sub_address
1302 );
[4]1303 }
1304 }
1305
1306 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
1307 //////////////////////////
1308 // クラス
1309 //////////////////////////
1310
1311 top_pos=i;
1312
[64]1313 const DWORD dwClassType=basbuf[i+1];
[4]1314
1315 i+=2;
1316
1317 //アラインメント修飾子
1318 int iAlign=0;
[76]1319 if(memicmp(basbuf+i,"Align(",6)==0){
[4]1320 i+=6;
1321 i+=GetStringInPare_RemovePare(temporary,basbuf+i)+1;
1322 iAlign=atoi(temporary);
1323
1324 if(!(iAlign==1||iAlign==2||iAlign==4||iAlign==8||iAlign==16))
1325 SetError(51,NULL,i);
1326 }
1327
[92]1328 if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENUM ){
1329 // 列挙型の場合
1330 i+=2;
1331 }
[4]1332
1333 //クラス名を取得
[17]1334 GetIdentifierToken( temporary, basbuf, i );
[4]1335
[102]1336 CClass *pobj_c=pobj_DBClass->Find(namespaceScopes, temporary);
[4]1337 if(!pobj_c) continue;
1338
1339 if(lpszInheritsClass){
1340 if(lstrcmp(lpszInheritsClass,pobj_c->name)!=0){
1341 //継承先先読み用
1342 continue;
1343 }
1344 }
1345
1346 if(pobj_c->ppobj_Member){
1347 //既に先読みされているとき
1348 continue;
1349 }
1350
1351 pobj_c->iAlign=iAlign;
1352
1353 //メンバ用メモリを初期化
1354 pobj_c->ppobj_Member=(CMember **)HeapAlloc(hHeap,0,1);
1355 pobj_c->iMemberNum=0;
1356
1357 pobj_c->ConstructorMemberSubIndex=-1;
1358 pobj_c->DestructorMemberSubIndex=-1;
1359
1360 //アクセス制限の初期値をセット
1361 if(dwClassType==ESC_CLASS) dwAccess=ACCESS_PRIVATE;
1362 else dwAccess=ACCESS_PUBLIC;
1363
[29]1364 if( lstrcmp( pobj_c->name, "Object" ) == 0 || dwClassType == ESC_TYPE ){
1365 //継承無し
1366 pobj_c->pobj_InheritsClass=0;
1367
1368 //仮想関数の数を初期化
1369 pobj_c->vtbl_num=0;
1370 }
1371 else{
1372 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS){
1373 //継承を行う場合
1374 for(i+=3,i2=0;;i++,i2++){
1375 if(IsCommandDelimitation(basbuf[i])){
1376 temporary[i2]=0;
1377 break;
1378 }
1379 temporary[i2]=basbuf[i];
[4]1380 }
1381
[29]1382 if(lstrcmpi(temporary,pobj_c->name)==0){
1383 SetError(105,temporary,i);
1384 goto InheritsError;
1385 }
[4]1386 }
[29]1387 else{
1388 //Objectを継承する
1389 lstrcpy( temporary, "Object" );
1390 }
[4]1391
1392 //継承元クラスを取得
[102]1393 CClass *pInheritsClass = Find(temporary);
[29]1394 if( !pInheritsClass ){
[4]1395 SetError(106,temporary,i);
1396 goto InheritsError;
1397 }
1398
[90]1399 if( pInheritsClass->IsInterface() ){
1400 // クラスを継承していないとき
[102]1401 CClass *pObjectClass = Find("Object");
[90]1402 if( !pObjectClass ){
1403 SetError(106,"Object",i);
1404 goto InheritsError;
1405 }
[4]1406
[90]1407 if( !pobj_c->Inherits( *pObjectClass, i ) ){
1408 goto InheritsError;
1409 }
[4]1410 }
1411
[29]1412 //継承させる
[90]1413 if( !pobj_c->Inherits( *pInheritsClass, i ) ){
1414 goto InheritsError;
1415 }
[4]1416 }
1417InheritsError:
1418
[18]1419 //メンバとメソッドを取得
[4]1420 while(1){
1421 i++;
1422
1423 //エラー
1424 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
1425 SetError(22,"Class",i);
1426 i--;
1427 break;
1428 }
1429
1430 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
1431 SetError(111,NULL,i);
1432 break;
1433 }
1434
1435 //Static修飾子
1436 BOOL bStatic;
1437 if(basbuf[i]==1&&basbuf[i+1]==ESC_STATIC){
1438 bStatic=1;
1439 i+=2;
1440 }
1441 else bStatic=0;
1442
[17]1443 //Const修飾子
1444 bool isConst = false;
1445 if( basbuf[i] == 1 && basbuf[i + 1] == ESC_CONST ){
1446 isConst = true;
1447 i += 2;
1448 }
[64]1449/*
[40]1450 //Ref修飾子
1451 bool isRef = false;
1452 if( basbuf[i] == 1 && basbuf[i + 1] == ESC_BYREF ){
1453 isRef = true;
1454 i += 2;
[64]1455 }*/
[40]1456
[4]1457 if(basbuf[i]==1&&(
1458 basbuf[i+1]==ESC_ABSTRACT||basbuf[i+1]==ESC_VIRTUAL||basbuf[i+1]==ESC_OVERRIDE||
1459 basbuf[i+1]==ESC_SUB||basbuf[i+1]==ESC_FUNCTION
1460 )){
1461 i3=basbuf[i+1];
1462 sub_address=i;
1463 }
1464 else i3=0;
1465
1466 BOOL bVirtual=0,bAbstract=0,bOverride=0;
1467 if(i3==ESC_ABSTRACT){
1468 bAbstract=1;
1469 bVirtual=1;
1470 i+=2;
1471
1472 i3=basbuf[i+1];
1473 }
1474 else if(i3==ESC_VIRTUAL){
1475 bAbstract=0;
1476 bVirtual=1;
1477 i+=2;
1478
1479 i3=basbuf[i+1];
1480 }
1481 else if(i3==ESC_OVERRIDE){
1482 bOverride=1;
1483 bVirtual=1;
1484
1485 i+=2;
1486
1487 i3=basbuf[i+1];
1488 }
1489
1490 for(i2=0;;i++,i2++){
1491 if(IsCommandDelimitation(basbuf[i])){
1492 temporary[i2]=0;
1493 break;
1494 }
1495 temporary[i2]=basbuf[i];
1496 }
1497 if(temporary[0]=='\0'){
1498 if(basbuf[i]=='\0'){
1499
1500 if(dwClassType==ESC_CLASS)
1501 SetError(22,"Class",top_pos);
1502 else
1503 SetError(22,"Type",top_pos);
1504
1505 i--;
1506 break;
1507 }
1508 continue;
1509 }
1510
1511 //End Class記述の場合
1512 if(temporary[0]==1&&temporary[1]==ESC_ENDCLASS&&dwClassType==ESC_CLASS) break;
1513 if(temporary[0]==1&&temporary[1]==ESC_ENDTYPE&&dwClassType==ESC_TYPE) break;
1514
1515 //アクセスを変更
1516 if(lstrcmpi(temporary,"Private")==0){
1517 dwAccess=ACCESS_PRIVATE;
1518 continue;
1519 }
1520 if(lstrcmpi(temporary,"Public")==0){
1521 dwAccess=ACCESS_PUBLIC;
1522 continue;
1523 }
1524 if(lstrcmpi(temporary,"Protected")==0){
1525 dwAccess=ACCESS_PROTECTED;
1526 continue;
1527 }
1528
1529 extern int cp;
1530 if(i3==0){
1531 if(bStatic){
1532 //静的メンバを追加
1533 cp=i; //エラー用
[64]1534 pobj_c->AddStaticMember( dwAccess, isConst, false, temporary, i);
[4]1535 }
1536 else{
1537 //メンバを追加
1538 cp=i; //エラー用
[64]1539 pobj_c->AddMember( dwAccess, isConst, false, temporary );
[4]1540
1541
[89]1542 if(pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->IsStruct()){
[75]1543 if(pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->GetClass().ppobj_Member==0){
[4]1544 //参照先が読み取られていないとき
[75]1545 GetClass_recur(pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->GetClass().name);
[4]1546 }
1547 }
1548
1549
[89]1550 if(pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->IsStruct()){
[4]1551 //循環参照のチェック
1552 pobj_LoopRefCheck->add(pobj_c->name);
[75]1553 if(!MemberVar_LoopRefCheck(pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->GetClass())){
[4]1554 //エラー回避
[75]1555 pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->SetBasicType( DEF_PTR_VOID );
[4]1556 }
1557 pobj_LoopRefCheck->del(pobj_c->name);
1558 }
1559 }
1560 }
1561 else{
1562 //メソッドを追加
1563 cp=i; //エラー用
[18]1564 AddMethod(pobj_c,
1565 dwAccess,
1566 bStatic,
1567 isConst,
1568 bAbstract,
1569 bVirtual,
1570 bOverride,
1571 temporary,
1572 sub_address);
[4]1573
1574 if(bAbstract) continue;
1575
1576 for(;;i++){
1577 if(basbuf[i]=='\0'){
1578 i--;
1579 break;
1580 }
1581 if(basbuf[i-1]!='*'&&
1582 basbuf[i]==1&&(
1583 basbuf[i+1]==ESC_SUB||
1584 basbuf[i+1]==ESC_FUNCTION||
1585 basbuf[i+1]==ESC_MACRO||
1586 basbuf[i+1]==ESC_TYPE||
1587 basbuf[i+1]==ESC_CLASS||
1588 basbuf[i+1]==ESC_INTERFACE||
1589 basbuf[i+1]==ESC_ENUM)){
1590 GetDefaultNameFromES(i3,temporary);
1591 SetError(22,temporary,i);
1592 }
1593 if(basbuf[i]==1&&basbuf[i+1]==GetEndXXXCommand((char)i3)){
1594 i+=2;
1595 break;
1596 }
1597 }
1598 }
1599 }
1600 }
1601 }
1602}
1603
[67]1604void CDBClass::GetAllClassInfo(void){
[4]1605 //ループ継承チェック用のクラス
1606 pobj_LoopRefCheck=new CLoopRefCheck();
1607
1608 //クラスを取得
1609 GetClass_recur(0);
1610
1611 delete pobj_LoopRefCheck;
1612 pobj_LoopRefCheck=0;
[89]1613
1614 // イテレータ用のデータを作る
1615 pobj_DBClass->Iterator_Init();
[4]1616}
1617
[89]1618void CDBClass::Compile_System_InitializeUserTypes(){
[90]1619 char temporary[VN_SIZE];
[89]1620
1621 ////////////////////////////////////////////////////////////////////
1622 // クラス登録
1623 ////////////////////////////////////////////////////////////////////
1624
1625 // イテレータをリセット
1626 Iterator_Reset();
1627
1628 while( Iterator_HasNext() ){
[91]1629 const CClass &objClass = *Iterator_GetNext();
[89]1630
[91]1631 if( !objClass.IsUsing() ){
1632 // 未使用のクラスは無視する
1633 continue;
1634 }
1635
[94]1636 char referenceOffsetsBuffer[1024] = "";
1637 int numOfReference = 0;
1638 for( int i=0; i<objClass.iMemberNum; i++ ){
1639 CMember &member = *objClass.ppobj_Member[i];
1640
1641 if( member.IsObject() || member.IsPointer() ){
1642 if( referenceOffsetsBuffer[0] ){
1643 lstrcat( referenceOffsetsBuffer, "," );
1644 }
1645
1646 sprintf( referenceOffsetsBuffer + lstrlen( referenceOffsetsBuffer ),
1647 "%d",
1648 objClass.GetMemberOffset( member.name ) );
1649
1650 numOfReference++;
1651 }
1652 }
1653
[89]1654 sprintf( temporary
[94]1655 , "Add(%c%c_System_TypeForClass(\"%s\",\"%s\",[%s],%d))"
[89]1656 , 1
1657 , ESC_NEW
[94]1658 , "" // 名前空間 (TODO: 実装)
1659 , objClass.name // クラス名
1660 , referenceOffsetsBuffer // 参照メンバオフセット配列
1661 , numOfReference // 参照メンバの個数
[89]1662 );
1663
1664 // コンパイル
1665 ChangeOpcode( temporary );
1666
1667 // ネイティブコードバッファの再確保
1668 ReallocNativeCodeBuffer();
1669 }
1670
1671
1672 ////////////////////////////////////////////////////////////////////
[90]1673 // 基底クラスを登録
1674 ////////////////////////////////////////////////////////////////////
1675
1676 sprintf(temporary, "%c%ctempType=Nothing%c%cTypeBaseImpl"
1677 , HIBYTE( COM_DIM )
1678 , LOBYTE( COM_DIM )
1679 , 1
1680 , ESC_AS
1681 );
1682 ChangeOpcode( temporary );
1683
1684 // イテレータをリセット
1685 Iterator_Reset();
1686
1687 while( Iterator_HasNext() ){
[91]1688 const CClass &objClass = *Iterator_GetNext();
[90]1689
[91]1690 if( !objClass.IsUsing() ){
1691 // 未使用のクラスは無視する
1692 continue;
1693 }
1694
1695 if( objClass.pobj_InheritsClass ){
[90]1696 sprintf( temporary
1697 , "tempType=Search(\"%s\",\"%s\")"
1698 , "" // 名前空間 (TODO: 実装)
[91]1699 , objClass.name // クラス名
[90]1700 );
1701
1702 // コンパイル
1703 ChangeOpcode( temporary );
1704
1705 sprintf( temporary
1706 , "tempType.SetBaseType(Search(\"%s\",\"%s\"))"
1707 , "" // 名前空間 (TODO: 実装)
[91]1708 , objClass.pobj_InheritsClass->name // 基底クラス名
[90]1709 );
1710
1711 // コンパイル
1712 ChangeOpcode( temporary );
1713 }
1714
1715 // ネイティブコードバッファの再確保
1716 ReallocNativeCodeBuffer();
1717 }
1718
1719
1720
1721 ////////////////////////////////////////////////////////////////////
[89]1722 // 継承関係登録
1723 ////////////////////////////////////////////////////////////////////
1724 // TODO: 未完成
1725 /*
1726
1727 // イテレータをリセット
1728 Iterator_Reset();
1729
1730 while( Iterator_HasNext() ){
1731 CClass *pClass = Iterator_GetNext();
1732
1733 sprintf( genBuffer + length
1734 , "obj.Search( \"%s\" ).SetBaseType( Search( \"%s\" ) ):"
1735 , "" // クラス名
1736 , pClass->name // クラス名
1737 );
1738 length += lstrlen( genBuffer + length );
1739
1740 while( length + 8192 > max ){
1741 max += 8192;
1742 genBuffer = (char *)realloc( genBuffer, max );
1743 }
1744 }*/
[87]1745}
1746
1747
1748
[67]1749CClass *CDBClass::GetStringClass() const
1750{
1751 if( !pStringClass ){
1752 SetError();
1753 return NULL;
1754 }
1755 return pStringClass;
1756}
1757CClass *CDBClass::GetObjectClass() const
1758{
1759 if( !pObjectClass ){
1760 SetError();
1761 return NULL;
1762 }
1763 return pObjectClass;
1764}
1765
[75]1766void CDBClass::StartCompile( UserProc *pUserProc ){
1767 pCompilingClass = pUserProc->GetParentClassPtr();
[18]1768 if( pCompilingClass ){
[91]1769 pCompilingClass->Using();
1770
[75]1771 pCompilingMethod = pCompilingClass->GetMethodInfo( pUserProc );
[18]1772 if( !pCompilingMethod ){
[75]1773 pCompilingMethod = pCompilingClass->GetStaticMethodInfo( pUserProc );
[18]1774 if( !pCompilingMethod ){
1775 SetError(300,NULL,cp);
1776 }
1777 }
1778 }
1779 else{
1780 pCompilingMethod = NULL;
1781 }
1782}
1783CClass *CDBClass::GetNowCompilingClass(){
1784 return pCompilingClass;
1785}
1786CMethod *CDBClass::GetNowCompilingMethodInfo(){
1787 return pCompilingMethod;
1788}
[4]1789
1790
1791
[18]1792
[4]1793//////////////////////
1794// イテレータ
1795//////////////////////
1796
[89]1797void CDBClass::Iterator_Init(void){
[4]1798 if(ppobj_IteClass) HeapDefaultFree(ppobj_IteClass);
1799
1800 iIteMaxNum=0;
1801 iIteNextNum=0;
1802 ppobj_IteClass=(CClass **)HeapAlloc(hHeap,0,1);
1803
1804 int i;
1805 for(i=0;i<MAX_CLASS_HASH;i++){
1806 if(pobj_ClassHash[i]){
1807 CClass *pobj_c;
1808 pobj_c=pobj_ClassHash[i];
1809 while(1){
1810 ppobj_IteClass=(CClass **)HeapReAlloc(hHeap,0,ppobj_IteClass,(iIteMaxNum+1)*sizeof(CClass *));
1811 ppobj_IteClass[iIteMaxNum]=pobj_c;
1812 iIteMaxNum++;
1813
1814 if(pobj_c->pobj_NextClass==0) break;
1815 pobj_c=pobj_c->pobj_NextClass;
1816 }
1817 }
1818 }
1819}
[89]1820void CDBClass::Iterator_Reset(void){
1821 iIteNextNum = 0;
1822}
[4]1823BOOL CDBClass::Iterator_HasNext(void){
1824 if(iIteNextNum<iIteMaxNum) return 1;
1825 return 0;
1826}
1827CClass *CDBClass::Iterator_GetNext(void){
1828 CClass *pobj_c;
1829 pobj_c=ppobj_IteClass[iIteNextNum];
1830 iIteNextNum++;
1831 return pobj_c;
1832}
1833int CDBClass::Iterator_GetMaxCount(void){
1834 return iIteMaxNum;
1835}
Note: See TracBrowser for help on using the repository browser.