source: dev/BasicCompiler_Common/Class.cpp@ 85

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

オブジェクトの循環参照を許容した(構造体はダメ)。
抽象クラスをメンバの型に指定できるようにした。
メンバがオブジェクトだったとき、自動的にNewするのをやめ、初期値としてNothingを指定するようにした。

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