source: dev/BasicCompiler_Common/Class.cpp@ 82

Last change on this file since 82 was 79, checked in by dai_9181, 18 years ago

バージョンをβ17にした。
#strictをデフォルトの状態で適用するようにした(#90)。
Dimステートメントにおいて、初期値式とAsが同時に指定されていたとき、As以降も初期値式の一部として捉えるよう、変更(#91)。
GetTypeDef関数を完全廃止。

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