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

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

インターフェイスメソッドはオーバーライド対象外とした

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