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

Last change on this file since 353 was 353, checked in by dai_9181, 16 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.