source: dev/BasicCompiler_Common/Class.cpp@ 90

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

実行時型情報の生成にほぼ対応した。

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