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

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

基底クラスからインターフェイスメソッドを実装できるようにした。

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