source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/src/Compiler.cpp @ 745

Last change on this file since 745 was 745, checked in by dai, 15 years ago
  • Compiler::AddStringToDataTableメソッドを実装。
  • ToWStringメソッドの内部予備バッファを増やした。
File size: 13.5 KB
Line 
1#include "stdafx.h"
2
3using namespace ActiveBasic::Compiler;
4
5Compiler compiler;
6
7Compiler::Compiler()
8    : isBuildSuccessful( false )
9    , targetModuleType( ActiveBasic::Common::TargetModuleType::Exe )
10    , isDebug( false )
11    , isUnicode( false )
12    , isCore( false )
13    , currentRelationalObjectModuleIndexForSource( 0 )
14{
15    // 生成先のオブジェクトモジュールを登録
16    ObjectModule *pObjectModule = new ObjectModule();
17    staticLibraries.push_back( pObjectModule );
18    SelectObjectModule( pObjectModule );
19
20    namespaceSupporter.RegistAllNamespaceScopesCollection( &GetObjectModule().meta.GetNamespaces() );
21
22    Symbol::RegistNamespaceSupporter( &namespaceSupporter );
23}
24Compiler::~Compiler()
25{
26    BOOST_FOREACH( ObjectModule *pStaticLibrary, staticLibraries )
27    {
28        delete pStaticLibrary;
29    }
30    staticLibraries.clear();
31}
32
33void Compiler::PreStaticLink( const ObjectModules &staticLibraries )
34{
35    BOOST_FOREACH( const ObjectModule *pStaticLibrary, staticLibraries )
36    {
37        // 関連オブジェクトモジュールの名前リスト
38        this->GetObjectModule().relationalObjectModuleNames.push_back( pStaticLibrary->GetName() );
39    }
40}
41void Compiler::StaticLink( ObjectModules &staticLibraries )
42{
43    BOOST_FOREACH( ObjectModule *pStaticLibrary, staticLibraries )
44    {
45        if( &this->GetObjectModule() == pStaticLibrary )
46        {
47            // 自分自身の場合はリンクしない
48            continue;
49        }
50
51        // メタ情報
52        this->GetObjectModule().StaticLink( *pStaticLibrary, this->IsSll() );
53    }
54}
55
56const std::string &Compiler::GetGlobalAreaProcName() const
57{
58    static std::string globalAreaProcName;
59
60    if( globalAreaProcName.empty() )
61    {
62        // 初期化
63        _ASSERTE( !this->GetModuleName().empty() );
64
65        std::string originalName = this->GetModuleName();
66
67        // モジュール名がシンボル名として使えない場合があるので、16進数文字列に変換する
68        char temporary[VN_SIZE*2] = "";
69        for( int i=0; i<static_cast<int>(originalName.size()); i++ )
70        {
71            sprintf( temporary + strlen(temporary), "%2x", originalName[i] );
72        }
73
74        globalAreaProcName = (std::string)"_GlobalArea_" + temporary;
75    }
76
77    return globalAreaProcName;
78}
79
80int Compiler::AddStringToDataTable( const std::string &text )
81{
82    if( this->IsUnicode() )
83    {
84        return this->GetObjectModule().dataTable.AddWString( Jenga::Common::ToWString( text ) );
85    }
86    else
87    {
88        return this->GetObjectModule().dataTable.AddString( text );
89    }
90}
91
92ActiveBasic::Compiler::Error::StringToTypeErrorCode::EnumType Compiler::StringToGenericTypeEx( const std::string &typeName, Type &type )
93{
94    // ジェネリッククラスをインスタンス化した型の場合
95    int i = 0;
96    char className[VN_SIZE];
97    GetIdentifierToken( className, typeName.c_str(), i );
98
99    // ジェネリクスクラスを取得
100    const CClass *pGenericClass = this->GetObjectModule().meta.FindClassSupportedTypeDef( 
101        LexicalAnalyzer::FullNameToSymbol( className )
102    );
103
104    if( !pGenericClass )
105    {
106        return ActiveBasic::Compiler::Error::StringToTypeErrorCode::NotfoundGenericClass;
107    }
108
109    if( typeName[i] != '<' )
110    {
111        Jenga::Throw( "StringToType内でジェネリクス構文の解析に失敗" );
112    }
113
114    GenericTypes genericTypes;
115    bool isValueType = false;
116    while( true )
117    {
118        i++;
119
120        char typeParameterStr[VN_SIZE];
121        GetIdentifierToken( typeParameterStr, typeName.c_str(), i );
122
123        // 型パラメータの型情報を取得
124        Type typeParameterType;
125        StringToType( typeParameterStr, typeParameterType );
126
127        if( this->IsCompilingClass() )
128        {
129            if( this->pCompilingClass->IsExpanded() && typeParameterType.IsTypeParameter() )
130            {
131                // 現在コンパイル中のクラスがテンプレート展開済みのクラスで、
132                // 尚且つターゲットとなる型が型パラメータだったとき
133
134                // テンプレート展開情報を用いて型解決を行う
135                this->pCompilingClass->ResolveExpandedClassActualTypeParameter( typeParameterType );
136            }
137        }
138
139        genericTypes.push_back( GenericType( "(non support)", typeParameterType ) );
140
141        if( typeParameterType.IsValueType() )
142        {
143            // 値型の場合
144            isValueType = true;
145        }
146
147        if( typeName[i] != ',' )
148        {
149            break;
150        }
151    }
152
153    // 基本型をセット
154    type.SetBasicType( DEF_OBJECT );
155
156    if( isValueType )
157    {
158        // 型パラメータに値型が指定された場合
159
160        // 仮型パラメータを実型パラメータに変換
161        Types actualTypes;
162        BOOST_FOREACH( const GenericType &genericType, genericTypes )
163        {
164            actualTypes.push_back( genericType.GetType() );
165        }
166
167        // テンプレートとしてクラスを展開する
168        const CClass *pExpandedClass = LexicalAnalyzer::TemplateExpand( *const_cast<CClass *>(pGenericClass), actualTypes );
169
170        if( pExpandedClass )
171        {
172            // 拡張情報をセット
173            type.SetClassPtr( pExpandedClass );
174        }
175        else
176        {
177            // TODO: 消す
178            goto Generic;
179        }
180    }
181    else
182    {
183Generic:
184        // 型パラメータにクラス型が指定された場合
185
186        // ジェネリック クラスとして利用する
187
188        // 拡張情報をセット
189        type.SetClassPtr( pGenericClass );
190        type.SetActualGenericTypes( genericTypes );
191    }
192
193    return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
194}
195ActiveBasic::Compiler::Error::StringToTypeErrorCode::EnumType Compiler::StringToTypeEx( const std::string &typeName, Type &type, bool isResolveGenerics )
196{
197    type.SetIndex( -1 );
198
199
200    /////////////////////////////////////////////////////////
201    // ☆★☆ ジェネリクスサポート ☆★☆
202
203    if( strstr( typeName.c_str(), "<" ) )
204    {
205        return StringToGenericTypeEx( typeName, type );
206    }
207
208    //
209    /////////////////////////////////////////////////////////
210
211
212    if( typeName[0] == '*' ){
213        if( typeName.size() >= 3
214            && typeName[1] == 1 && ( typeName[2] == ESC_FUNCTION || typeName[2] == ESC_SUB ) )
215        {
216            // 関数ポインタを追加する
217            {
218                DWORD dwProcType = (DWORD)typeName[2];
219                const std::string &paramStr = typeName.substr( 3 );
220
221                Procedure::Kind kind = ( dwProcType == ESC_FUNCTION )
222                    ? Procedure::Function
223                    : Procedure::Sub;
224
225                ProcPointer *pProcPointer = new ProcPointer( kind );
226
227                //buffer[0]は'('となっている
228                extern int cp;
229                ActiveBasic::Compiler::LexicalAnalyzer::SetParamsAndReturnType( pProcPointer, paramStr.c_str(), false, cp );
230
231                this->GetObjectModule().meta.GetProcPointers().push_back( pProcPointer );
232            }
233
234            //関数ポインタ(*Function)
235            type.SetBasicType( DEF_PTR_PROC );
236            type.SetIndex( this->GetObjectModule().meta.GetProcPointers().size() - 1 );
237            return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
238        }
239
240        const std::string &nextTypeName = typeName.substr( 1 );
241
242        ActiveBasic::Compiler::Error::StringToTypeErrorCode::EnumType result = StringToTypeEx( nextTypeName, type, isResolveGenerics );
243        if( result != ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful )
244        {
245            return result;
246        }
247
248        type.PtrLevelUp();
249
250        return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
251    }
252
253    {
254        int basicType;
255        if( Type::StringToBasicType( typeName, basicType ) )
256        {
257            // 基本型だったとき
258            type.SetBasicType( basicType );
259            return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
260        }
261    }
262
263    // Object型だったとき
264    if( typeName == "Object" )
265    {
266        type.SetType( DEF_OBJECT, this->GetObjectModule().meta.GetClasses().GetObjectClassPtr() );
267        return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
268    }
269
270    // String型だったとき
271    if( typeName == "String" )
272    {
273        type.SetType( DEF_OBJECT, this->GetObjectModule().meta.GetClasses().GetStringClassPtr() );
274        return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
275    }
276
277
278    ////////////////////
279    // TypeDefされた型
280    ////////////////////
281    const TypeDef *pTypeDef = this->GetObjectModule().meta.GetTypeDefs().Find( LexicalAnalyzer::FullNameToSymbol( typeName ) );
282    if( pTypeDef )
283    {
284        type = pTypeDef->GetBaseType();
285
286        if( type.IsObject() )
287        {
288            if( isResolveGenerics && type.GetClass().IsGeneric() && !type.HasActualGenericType() )
289            {
290                // ジェネリッククラスの場合
291                trace( "型解決されていない" );
292                return ActiveBasic::Compiler::Error::StringToTypeErrorCode::FailedResolveGenericType;
293            }
294        }
295
296        return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
297    }
298
299    //クラス
300    const CClass *pobj_c = this->GetObjectModule().meta.FindClassSupportedTypeDef( LexicalAnalyzer::FullNameToSymbol( typeName ) );
301    if(pobj_c)
302    {
303        if( isResolveGenerics && pobj_c->IsGeneric() )
304        {
305            // ジェネリッククラスの場合
306            trace( "型解決されていない" );
307            return ActiveBasic::Compiler::Error::StringToTypeErrorCode::FailedResolveGenericType;
308        }
309
310        if( pobj_c->IsStructure() )
311        {
312            type.SetBasicType( DEF_STRUCT );
313        }
314        else
315        {
316            type.SetBasicType( DEF_OBJECT );
317        }
318        type.SetClassPtr( pobj_c );
319        return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
320    }
321
322
323    /////////////////////////////////////////////////////////
324    // ☆★☆ ジェネリクスサポート ☆★☆
325
326    // 型パラメータ
327    if( this->IsCompilingClass() )
328    {
329        // クラスに属するメソッドをコンパイルしているとき
330        int formalTypeIndex = this->GetCompilingClass().GetFormalGenericTypeParameterIndex( typeName );
331        if( formalTypeIndex != -1 )
332        {
333            // コンパイル中クラスにおけるジェネリクス用の型パラメータのとき
334            type.SetBasicType( DEF_TYPE_PARAMETER );
335            type.SetClassPtr( &this->GetCompilingClass().GetFormalGenericTypes()[formalTypeIndex].GetType().GetClass() );
336            type.SetFormalTypeName( typeName );
337            type.SetFormalTypeIndex( formalTypeIndex );
338            return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
339        }
340    }
341
342    //
343    /////////////////////////////////////////////////////////
344
345    return ActiveBasic::Compiler::Error::StringToTypeErrorCode::NotfoundType;
346}
347
348bool Compiler::StringToType( const std::string &typeName, Type &type )
349{
350    return ( StringToTypeEx( typeName, type, false ) == ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful );
351}
352
353const std::string Compiler::TypeToString( const Type &type )
354{
355    if( PTR_LEVEL( type.GetBasicType() ) ){
356        //ポインタレベルが1以上の場合
357        Type tempType( type );
358        tempType.PtrLevelDown();
359
360        return '*' + TypeToString( tempType );
361    }
362    else if( type.IsObject() || type.IsStruct() )
363    {
364        //オブジェクトまたは構造体
365
366        if( !( type.GetIndex() == 0 || type.GetIndex() == -1 ) )
367        {
368            std::string result = type.GetClass().GetName();
369            if( type.GetClass().GetNamespaceScopes().size() >= 1 )
370            {
371                result = type.GetClass().GetNamespaceScopes().ToString()
372                    + "."
373                    + result;
374            }
375
376            if( type.GetClass().IsExpanded() )
377            {
378                // テンプレート展開済みのクラスの場合
379                std::string actualGenericTypesName;
380                BOOST_FOREACH( const Type &typeParameter, type.GetClass().expandedClassActualTypeParameters )
381                {
382                    if( actualGenericTypesName.size() )
383                    {
384                        actualGenericTypesName += ',';
385                    }
386                    actualGenericTypesName += typeParameter.ToString();
387                }
388
389                result += '<' + actualGenericTypesName + '>';
390            }
391
392            return result;
393        }
394    }
395    else if( type.IsProcPtr() ){
396        if( type.GetIndex() == 0 || type.GetIndex() == -1 ){
397            return "VoidPtr";
398        }
399        else{
400            if( this->GetObjectModule().meta.GetProcPointers()[type.GetIndex()]->ReturnType().IsNull() ){
401                return "*Sub";
402            }
403            return "*Function";
404        }
405    }
406    else{
407        // 基本型
408        const char *lpszTypeName = Type::BasicTypeToCharPtr( type );
409        if( lpszTypeName )
410        {
411            return (const std::string)lpszTypeName;
412        }
413    }
414
415    compiler.errorMessenger.Output(1, NULL, cp);
416
417    return (std::string)"(null)";
418}
419
420int Compiler::SizeOf( const Type &type )
421{
422    Type tempType( type );
423    if( this->IsCompilingClass() )
424    {
425        if( this->pCompilingClass->IsExpanded() && tempType.IsTypeParameter() )
426        {
427            // 現在コンパイル中のクラスがテンプレート展開済みのクラスで、
428            // 尚且つターゲットとなる型が型パラメータだったとき
429
430            // テンプレート展開情報を用いて型解決を行う
431            this->pCompilingClass->ResolveExpandedClassActualTypeParameter( tempType );
432        }
433    }
434    return tempType.GetSize();
435}
436
437void Compiler::ClearCompilingUserProcAndClass()
438{
439    this->pCompilingUserProc = NULL;
440    this->pCompilingClass = NULL;
441}
442
443void Compiler::SetCompilingClass( const CClass *pClass )
444{
445    this->pCompilingClass = pClass;
446}
447
448void Compiler::SetCompilingUserProc( const UserProc *pUserProc )
449{
450    this->pCompilingUserProc = pUserProc;
451
452    this->SetCompilingClass( pUserProc->GetParentClassPtr() );
453}
454
455void Compiler::StartGlobalAreaCompile()
456{
457    ClearCompilingUserProcAndClass();
458}
459
460void Compiler::StartProcedureCompile( const UserProc *pUserProc )
461{
462    //コンパイル中の関数
463    this->SetCompilingUserProc( pUserProc );
464
465    if( pUserProc->HasParentClass() )
466    {
467        // クラスの使用チェック
468        pUserProc->GetParentClass().Using();
469    }
470
471    // コンパイル中の関数が属する名前空間
472    this->GetNamespaceSupporter().SetLivingNamespaceScopes( pUserProc->GetNamespaceScopes() );
473
474    // コンパイル中の関数でImportsされている名前空間
475    this->GetNamespaceSupporter().SetImportedNamespaces( pUserProc->GetImportedNamespaces() );
476
477    // コード生成対象を選択
478    this->codeGenerator.Select( (const_cast<UserProc *>(pUserProc))->GetNativeCode() );
479}
480void Compiler::FinishProcedureCompile()
481{
482    this->pCompilingUserProc = NULL;
483    this->pCompilingClass = NULL;
484}
485
486bool Compiler::IsGlobalAreaCompiling()
487{
488    if( pCompilingUserProc == NULL )
489    {
490        return true;
491    }
492    return ( pCompilingUserProc->GetName() == this->GetGlobalAreaProcName() );
493}
494bool Compiler::IsLocalAreaCompiling()
495{
496    return !IsGlobalAreaCompiling();
497}
498const UserProc &Compiler::GetCompilingUserProc()
499{
500    if( pCompilingUserProc == NULL )
501    {
502        _ASSERTE( false );
503        throw;
504    }
505    return *pCompilingUserProc;
506}
507
508bool Compiler::IsCompilingClass()
509{
510    return ( pCompilingClass != NULL );
511}
512const CClass &Compiler::GetCompilingClass()
513{
514    if( this->IsCompilingClass() )
515    {
516        return *pCompilingClass;
517    }
518
519    throw;
520}
Note: See TracBrowser for help on using the repository browser.