source: dev/BasicCompiler_Common/Class.cpp@ 99

Last change on this file since 99 was 97, checked in by dai_9181, 18 years ago

関数の戻り値オブジェクトのメンバ・メソッドを一時オブジェクトを介さずに参照できるようにした。

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