Ignore:
Timestamp:
Jun 5, 2008, 10:04:39 PM (16 years ago)
Author:
dai_9181
Message:

ジェネリッククラスの型パラメータに値型が指定されたときに限り、テンプレート展開を行うようにした。

TODO: libファイルを跨ってテンプレート展開ができていないため、ソースコード管理部分に手を加える必要あり。

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ab5.0/abdev/BasicCompiler_Common/src/Compiler.cpp

    r628 r632  
    1414}
    1515
    16 ActiveBasic::Compiler::Error::StringToTypeErrorCode::EnumType Compiler::StringToTypeEx( const std::string &typeName, Type &type, bool isResolveGenerics )
    17 {
    18     type.SetIndex( -1 );
    19 
    20 
    21     /////////////////////////////////////////////////////////
    22     // ☆★☆ ジェネリクスサポート ☆★☆
    23 
    24     if( strstr( typeName.c_str(), "<" ) )
    25     {
    26         // ジェネリッククラスをインスタンス化した型の場合
    27         int i = 0;
    28         char className[VN_SIZE];
    29         GetIdentifierToken( className, typeName.c_str(), i );
    30 
    31         // ジェネリクスクラスを取得
    32         const CClass *pGenericClass = this->GetObjectModule().meta.FindClassSupportedTypeDef(
    33             LexicalAnalyzer::FullNameToSymbol( className )
    34         );
    35 
    36         if( !pGenericClass )
    37         {
    38             return ActiveBasic::Compiler::Error::StringToTypeErrorCode::NotfoundGenericClass;
    39         }
    40 
    41         if( typeName[i] != '<' )
    42         {
    43             Jenga::Throw( "StringToType内でジェネリクス構文の解析に失敗" );
    44         }
    45 
    46         GenericTypes genericTypes;
    47         while( true )
    48         {
    49             i++;
    50 
    51             char typeParameter[VN_SIZE];
    52             GetIdentifierToken( typeParameter, typeName.c_str(), i );
    53 
    54             // 型パラメータの型情報を取得
    55             Type baseType;
    56             StringToType( typeParameter, baseType );
    57 
    58             genericTypes.push_back( GenericType( "(non support)", baseType ) );
    59 
    60             if( typeName[i] != ',' )
    61             {
    62                 break;
    63             }
    64         }
    65 
    66         // 基本型をセット
    67         type.SetBasicType( DEF_OBJECT );
     16ActiveBasic::Compiler::Error::StringToTypeErrorCode::EnumType Compiler::StringToGenericTypeEx( const std::string &typeName, Type &type )
     17{
     18    // ジェネリッククラスをインスタンス化した型の場合
     19    int i = 0;
     20    char className[VN_SIZE];
     21    GetIdentifierToken( className, typeName.c_str(), i );
     22
     23    // ジェネリクスクラスを取得
     24    const CClass *pGenericClass = this->GetObjectModule().meta.FindClassSupportedTypeDef(
     25        LexicalAnalyzer::FullNameToSymbol( className )
     26    );
     27
     28    if( !pGenericClass )
     29    {
     30        return ActiveBasic::Compiler::Error::StringToTypeErrorCode::NotfoundGenericClass;
     31    }
     32
     33    if( typeName[i] != '<' )
     34    {
     35        Jenga::Throw( "StringToType内でジェネリクス構文の解析に失敗" );
     36    }
     37
     38    GenericTypes genericTypes;
     39    bool isValueType = false;
     40    while( true )
     41    {
     42        i++;
     43
     44        char typeParameterStr[VN_SIZE];
     45        GetIdentifierToken( typeParameterStr, typeName.c_str(), i );
     46
     47        // 型パラメータの型情報を取得
     48        Type typeParameterType;
     49        StringToType( typeParameterStr, typeParameterType );
     50
     51        genericTypes.push_back( GenericType( "(non support)", typeParameterType ) );
     52
     53        if( typeParameterType.IsValueType() )
     54        {
     55            // 値型の場合
     56            isValueType = true;
     57        }
     58
     59        if( typeName[i] != ',' )
     60        {
     61            break;
     62        }
     63    }
     64
     65    // 基本型をセット
     66    type.SetBasicType( DEF_OBJECT );
     67
     68    if( isValueType )
     69    {
     70        // 型パラメータに値型が指定された場合
     71
     72        // 仮型パラメータを実型パラメータに変換
     73        Types actualTypes;
     74        BOOST_FOREACH( const GenericType &genericType, genericTypes )
     75        {
     76            actualTypes.push_back( genericType.GetType() );
     77        }
     78
     79        // テンプレートとしてクラスを展開する
     80        const CClass *pExpandedClass = LexicalAnalyzer::TemplateExpand( *const_cast<CClass *>(pGenericClass), actualTypes );
     81
     82        if( pExpandedClass )
     83        {
     84            // 拡張情報をセット
     85            type.SetClassPtr( pExpandedClass );
     86        }
     87        else
     88        {
     89            // TODO: 消す
     90            goto Generic;
     91        }
     92    }
     93    else
     94    {
     95Generic:
     96        // 型パラメータにクラス型が指定された場合
     97
     98        // ジェネリック クラスとして利用する
    6899
    69100        // 拡張情報をセット
    70101        type.SetClassPtr( pGenericClass );
    71102        type.SetActualGenericTypes( genericTypes );
    72 
    73         return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
     103    }
     104
     105    return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
     106}
     107ActiveBasic::Compiler::Error::StringToTypeErrorCode::EnumType Compiler::StringToTypeEx( const std::string &typeName, Type &type, bool isResolveGenerics )
     108{
     109    type.SetIndex( -1 );
     110
     111
     112    /////////////////////////////////////////////////////////
     113    // ☆★☆ ジェネリクスサポート ☆★☆
     114
     115    if( strstr( typeName.c_str(), "<" ) )
     116    {
     117        return StringToGenericTypeEx( typeName, type );
    74118    }
    75119
     
    147191    // TypeDefされた型
    148192    ////////////////////
    149     int i=this->GetObjectModule().meta.GetTypeDefs().GetIndex( LexicalAnalyzer::FullNameToSymbol( typeName ) );
    150     if(i!=-1)
    151     {
    152         type = this->GetObjectModule().meta.GetTypeDefs()[i].GetBaseType();
     193    const TypeDef *pTypeDef = this->GetObjectModule().meta.GetTypeDefs().Find( LexicalAnalyzer::FullNameToSymbol( typeName ) );
     194    if( pTypeDef )
     195    {
     196        type = pTypeDef->GetBaseType();
     197
     198        if( type.IsObject() )
     199        {
     200            if( isResolveGenerics && !type.HasActualGenericType() )
     201            {
     202                // ジェネリッククラスの場合
     203                trace( "型解決されていない" );
     204                return ActiveBasic::Compiler::Error::StringToTypeErrorCode::FailedResolveGenericType;
     205            }
     206        }
     207
    153208        return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
    154209    }
    155210
    156211    //クラス
    157     const CClass *pobj_c = this->GetObjectModule().meta.GetClasses().FindEx( LexicalAnalyzer::FullNameToSymbol( typeName ) );
     212    const CClass *pobj_c = this->GetObjectModule().meta.FindClassSupportedTypeDef( LexicalAnalyzer::FullNameToSymbol( typeName ) );
    158213    if(pobj_c)
    159214    {
Note: See TracChangeset for help on using the changeset viewer.