source: dev/BasicCompiler_Common/Class.cpp@ 108

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

関数、クラスメソッドにImports機構を適用。

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