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

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

インターフェイスを実装

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