source: dev/BasicCompiler_Common/Class.cpp@ 128

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

Blittable型を導入した。

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