source: dev/BasicCompiler_Common/Class.cpp@ 140

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

traceログ機能を搭載
動的メンバをstl::vectorにまとめた
シンボルをクラス化した

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