source: dev/BasicCompiler_Common/Class.cpp@ 29

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

Ver5.0β10としてリリース。
すべてのクラスをObjectからの派生にした。

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