source: dev/BasicCompiler_Common/Class.cpp@ 134

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

Prototype::IsEqualSymbolメソッドを実装。

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