source: dev/trunk/jenga/src/smoothie/Class.cpp@ 174

Last change on this file since 174 was 173, checked in by dai_9181, 17 years ago
File size: 20.1 KB
Line 
1#include <stdlib.h>
2
3#include <jenga/include/smoothie/Smoothie.h>
4#include <jenga/include/smoothie/Class.h>
5#include <jenga/include/smoothie/SmoothieException.h>
6
7
8class CLoopRefCheck{
9 char **names;
10 int num;
11 void init(){
12 int i;
13 for(i=0;i<num;i++){
14 free(names[i]);
15 }
16 free(names);
17 }
18public:
19 CLoopRefCheck()
20 {
21 names=(char **)malloc(1);
22 num=0;
23 }
24 ~CLoopRefCheck()
25 {
26 init();
27 }
28 void add(const char *lpszInheritsClass)
29 {
30 names=(char **)realloc(names,(num+1)*sizeof(char *));
31 names[num]=(char *)malloc(lstrlen(lpszInheritsClass)+1);
32 lstrcpy(names[num],lpszInheritsClass);
33 num++;
34 }
35 void del(const char *lpszInheritsClass)
36 {
37 int i;
38 for(i=0;i<num;i++){
39 if(lstrcmp(names[i],lpszInheritsClass)==0){
40 free(names[i]);
41 break;
42 }
43 }
44 if(i!=num){
45 num--;
46 for(;i<num;i++){
47 names[i]=names[i+1];
48 }
49 }
50 }
51 BOOL check(const CClass &inheritsClass) const
52 {
53 //ループ継承チェック
54 int i;
55 for(i=0;i<num;i++){
56 if( inheritsClass.GetName() == names[i] ){
57 return 1;
58 }
59 }
60 return 0;
61 }
62};
63CLoopRefCheck *pobj_LoopRefCheck;
64
65
66
67
68CClass::CClass( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const string &name )
69 : isReady( false )
70 , Prototype( namespaceScopes, name )
71 , importedNamespaces( importedNamespaces )
72 , ConstructorMemberSubIndex( 0 )
73 , DestructorMemberSubIndex( 0 )
74 , classType( Class )
75 , pobj_InheritsClass( NULL )
76 , vtblNum( 0 )
77 , iAlign( 0 )
78 , vtbl_offset( -1 )
79 , isCompilingConstructor( false )
80 , isCompilingDestructor( false )
81 , pobj_NextClass( NULL )
82{
83}
84CClass::~CClass(){
85 // 動的メンバ
86 BOOST_FOREACH( CMember *member, dynamicMembers ){
87 delete member;
88 }
89
90 // 静的メンバ
91 BOOST_FOREACH( CMember *member, staticMembers ){
92 delete member;
93 }
94}
95
96bool CClass::IsInheritsInterface( const CClass *pInterfaceClass ) const
97{
98 BOOST_FOREACH( const InheritedInterface &objInterface, interfaces ){
99 if( pInterfaceClass == &objInterface.GetInterfaceClass() ){
100 return true;
101 }
102 }
103 return false;
104}
105
106bool CClass::IsClass() const
107{
108 return classType == CClass::Class;
109}
110bool CClass::IsInterface() const
111{
112 return classType == CClass::Interface;
113}
114bool CClass::IsEnum() const
115{
116 return classType == CClass::Enum;
117}
118bool CClass::IsDelegate() const
119{
120 return classType == CClass::Delegate;
121}
122bool CClass::IsStructure() const
123{
124 return classType == CClass::Structure;
125}
126
127bool CClass::Inherits( const char *inheritNames, int nowLine ){
128 int i = 0;
129 bool isInheritsClass = false;
130 while( true ){
131
132 char temporary[VN_SIZE];
133 for( int i2=0;; i++, i2++ ){
134 if( inheritNames[i] == '\0' || inheritNames[i] == ',' ){
135 temporary[i2] = 0;
136 break;
137 }
138 temporary[i2] = inheritNames[i];
139 }
140
141 //継承元クラスを取得
142 const CClass *pInheritsClass = Smoothie::meta.classes.Find(temporary);
143 if( !pInheritsClass ){
144 throw SmoothieException(106,temporary,nowLine);
145 return false;
146 }
147
148 if( pInheritsClass->IsInterface() ){
149 // インターフェイスはあとで継承する
150 }
151 else if( pInheritsClass->IsClass() ){
152 // クラスを継承する
153 isInheritsClass = true;
154
155 if( !InheritsClass( *pInheritsClass, nowLine ) ){
156 return false;
157 }
158 }
159 else{
160 throw SmoothieException(135,NULL,nowLine);
161 return false;
162 }
163
164 if( inheritNames[i] == '\0' ){
165 break;
166 }
167 i++;
168 }
169
170 if( !isInheritsClass ){
171 // クラスを一つも継承していないとき
172 const CClass *pObjectClass = Smoothie::meta.classes.Find("Object");
173 if( !pObjectClass ){
174 throw SmoothieException(106,"Object",i);
175 return false;
176 }
177
178 if( !InheritsClass( *pObjectClass, nowLine ) ){
179 return false;
180 }
181 }
182
183 i=0;
184 while( true ){
185
186 char temporary[VN_SIZE];
187 for( int i2=0;; i++, i2++ ){
188 if( inheritNames[i] == '\0' || inheritNames[i] == ',' ){
189 temporary[i2] = 0;
190 break;
191 }
192 temporary[i2] = inheritNames[i];
193 }
194
195 //継承元クラスを取得
196 const CClass *pInheritsClass = Smoothie::meta.classes.Find(temporary);
197 if( !pInheritsClass ){
198 throw SmoothieException(106,temporary,nowLine);
199 return false;
200 }
201
202 if( pInheritsClass->IsInterface() ){
203 // インターフェイスを継承する
204 if( !InheritsInterface( *pInheritsClass, nowLine ) ){
205 return false;
206 }
207 }
208 else if( pInheritsClass->IsClass() ){
209 // クラスはさっき継承した
210 }
211 else{
212 throw SmoothieException(135,NULL,nowLine);
213 return false;
214 }
215
216 if( inheritNames[i] == '\0' ){
217 break;
218 }
219 i++;
220 }
221
222 return true;
223}
224/*
225bool CClass::InheritsClass( const CClass &inheritsClass, int nowLine ){
226
227 //ループ継承でないかをチェック
228 if(pobj_LoopRefCheck->check(inheritsClass)){
229 throw SmoothieException(123,inheritsClass.GetName(),nowLine);
230 return false;
231 }
232
233 if( !inheritsClass.IsReady() ){
234 //継承先が読み取られていないとき
235 pobj_LoopRefCheck->add(this->GetName().c_str());
236 Smoothie::meta.classes.GetClass_recur(inheritsClass.GetName().c_str());
237 pobj_LoopRefCheck->del(this->GetName().c_str());
238 }
239
240 //メンバをコピー
241 BOOST_FOREACH( CMember *inheritsClassDynamicMember, inheritsClass.dynamicMembers ){
242 CMember *pMember = new CMember( *inheritsClassDynamicMember );
243
244 // アクセシビリティ
245 if( inheritsClassDynamicMember->IsPrivate() ){
246 pMember->SetAccessibility( Prototype::None );
247 }
248 else{
249 pMember->SetAccessibility( inheritsClassDynamicMember->GetAccessibility() );
250 }
251
252 dynamicMembers.push_back( pMember );
253 }
254
255 //メソッドをコピー
256 BOOST_FOREACH( const CMethod *pBaseMethod, inheritsClass.methods ){
257 CMethod *pMethod = new DynamicMethod( *pBaseMethod );
258
259 // アクセシビリティ
260 if(pBaseMethod->GetAccessibility() == Prototype::Private){
261 pMethod->SetAccessibility( Prototype::None );
262 }
263 else{
264 pMethod->SetAccessibility( pBaseMethod->GetAccessibility() );
265 }
266
267 //pobj_Inherits
268 // ※継承元のClassIndexをセット(入れ子継承を考慮する)
269 if(pBaseMethod->GetInheritsClassPtr()==0){
270 pMethod->SetInheritsClassPtr( &inheritsClass );
271 }
272 else{
273 pMethod->SetInheritsClassPtr( pBaseMethod->GetInheritsClassPtr() );
274 }
275
276 methods.push_back( pMethod );
277 }
278
279 //仮想関数の数
280 AddVtblNum( inheritsClass.GetVtblNum() );
281
282 //継承先のクラスをメンバとして保持する
283 pobj_InheritsClass = &inheritsClass;
284
285 return true;
286}
287bool CClass::InheritsInterface( const CClass &inheritsInterface, int nowLine ){
288
289 //ループ継承でないかをチェック
290 if(pobj_LoopRefCheck->check(inheritsInterface)){
291 throw SmoothieException(123,inheritsInterface.GetName(),nowLine);
292 return false;
293 }
294
295 if( !inheritsInterface.IsReady() ){
296 //継承先が読み取られていないとき
297 pobj_LoopRefCheck->add(this->GetName().c_str());
298 Smoothie::meta.classes.GetClass_recur(inheritsInterface.GetName().c_str());
299 pobj_LoopRefCheck->del(this->GetName().c_str());
300 }
301
302 //メソッドをコピー
303 BOOST_FOREACH( const CMethod *pBaseMethod, inheritsInterface.methods ){
304 CMethod *pMethod = new DynamicMethod( *pBaseMethod );
305
306 // アクセシビリティ
307 if(pBaseMethod->GetAccessibility() == Prototype::Private){
308 pMethod->SetAccessibility( Prototype::None );
309 }
310 else{
311 pMethod->SetAccessibility( pBaseMethod->GetAccessibility() );
312 }
313
314 //pobj_Inherits
315 // ※継承元のClassIndexをセット(入れ子継承を考慮する)
316 if(pBaseMethod->GetInheritsClassPtr()==0){
317 pMethod->SetInheritsClassPtr( &inheritsInterface );
318 }
319 else{
320 pMethod->SetInheritsClassPtr( pBaseMethod->GetInheritsClassPtr() );
321 }
322
323 methods.push_back( pMethod );
324 }
325
326 interfaces.push_back( InheritedInterface( const_cast<CClass *>(&inheritsInterface), vtblNum ) );
327
328 //仮想関数の数
329 AddVtblNum( inheritsInterface.GetVtblNum() );
330
331 return true;
332}
333void CClass::AddMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer ){
334 CMember *pMember = new CMember( this, accessibility, isConst, isRef, buffer );
335 dynamicMembers.push_back( pMember );
336}
337void CClass::AddStaticMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){
338 CMember *pMember = new CMember( this, accessibility, isConst, isRef, buffer, nowLine );
339 staticMembers.push_back( pMember );
340}*/
341BOOL CClass::DupliCheckAll(const char *name){
342 //重複チェック
343
344 //メンバ
345 if(DupliCheckMember(name)) return 1;
346
347 //メソッド
348 BOOST_FOREACH( const CMethod *pMethod, methods ){
349 if( lstrcmp( name, pMethod->pUserProc->GetName().c_str() ) == 0 ){
350 return 1;
351 }
352 }
353
354 return 0;
355}
356BOOL CClass::DupliCheckMember(const char *name){
357 //重複チェック
358
359 // 動的メンバ
360 BOOST_FOREACH( CMember *pMember, dynamicMembers ){
361 if( GetName() == pMember->GetName() ){
362 return 1;
363 }
364 }
365
366 // 静的メンバ
367 BOOST_FOREACH( CMember *pMember, staticMembers ){
368 if( GetName() == pMember->GetName() ){
369 return 1;
370 }
371 }
372
373 return 0;
374}
375
376//デフォルト コンストラクタ メソッドを取得
377const CMethod *CClass::GetConstructorMethod() const
378{
379 if( ConstructorMemberSubIndex == -1 ) return NULL;
380 return methods[ConstructorMemberSubIndex];
381}
382
383//デストラクタ メソッドを取得
384const CMethod *CClass::GetDestructorMethod() const
385{
386 if( DestructorMemberSubIndex == -1 ) return NULL;
387 return methods[DestructorMemberSubIndex];
388}
389
390//サイズを取得
391int CClass::GetSize() const
392{
393 return GetMemberOffset( NULL, NULL );
394}
395
396//メンバのオフセットを取得
397int CClass::GetMemberOffset( const char *memberName, int *pMemberNum ) const
398{
399 int i2;
400
401 //仮想関数が存在する場合は関数リストへのポインタのサイズを追加
402 int offset = IsExistVirtualFunctions() ? PTR_SIZE : 0;
403
404 int alignment;
405 if(iAlign) alignment=iAlign;
406 else alignment=1;
407
408 int iMaxAlign=0;
409 int i = -1;
410 BOOST_FOREACH( CMember *pMember, dynamicMembers ){
411 i++;
412
413 i2 = pMember->GetType().GetSize();
414
415 //アラインメントを算出
416 int member_size;
417 if( pMember->GetType().IsStruct() ){
418 //メンバクラスのアラインメントを取得
419 member_size=pMember->GetType().GetClass().GetAlignment();
420 }
421 else{
422 //メンバサイズを取得
423 member_size=i2;
424 }
425 if(iMaxAlign<member_size) iMaxAlign=member_size;
426
427 //アラインメントを考慮
428 if(iAlign&&iAlign<member_size){
429 if(offset%alignment) offset+=alignment-(offset%alignment);
430 }
431 else{
432 if(alignment<member_size) alignment=member_size;
433
434 if(member_size==0){
435 //メンバを持たないクラス
436 //※何もしない(オフセットの計算をしない)
437 }
438 else{
439 if(offset%member_size) offset+=member_size-(offset%member_size);
440 }
441 }
442
443 if(memberName){
444 //メンバ指定がある場合は、オフセットを返す
445 if( pMember->GetName() == memberName ){
446 if(pMemberNum) *pMemberNum=i;
447 return offset;
448 }
449 }
450
451 //配列を考慮したメンバサイズを取得
452 member_size=i2 * Variable::GetSubScriptCounts(pMember->SubScripts);
453
454 //メンバサイズを加算
455 offset+= member_size;
456 }
457
458 if(iMaxAlign<alignment) alignment=iMaxAlign;
459
460 //アラインメントを考慮
461 if(alignment){
462 if(offset%alignment) offset+=alignment-(offset%alignment);
463 }
464
465 if(pMemberNum) *pMemberNum=i;
466 return offset;
467}
468
469int CClass::GetAlignment() const
470{
471 //仮想関数が存在する場合は関数リストへのポインタのサイズを追加
472 int alignment = IsExistVirtualFunctions() ? PTR_SIZE : 0;
473
474 BOOST_FOREACH( CMember *pMember, dynamicMembers ){
475 int member_size;
476 if(pMember->GetType().IsStruct()){
477 //メンバクラスのアラインメントを取得
478 member_size=pMember->GetType().GetClass().GetAlignment();
479 }
480 else{
481 //メンバサイズを取得
482 member_size = pMember->GetType().GetSize();
483 }
484
485 //アラインメントをセット
486 if(alignment<member_size) alignment=member_size;
487 }
488
489 if(alignment==0) return 0;
490
491 if(iAlign) alignment=iAlign;
492
493 return alignment;
494}
495
496
497
498int CClass::GetFuncNumInVtbl( const UserProc *pUserProc ) const
499{
500 int n = 0;
501 BOOST_FOREACH( const CMethod *pMethod, methods ){
502 if( pMethod->pUserProc == pUserProc ) break;
503 if( pMethod->IsVirtual() ) n++;
504 }
505 return n;
506}
507/*
508LONG_PTR CClass::GetVtblGlobalOffset(void) const
509{
510
511 //既に存在する場合はそれを返す
512 if(vtbl_offset!=-1) return vtbl_offset;
513
514
515
516 //////////////////////////////////////
517 // 存在しないときは新たに生成する
518 //////////////////////////////////////
519
520 UserProc **ppsi;
521 ppsi=(UserProc **)malloc(GetVtblNum()*sizeof(GlobalProc *));
522
523 //関数テーブルに値をセット
524 int i2 = 0;
525 BOOST_FOREACH( const CMethod *pMethod, methods ){
526 if(pMethod->IsVirtual()){
527 pMethod->pUserProc->Using();
528
529 if(pMethod->IsAbstract()){
530 extern int cp;
531 throw SmoothieException(300,NULL,cp);
532
533 ppsi[i2]=0;
534 }
535 else{
536 ppsi[i2]=pMethod->pUserProc;
537 }
538 i2++;
539 }
540 }
541
542 vtbl_offset=dataTable.AddBinary((void *)ppsi,GetVtblNum()*sizeof(LONG_PTR));
543
544 for( int i=0; i < GetVtblNum(); i++ ){
545 pobj_Reloc->AddSchedule_DataSection(vtbl_offset+i*sizeof(LONG_PTR));
546 }
547
548 free(ppsi);
549
550 return vtbl_offset;
551}
552void CClass::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){
553 if(vtbl_offset==-1) return;
554
555 LONG_PTR *pVtbl;
556 pVtbl=(LONG_PTR *)((char *)dataTable.GetPtr()+vtbl_offset);
557
558 int i;
559 for(i=0;i<GetVtblNum();i++){
560 GlobalProc *pUserProc;
561 pUserProc=(GlobalProc *)pVtbl[i];
562 if(!pUserProc) continue;
563 pVtbl[i]=pUserProc->beginOpAddress+ImageBase+MemPos_CodeSection;
564 }
565}*/
566bool CClass::IsAbstract() const
567{
568 // 未実装(abstract)の仮想関数を持つ場合はtrueを返す
569
570 BOOST_FOREACH( const CMethod *pMethod, methods ){
571 if(pMethod->IsVirtual()){
572 if(pMethod->IsAbstract()){
573 return true;
574 }
575 }
576 }
577
578 return false;
579}
580
581// コンストラクタのコンパイルを開始
582void CClass::NotifyStartConstructorCompile() const
583{
584 isCompilingConstructor = true;
585}
586
587//コンストラクタのコンパイルを終了
588void CClass::NotifyFinishConstructorCompile() const
589{
590 isCompilingConstructor = false;
591}
592
593//コンストラクタをコンパイル中かどうかを判別
594bool CClass::IsCompilingConstructor() const
595{
596 return isCompilingConstructor;
597}
598
599//デストラクタのコンパイルを開始
600void CClass::NotifyStartDestructorCompile() const{
601 isCompilingDestructor = true;
602}
603
604//デストラクタのコンパイルを終了
605void CClass::NotifyFinishDestructorCompile() const{
606 isCompilingDestructor = false;
607}
608
609//デストラクタをコンパイル中かどうかを判別
610bool CClass::IsCompilingDestructor() const
611{
612 return isCompilingDestructor;
613}
614
615//自身の派生クラスかどうかを確認
616bool CClass::IsSubClass( const CClass *pClass ) const
617{
618 pClass = pClass->pobj_InheritsClass;
619 while( pClass ){
620 if( this == pClass ) return true;
621 pClass = pClass->pobj_InheritsClass;
622 }
623 return false;
624}
625
626//自身と等しいまたは派生クラスかどうかを確認
627bool CClass::IsEqualsOrSubClass( const CClass *pClass ) const
628{
629 if( IsEquals( pClass ) ) return true;
630 return IsSubClass( pClass );
631}
632
633// 自身と等しいまたは派生クラス、基底クラスかどうかを確認
634bool CClass::IsEqualsOrSubClassOrSuperClass( const CClass &objClass ) const
635{
636 if( IsEquals( &objClass ) ) return true;
637 if( IsSubClass( &objClass ) ) return true;
638 if( objClass.IsSubClass( this ) ) return true;
639 return false;
640}
641
642
643
644int Classes::hash(const char *name) const{
645 int key;
646
647 for(key=0;*name!='\0';name++){
648 key=((key<<8)+ *name )%MAX_CLASS_HASH;
649 }
650
651 return key;
652}
653
654void Classes::DestroyClass(CClass *pobj_c){
655 if(pobj_c->pobj_NextClass){
656 DestroyClass(pobj_c->pobj_NextClass);
657 }
658
659 delete pobj_c;
660}
661
662Classes::Classes():
663 pStringClass( NULL ),
664 pObjectClass( NULL ),
665 pCompilingClass( NULL ),
666 pCompilingMethod( NULL ),
667 ppobj_IteClass( NULL ),
668 iIteMaxNum( 0 ),
669 iIteNextNum( 0 )
670{
671 Clear();
672}
673Classes::~Classes(){
674 Clear();
675}
676void Classes::Clear()
677{
678 int i;
679 for(i=0;i<MAX_CLASS_HASH;i++){
680 if(pobj_ClassHash[i]) DestroyClass(pobj_ClassHash[i]);
681 }
682
683 if(ppobj_IteClass) free(ppobj_IteClass);
684 memset( pobj_ClassHash, 0, MAX_CLASS_HASH * sizeof(CClass *) );
685}
686
687void Classes::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){
688 int i;
689 for(i=0;i<MAX_CLASS_HASH;i++){
690 if(pobj_ClassHash[i]){
691 CClass *pobj_c;
692 pobj_c=pobj_ClassHash[i];
693 while(1){
694 pobj_c->ActionVtblSchedule(ImageBase,MemPos_CodeSection);
695
696 if(pobj_c->pobj_NextClass==0) break;
697 pobj_c=pobj_c->pobj_NextClass;
698 }
699 }
700 }
701}
702
703const CClass *Classes::Find( const NamespaceScopes &namespaceScopes, const string &name ) const
704{
705 int key;
706 key=hash(name.c_str());
707
708 if( namespaceScopes.size() == 0 && name == "Object" ){
709 return GetObjectClassPtr();
710 }
711 else if( namespaceScopes.size() == 0 && name == "String" ){
712 return GetStringClassPtr();
713 }
714
715 if(pobj_ClassHash[key]){
716 CClass *pobj_c;
717 pobj_c=pobj_ClassHash[key];
718 while(1){
719 if( pobj_c->IsEqualSymbol( namespaceScopes, name ) ){
720 //名前空間とクラス名が一致した
721 return pobj_c;
722 }
723
724 if(pobj_c->pobj_NextClass==0) break;
725 pobj_c=pobj_c->pobj_NextClass;
726 }
727 }
728
729 // TypeDefも見る
730 int index = Smoothie::meta.typeDefs.GetIndex( namespaceScopes, name );
731 if( index != -1 ){
732 Type type = Smoothie::meta.typeDefs[index].GetBaseType();
733 if( type.IsObject() ){
734 return &type.GetClass();
735 }
736 }
737
738 return NULL;
739}
740const CClass *Classes::Find( const string &fullName ) const
741{
742 char AreaName[VN_SIZE] = ""; //オブジェクト変数
743 char NestName[VN_SIZE] = ""; //入れ子メンバ
744 bool isNest = CClass::SplitName( fullName.c_str(), AreaName, NestName );
745
746 return Find( NamespaceScopes( AreaName ), NestName );
747}
748
749CClass *Classes::AddClass( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name,int nowLine){
750 //////////////////////////////////////////////////////////////////////////
751 // クラスを追加
752 // ※名前のみを登録。その他の情報はSetClassメソッドで!
753 //////////////////////////////////////////////////////////////////////////
754
755 CClass *pobj_c;
756 pobj_c=new CClass(namespaceScopes, importedNamespaces, name);
757
758 if(lstrcmp(name,"String")==0){
759 //Stringクラス
760 pStringClass=pobj_c;
761 }
762 if( lstrcmp( name, "Object" ) == 0 ){
763 pObjectClass = pobj_c;
764 }
765
766
767 /////////////////////////////////
768 // ハッシュデータに追加
769 /////////////////////////////////
770
771 int key;
772 key=hash(name);
773
774 if(pobj_ClassHash[key]){
775 CClass *pobj_c2;
776 pobj_c2=pobj_ClassHash[key];
777 while(1){
778 if( pobj_c2->IsEqualSymbol( namespaceScopes, name ) ){
779 //名前空間及びクラス名が重複した場合
780 throw SmoothieException(15,name,nowLine);
781 return 0;
782 }
783
784 if(pobj_c2->pobj_NextClass==0) break;
785 pobj_c2=pobj_c2->pobj_NextClass;
786 }
787 pobj_c2->pobj_NextClass=pobj_c;
788 }
789 else{
790 pobj_ClassHash[key]=pobj_c;
791 }
792
793 return pobj_c;
794}
795
796
797
798CClass *Classes::GetStringClassPtr() const
799{
800 if( !pStringClass ){
801 throw SmoothieException();
802 return NULL;
803 }
804 return pStringClass;
805}
806CClass *Classes::GetObjectClassPtr() const
807{
808 if( !pObjectClass ){
809 throw SmoothieException();
810 return NULL;
811 }
812 return pObjectClass;
813}
814
815void Classes::StartCompile( UserProc *pUserProc ){
816 pCompilingClass = pUserProc->GetParentClassPtr();
817 if( pCompilingClass ){
818 pCompilingClass->Using();
819
820 pCompilingMethod = pCompilingClass->GetMethods().GetMethodPtr( pUserProc );
821 if( !pCompilingMethod ){
822 pCompilingMethod = pCompilingClass->GetStaticMethods().GetMethodPtr( pUserProc );
823 if( !pCompilingMethod ){
824 throw SmoothieException(300);
825 }
826 }
827 }
828 else{
829 pCompilingMethod = NULL;
830 }
831}
832const CClass *Classes::GetNowCompilingClass() const
833{
834 return pCompilingClass;
835}
836const CMethod *Classes::GetNowCompilingMethodInfo(){
837 return pCompilingMethod;
838}
839
840
841
842
843//////////////////////
844// イテレータ
845//////////////////////
846
847void Classes::Iterator_Init(void){
848 if(ppobj_IteClass) free(ppobj_IteClass);
849
850 iIteMaxNum=0;
851 iIteNextNum=0;
852 ppobj_IteClass=(CClass **)malloc(1);
853
854 int i;
855 for(i=0;i<MAX_CLASS_HASH;i++){
856 if(pobj_ClassHash[i]){
857 CClass *pobj_c;
858 pobj_c=pobj_ClassHash[i];
859 while(1){
860 ppobj_IteClass=(CClass **)realloc(ppobj_IteClass,(iIteMaxNum+1)*sizeof(CClass *));
861 ppobj_IteClass[iIteMaxNum]=pobj_c;
862 iIteMaxNum++;
863
864 if(pobj_c->pobj_NextClass==0) break;
865 pobj_c=pobj_c->pobj_NextClass;
866 }
867 }
868 }
869}
870void Classes::Iterator_Reset(void){
871 iIteNextNum = 0;
872}
873BOOL Classes::Iterator_HasNext(void){
874 if(iIteNextNum<iIteMaxNum) return 1;
875 return 0;
876}
877CClass *Classes::Iterator_GetNext(void){
878 CClass *pobj_c;
879 pobj_c=ppobj_IteClass[iIteNextNum];
880 iIteNextNum++;
881 return pobj_c;
882}
883int Classes::Iterator_GetMaxCount(void){
884 return iIteMaxNum;
885}
Note: See TracBrowser for help on using the repository browser.