source: dev/BasicCompiler_Common/Class.cpp @ 129

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

_System_StartupProgramの呼び出し順序を変更。

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