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

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

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

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