source: dev/BasicCompiler_Common/Class.cpp@ 139

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

クラス情報取得時のクラス先読み処理で名前空間の関係が崩れてしまうバグを修正。
インクルードパスに'/'文字を含めたときに'
'として判断するようにした。

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