source: dev/BasicCompiler_Common/Class.cpp@ 129

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

_System_StartupProgramの呼び出し順序を変更。

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