source: dev/BasicCompiler_Common/Class.cpp@ 135

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

Method/Memberのリファクタリング

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