source: dev/BasicCompiler_Common/Class.cpp@ 106

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

名前空間機能をクラスの静的メンバに適用。

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