source: dev/BasicCompiler_Common/Class.cpp@ 62

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

グローバル変数に対してByRefを指定できるようにした

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