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

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

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

Location:
trunk/ab5.0/abdev/BasicCompiler_Common
Files:
10 edited

Legend:

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

    r587 r632  
    758758            }
    759759
    760             ChangeOpcode(Command);
     760            if( Command[0] )
     761            {
     762                ChangeOpcode(Command);
     763            }
    761764
    762765
  • trunk/ab5.0/abdev/BasicCompiler_Common/NumOpe_GetType.cpp

    r600 r632  
    829829                        isNothing_stack[sp] = true;
    830830
    831                         type_stack[sp] = DEF_OBJECT;
    832831                        if( baseType.IsObject() ){
     832                            type_stack[sp] = DEF_OBJECT;
    833833                            index_stack[sp] = baseType.GetIndex();
    834834                        }
    835835                        else{
    836                             index_stack[sp] = (LONG_PTR)compiler.GetObjectModule().meta.GetClasses().GetObjectClassPtr();
     836                            type_stack[sp] = baseType.GetBasicType();
     837                            index_stack[sp] = baseType.GetIndex();
    837838                        }
     839
    838840                        *pIsLiteralCalculation = false;
    839841                        sp++;
  • trunk/ab5.0/abdev/BasicCompiler_Common/StrOperation.cpp

    r603 r632  
    365365            lstrcpy(name,"End Enum");
    366366            break;
     367        case ESC_OPERATOR:
     368            lstrcpy( name, "Operator" );
     369            break;
    367370    }
    368371}
     
    378381        if( temporary[i] == 1 )
    379382        {
     383            int esc = temporary[i+1];
    380384            char temp2[255];
    381             GetDefaultNameFromES( temporary[i+1], temp2 );
     385            GetDefaultNameFromES( esc, temp2 );
    382386            if( i>0 )
    383387            {
     
    391395            }
    392396
     397            int slide = 2;
     398
     399            if( esc == ESC_OPERATOR )
     400            {
     401                extern char *calcNames[256];
     402                char calcId = temporary[i+2];
     403                if( calcNames[calcId] )
     404                {
     405                    lstrcat( temp2, calcNames[calcId] );
     406                }
     407                slide = 3;
     408            }
     409
    393410            int length = lstrlen( temp2 );
    394             SlideString( temporary + i+2, length-2 );
     411            SlideString( temporary + i+slide, length-slide );
    395412            memcpy( temporary + i, temp2, length );
    396413            maxLength = lstrlen( temporary );
  • trunk/ab5.0/abdev/BasicCompiler_Common/VariableOpe.cpp

    r628 r632  
    633633        }
    634634
    635         int typeDefIndex = compiler.GetObjectModule().meta.GetTypeDefs().GetIndex( LexicalAnalyzer::FullNameToSymbol( VarName ) );
    636         if( typeDefIndex != -1 ){
     635        const TypeDef *pTypeDef = compiler.GetObjectModule().meta.GetTypeDefs().Find( LexicalAnalyzer::FullNameToSymbol( VarName ) );
     636        if( pTypeDef )
     637        {
    637638            // TypeDef後の型名だったとき
    638             lstrcpy( VarName, compiler.GetObjectModule().meta.GetTypeDefs()[typeDefIndex].GetBaseName().c_str() );
     639            lstrcpy( VarName, pTypeDef->GetBaseName().c_str() );
    639640        }
    640641
  • trunk/ab5.0/abdev/BasicCompiler_Common/include/Compiler.h

    r628 r632  
    184184
    185185
     186private:
     187    ActiveBasic::Compiler::Error::StringToTypeErrorCode::EnumType StringToGenericTypeEx( const std::string &typeName, Type &type );
     188public:
    186189    ActiveBasic::Compiler::Error::StringToTypeErrorCode::EnumType StringToTypeEx( const std::string &typeName, Type &type, bool isResolveGenerics = false );
    187190    bool StringToType( const std::string &typeName, Type &type );
  • trunk/ab5.0/abdev/BasicCompiler_Common/include/LexicalAnalyzer.h

    r625 r632  
    4343    static void CollectClasses( const char *source, Classes &classes );
    4444
     45    // テンプレート展開
     46    static void TemplateExpand_ResolveMethod( const CMethod *pBaseMethod, const Types &actualTypes, CClass *pNewClass );
     47    static const CClass *TemplateExpand( CClass &_class, const Types &actualTypes );
     48
    4549    // グローバルプロシージャを収集する
    4650    static bool AnalyzeParameter( Parameters &params, const Jenga::Common::Strings &parameterStrings, int nowLine );
  • 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    {
  • trunk/ab5.0/abdev/BasicCompiler_Common/src/LexicalAnalyzer_Class.cpp

    r603 r632  
    287287    Subscripts subscripts;
    288288    Type type;
    289     GetDimentionFormat(buffer,VarName,subscripts,type,initBuffer,lpszConstructParameter);
     289    if( !GetDimentionFormat(buffer,VarName,subscripts,type,initBuffer,lpszConstructParameter) )
     290    {
     291        return NULL;
     292    }
    290293
    291294    //重複チェック
     
    12171220                extern int cp;
    12181221                if(i3==0){
    1219                     if(bStatic){
    1220                         //静的メンバを追加
    1221                         cp=i;   //エラー用
    1222                         pobj_c->AddStaticMember(
    1223                             LexicalAnalyzer::CreateMember( *pobj_c, accessibility, isConst, false, temporary, i )
    1224                         );
    1225                     }
    1226                     else{
    1227                         //メンバを追加
    1228                         cp=i;   //エラー用
    1229                         pobj_c->AddDynamicMember(
    1230                             LexicalAnalyzer::CreateMember( *pobj_c, accessibility, isConst, false, temporary, i )
    1231                         );
    1232 
    1233 
    1234                         if(pobj_c->GetDynamicMembers().back()->GetType().IsStruct()){
    1235                             if( !pobj_c->GetDynamicMembers().back()->GetType().GetClass().IsReady() ){
    1236                                 //参照先が読み取られていないとき
    1237                                 GetClass_recur( pobj_c->GetDynamicMembers().back()->GetType().GetClass().GetName().c_str(), classes );
     1222                    cp=i;   //エラー用
     1223                    Member *pMember = LexicalAnalyzer::CreateMember( *pobj_c, accessibility, isConst, false, temporary, i );
     1224                    if( pMember )
     1225                    {
     1226                        if(bStatic)
     1227                        {
     1228                            //静的メンバを追加
     1229                            pobj_c->AddStaticMember( pMember );
     1230                        }
     1231                        else
     1232                        {
     1233                            //メンバを追加
     1234                            pobj_c->AddDynamicMember( pMember );
     1235
     1236
     1237                            if(pobj_c->GetDynamicMembers().back()->GetType().IsStruct()){
     1238                                if( !pobj_c->GetDynamicMembers().back()->GetType().GetClass().IsReady() ){
     1239                                    //参照先が読み取られていないとき
     1240                                    GetClass_recur( pobj_c->GetDynamicMembers().back()->GetType().GetClass().GetName().c_str(), classes );
     1241                                }
    12381242                            }
    1239                         }
    1240 
    1241 
    1242                         if(pobj_c->GetDynamicMembers().back()->GetType().IsStruct()){
    1243                             //循環参照のチェック
    1244                             pobj_LoopRefCheck->add(pobj_c->GetName().c_str());
    1245                             if(!MemberVar_LoopRefCheck(pobj_c->GetDynamicMembers().back()->GetType().GetClass())){
    1246                                 //エラー回避
    1247                                 Type &type = const_cast<Type &>(pobj_c->GetDynamicMembers().back()->GetType());
    1248                                 type.SetBasicType( DEF_PTR_VOID );
     1243
     1244
     1245                            if(pobj_c->GetDynamicMembers().back()->GetType().IsStruct()){
     1246                                //循環参照のチェック
     1247                                pobj_LoopRefCheck->add(pobj_c->GetName().c_str());
     1248                                if(!MemberVar_LoopRefCheck(pobj_c->GetDynamicMembers().back()->GetType().GetClass())){
     1249                                    //エラー回避
     1250                                    Type &type = const_cast<Type &>(pobj_c->GetDynamicMembers().back()->GetType());
     1251                                    type.SetBasicType( DEF_PTR_VOID );
     1252                                }
     1253                                pobj_LoopRefCheck->del(pobj_c->GetName().c_str());
    12491254                            }
    1250                             pobj_LoopRefCheck->del(pobj_c->GetName().c_str());
    12511255                        }
    12521256                    }
     
    13551359    classes.Iterator_Init();
    13561360}
     1361
     1362void LexicalAnalyzer::TemplateExpand_ResolveMethod( const CMethod *pBaseMethod, const Types &actualTypes, CClass *pNewClass )
     1363{
     1364    UserProc *pUserProc = new UserProc(
     1365        pBaseMethod->GetUserProc(),
     1366        pNewClass
     1367    );
     1368    pUserProc->Using();
     1369    pUserProc->GetParameters().clear();
     1370    pUserProc->RealParams().clear();
     1371
     1372    // パラメータのジェネリック型を解決
     1373    BOOST_FOREACH( const Parameter *pParam, pBaseMethod->GetUserProc().Params() )
     1374    {
     1375        Type type = pParam->IsTypeParameter()
     1376            ? actualTypes[pParam->GetFormalTypeIndex()]
     1377            : *pParam;
     1378        type.SetPtrLevel( pParam->PtrLevel() );
     1379
     1380        pUserProc->GetParameters().push_back( new Parameter( *pParam, type ) );
     1381    }
     1382    BOOST_FOREACH( const Parameter *pParam, pBaseMethod->GetUserProc().RealParams() )
     1383    {
     1384        Type type = pParam->IsTypeParameter()
     1385            ? actualTypes[pParam->GetFormalTypeIndex()]
     1386            : *pParam;
     1387        type.SetPtrLevel( pParam->PtrLevel() );
     1388
     1389        pUserProc->RealParams().push_back( new Parameter( *pParam, type ) );
     1390    }
     1391
     1392    // 戻り値のジェネリック型を解決
     1393    if( pUserProc->ReturnType().IsTypeParameter() )
     1394    {
     1395        Type type = actualTypes[pUserProc->ReturnType().GetFormalTypeIndex()];
     1396        type.SetPtrLevel( pUserProc->ReturnType().PtrLevel() );
     1397        pUserProc->SetReturnType( type );
     1398    }
     1399
     1400    compiler.GetObjectModule().meta.GetUserProcs().Put( pUserProc );
     1401    compiler.GetObjectModule().meta.GetUserProcs().Iterator_Init();
     1402
     1403    LexicalAnalyzer::AddMethod(
     1404        pNewClass,
     1405        pUserProc,
     1406        pBaseMethod->GetAccessibility(),
     1407        pBaseMethod->IsStatic(),
     1408        pBaseMethod->IsConst(),
     1409        pBaseMethod->IsAbstract(),
     1410        pBaseMethod->IsVirtual(),
     1411        false,
     1412        "",
     1413        false,
     1414        -1
     1415    );
     1416}
     1417
     1418const CClass *LexicalAnalyzer::TemplateExpand( CClass &_class, const Types &actualTypes )
     1419{
     1420    // 展開済みのクラスがあればそれを返す
     1421    BOOST_FOREACH( const ExpandedTemplateClass *pExpandedTemplateClass, _class.expandedTemplateClasses )
     1422    {
     1423        if( pExpandedTemplateClass->GetActualTypes().IsEquals( actualTypes ) )
     1424        {
     1425            return &pExpandedTemplateClass->GetClass();
     1426        }
     1427    }
     1428
     1429
     1430    /////////////////////////////////////////////////////////////////
     1431    // 未展開の場合は新たに展開する
     1432    /////////////////////////////////////////////////////////////////
     1433
     1434    // クラスをコピー
     1435    CClass *pNewClass = new CClass(
     1436        _class.GetNamespaceScopes(),
     1437        _class.GetImportedNamespaces(),
     1438        _class.GetName(),
     1439        _class.GetClassType(),
     1440        _class.GetFormalGenericTypes(),
     1441        actualTypes,
     1442        _class.GetConstructorMemberSubIndex(),
     1443        _class.GetDestructorMemberSubIndex(),
     1444        0,
     1445        _class.GetFixedAlignment()
     1446    );
     1447
     1448    // 基底クラス
     1449    pNewClass->SetSuperClass( &_class.GetSuperClass() );
     1450
     1451    // インターフェイスのジェネリック型を解決
     1452    BOOST_FOREACH( const ::Interface *pInterface, _class.GetInterfaces() )
     1453    {
     1454        pNewClass->AddInterface( new ::Interface( &pInterface->GetClass(), actualTypes ) );
     1455    }
     1456
     1457    // メンバのジェネリック型を解決
     1458    BOOST_FOREACH( const Member *pMember, _class.GetDynamicMembers() )
     1459    {
     1460        Type type = pMember->GetType();
     1461        if( type.IsTypeParameter() )
     1462        {
     1463            // ジェネリック型だったときは値型に変換
     1464            type = actualTypes[type.GetFormalTypeIndex()];
     1465            type.SetPtrLevel( pMember->GetType().PtrLevel() );
     1466        }
     1467
     1468        pNewClass->GetDynamicMembers().push_back(
     1469            new Member( *pMember, type )
     1470        );
     1471    }
     1472
     1473    // クラス メソッドのジェネリック型を解決
     1474    BOOST_FOREACH( const CMethod *pMethod, _class.GetDynamicMethods() )
     1475    {
     1476        if( pMethod->GetUserProc().GetParentClassPtr() == &_class )
     1477        {
     1478            // ターゲットクラス内で実装されるメソッドの場合
     1479
     1480            TemplateExpand_ResolveMethod( pMethod, actualTypes, pNewClass );
     1481        }
     1482        else
     1483        {
     1484            DynamicMethod *pNewDynamicMethod = new DynamicMethod( *pMethod );
     1485            pNewClass->GetDynamicMethods().push_back( pNewDynamicMethod );
     1486        }
     1487    }
     1488
     1489    // インターフェイス メソッドのジェネリック型を解決
     1490    BOOST_FOREACH( const ::Interface *pInterface, _class.GetInterfaces() )
     1491    {
     1492        BOOST_FOREACH( const CMethod *pMethod, pInterface->GetDynamicMethods() )
     1493        {
     1494            TemplateExpand_ResolveMethod( pMethod, actualTypes, pNewClass );
     1495        }
     1496    }
     1497
     1498    pNewClass->SetVtblNum( _class.GetVtblNum() );
     1499
     1500    // 展開済みクラスとして登録
     1501    _class.expandedTemplateClasses.push_back( new ExpandedTemplateClass( pNewClass, actualTypes ) );
     1502
     1503    pNewClass->Readed();
     1504
     1505    return pNewClass;
     1506}
  • trunk/ab5.0/abdev/BasicCompiler_Common/src/LexicalAnalyzer_Procedure.cpp

    r574 r632  
    156156
    157157    //ソースコードの位置
    158     userProc.SetCodePos( nowLine );
     158    userProc.SetSourceCodePosition( SourceCodePosition( compiler.GetObjectModule().GetName(), nowLine ) );
    159159
    160160    //パラメータ
     
    286286
    287287    //ソースコードの位置
    288     pProc->SetCodePos( nowLine );
     288    pProc->SetSourceCodePosition( SourceCodePosition( compiler.GetObjectModule().GetName(), nowLine ) );
    289289
    290290    //パラメータ
  • trunk/ab5.0/abdev/BasicCompiler_Common/src/VtblGenerator.cpp

    r593 r632  
    9696    while( classes.Iterator_HasNext() )
    9797    {
    98         GenerateFullVTables( *classes.Iterator_GetNext() );
     98        CClass *pClass = classes.Iterator_GetNext();
     99        GenerateFullVTables( *pClass );
     100
     101        // テンプレート展開されたクラスも
     102        BOOST_FOREACH( ActiveBasic::Common::Lexical::ExpandedTemplateClass *pExpandedTemplateClass, pClass->expandedTemplateClasses )
     103        {
     104            if( !pExpandedTemplateClass->GetClass().expandedTemplateClasses.empty() )
     105            {
     106                // テンプレート展開後のクラスが更にテンプレート展開されていることはありえない
     107                throw;
     108            }
     109
     110            GenerateFullVTables( pExpandedTemplateClass->GetClass() );
     111        }
    99112    }
    100113}
     
    167180    while( classes.Iterator_HasNext() )
    168181    {
    169         ActionVtblSchedule( *classes.Iterator_GetNext(), ImageBase, MemPos_CodeSection, MemPos_DataSection );
     182        CClass *pClass = classes.Iterator_GetNext();
     183        ActionVtblSchedule( *pClass, ImageBase, MemPos_CodeSection, MemPos_DataSection );
     184
     185        // テンプレート展開されたクラスも
     186        BOOST_FOREACH( ActiveBasic::Common::Lexical::ExpandedTemplateClass *pExpandedTemplateClass, pClass->expandedTemplateClasses )
     187        {
     188            if( !pExpandedTemplateClass->GetClass().expandedTemplateClasses.empty() )
     189            {
     190                // テンプレート展開後のクラスが更にテンプレート展開されていることはありえない
     191                throw;
     192            }
     193
     194            ActionVtblSchedule( pExpandedTemplateClass->GetClass(), ImageBase, MemPos_CodeSection, MemPos_DataSection );
     195        }
    170196    }
    171197}
Note: See TracChangeset for help on using the changeset viewer.