source: dev/BasicCompiler_Common/Class.cpp@ 131

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

Prototypeクラスを用意した。

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