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

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

インターフェイス実装周りの仕様整備

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