source: dev/BasicCompiler_Common/Class.cpp@ 75

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

TYPEINFO→Typeへのリファクタリングを実施。64bitはほぼ完了。32bitが全般的に未完成。

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