source: dev/BasicCompiler_Common/Class.cpp@ 100

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

名前空間機能をグローバル関数に適用。

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