source: dev/trunk/abdev/BasicCompiler_Common/src/Class.cpp@ 340

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

Implements修飾子を作り始めた

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