Ignore:
Timestamp:
Nov 11, 2007, 3:12:06 PM (17 years ago)
Author:
dai_9181
Message:

Throw→Catch間のパラメータ引渡しに対応。
グローバル領域でのTryスコープを可能にした。これで例外処理機構実装完了。
エディタの補間機能にTry/Catch/Finally/EndTryを追加。

Location:
trunk/abdev/BasicCompiler_Common/src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/abdev/BasicCompiler_Common/src/Exception.cpp

    r361 r364  
    103103    void Try()
    104104    {
     105        // レキシカルスコープをレベルアップ
     106        compiler.codeGenerator.lexicalScopes.Start(
     107            compiler.codeGenerator.GetNativeCodeSize(),
     108            LexicalScope::SCOPE_TRY
     109        );
    105110    }
    106111
     
    113118        }
    114119
     120        if( catchScopes.size() )
     121        {
     122            // 既に1回以上のCatchが存在するとき
     123
     124            // レキシカルスコープをレベルダウン
     125            compiler.codeGenerator.lexicalScopes.End();
     126        }
     127
    115128        JmpFinally();
    116129
    117130        catchScopes.push_back( CatchScope( paramType, compiler.codeGenerator.GetNativeCodeSize() ) );
     131
     132        // レキシカルスコープをレベルアップ
     133        compiler.codeGenerator.lexicalScopes.Start(
     134            compiler.codeGenerator.GetNativeCodeSize(),
     135            LexicalScope::SCOPE_CATCH
     136        );
    118137    }
    119138    void Finally()
     
    125144        }
    126145
     146        if( catchScopes.size() )
     147        {
     148            // 既に1回以上のCatchが存在するとき
     149
     150            // レキシカルスコープをレベルダウン
     151            compiler.codeGenerator.lexicalScopes.End();
     152        }
     153
    127154        isDefinedFinally = true;
    128155
    129156        ResolveJmpFinally();
     157
     158        // レキシカルスコープをレベルアップ
     159        compiler.codeGenerator.lexicalScopes.Start(
     160            compiler.codeGenerator.GetNativeCodeSize(),
     161            LexicalScope::SCOPE_FINALLY
     162        );
    130163    }
    131164
     
    136169            Finally();
    137170        }
     171
     172        if( catchScopes.size() || isDefinedFinally )
     173        {
     174            // 既に1回以上のCatch、またはFinallyが存在するとき
     175
     176            // レキシカルスコープをレベルダウン
     177            compiler.codeGenerator.lexicalScopes.End();
     178        }
     179
     180        // レキシカルスコープをレベルダウン
     181        compiler.codeGenerator.lexicalScopes.End();
    138182    }
    139183
     
    174218
    175219            // Catchアドレス
    176             compiler.GetObjectModule().dataTable.schedules.push_back( Schedule( &UserProc::CompilingUserProc(), dataTableOffset + pos ) );
     220            const UserProc *pUserProc = &UserProc::CompilingUserProc();
     221            if( UserProc::IsGlobalAreaCompiling() )
     222            {
     223                pUserProc = UserProc::pGlobalProc;
     224            }
     225            compiler.GetObjectModule().dataTable.schedules.push_back( Schedule( pUserProc, dataTableOffset + pos ) );
    177226            compiler.GetObjectModule().dataTable.schedules.back().SpecifyCatchAddress();
    178227            pos += sizeof(LONG_PTR);
     
    188237void TryCommand()
    189238{
    190     if( UserProc::IsGlobalAreaCompiling() )
    191     {
    192         SetError();
    193     }
    194 
    195239    tryScopes.push_back( TryScope() );
    196240    tryScopes.back().Try();
     
    213257    }
    214258
     259    char varName[VN_SIZE];
    215260    Type paramType;
    216261    if( parameter[0] )
    217262    {
    218         char varName[VN_SIZE], typeName[VN_SIZE];
     263        char typeName[VN_SIZE];
    219264        SplitSyntacticForAs( parameter, varName, typeName );
    220265        if( !typeName[0] )
     
    232277
    233278    tryScopes.back().Catch( paramType );
     279
     280    if( paramType.IsObject() )
     281    {
     282        int backCp = cp;
     283
     284        char temporary[1024];
     285        sprintf( temporary, "Dim %s = Thread.CurrentThread().__GetThrowintParamObject() As %s", varName, paramType.GetClass().GetFullName().c_str() );
     286        MakeMiddleCode( temporary );
     287        ChangeOpcode( temporary );
     288        lstrcpy( temporary, "Thread.CurrentThread().__Catched()" );
     289        MakeMiddleCode( temporary );
     290        ChangeOpcode( temporary );
     291
     292        cp = backCp;
     293    }
    234294}
    235295void FinallyCommand()
  • trunk/abdev/BasicCompiler_Common/src/NativeCode.cpp

    r357 r364  
    4343    if( scheduleType == Schedule::CatchAddress )
    4444    {
    45         PutCatchAddressSchedule( &UserProc::CompilingUserProc(), l );
     45        const UserProc *pUserProc = &UserProc::CompilingUserProc();
     46        if( UserProc::IsGlobalAreaCompiling() )
     47        {
     48            pUserProc = UserProc::pGlobalProc;
     49        }
     50        PutCatchAddressSchedule( pUserProc, l );
    4651    }
    4752    else
  • trunk/abdev/BasicCompiler_Common/src/Procedure.cpp

    r353 r364  
    434434
    435435const UserProc *UserProc::pCompilingUserProc = NULL;
     436const UserProc *UserProc::pGlobalProc = NULL;
    436437
    437438
Note: See TracChangeset for help on using the changeset viewer.