source: dev/BasicCompiler_Common/Class.cpp@ 91

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

ログ機構(Smoothie::Logger)を導入。
動的型情報生成において、未使用クラスの登録は行わないようにした。

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