source: dev/BasicCompiler_Common/Class.cpp@ 133

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

Prototypeクラスをちょっとだけ装飾

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