source: dev/BasicCompiler_Common/Class.cpp@ 40

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

ByRef修飾子を関数戻り値とDimステートメントで指定可能にした。

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