source: dev/BasicCompiler_Common/Class.cpp@ 114

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

CClassクラスのインスタンスを全面的にconstにした。
TypeDefされたクラスの静的メソッドを呼び出せるようにした。(静的メンバへの対応はまだ)

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