source: dev/BasicCompiler_Common/Class.cpp@ 141

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

CClass::vtblNumをリファクタリングした。
インターフェイスを継承したとき、Objectクラスがインターフェイスの後ろに配置されてしまうバグを修正(どんなときも、Objectクラスが一番最初に継承されるべき)

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