source: dev/BasicCompiler_Common/Class.cpp @ 131

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

Prototypeクラスを用意した。

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