Ignore:
Timestamp:
May 7, 2008, 10:12:21 AM (16 years ago)
Author:
dai_9181
Message:

ParseDllProc/SetParamsAndReturnTypeForUserProcを実装。

File:
1 edited

Legend:

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

    r571 r572  
    146146        //パラメータを追加
    147147        params.push_back( pParam );
     148    }
     149
     150    return true;
     151}
     152
     153bool LexicalAnalyzer::SetParamsAndReturnTypeForUserProc( UserProc &userProc, const char *sourceOfParams, int nowLine, bool isStatic )
     154{
     155    int i = 0;
     156
     157    //ソースコードの位置
     158    userProc.SetCodePos( nowLine );
     159
     160    //パラメータ
     161    if(sourceOfParams[i]!='('){
     162        compiler.errorMessenger.Output(1,NULL,nowLine);
     163        return false;
     164    }
     165    if(sourceOfParams[i + 1]!=')'&& userProc.HasParentClass() ){
     166        //クラスのメンバ関数の場合のみ、デストラクタにパラメータがある場合にエラーをだす
     167        if(userProc.GetName()[0]=='~'){
     168            compiler.errorMessenger.Output(114,NULL,nowLine);
     169            return false;
     170        }
     171    }
     172
     173    // カッコ内のパラメータ文字列を取得
     174    char parametersStr1[8192];
     175    char parametersStr2[8192] = "";
     176    i += GetStringInPare( parametersStr1, sourceOfParams + i, true );
     177    if( sourceOfParams[i] == '(' )
     178    {
     179        i += GetStringInPare( parametersStr2, sourceOfParams + i, true );
     180    }
     181
     182    // 戻り値文字列を取得
     183    char returnTypeStr[VN_SIZE] = "";
     184    if( sourceOfParams[i] )
     185    {
     186        if( sourceOfParams[i] == 1 && sourceOfParams[i+1] == ESC_AS )
     187        {
     188            if( !userProc.IsFunction() ){
     189                // Sub/Macroの場合
     190                compiler.errorMessenger.Output(38,userProc.GetName(),nowLine);
     191            }
     192
     193            lstrcpy( returnTypeStr, sourceOfParams + i + 2 );
     194        }
     195        else
     196        {
     197            compiler.errorMessenger.Output(1,NULL,nowLine);
     198            return false;
     199        }
     200    }
     201
     202    Jenga::Common::Strings parameters;
     203
     204    // パラメータ
     205    SplitParameter( parametersStr1, parameters );
     206    ActiveBasic::Compiler::LexicalAnalyzer::AnalyzeParameter( userProc.GetParameters(), parameters, nowLine );
     207
     208    // 省略可能パラメータ(古い仕様。非推奨)
     209    userProc.SetSecondParmNum( (int)userProc.GetParameters().size() );
     210    SplitParameter( parametersStr2, parameters );
     211    ActiveBasic::Compiler::LexicalAnalyzer::AnalyzeParameter( userProc.GetParameters(), parameters, nowLine );
     212
     213
     214    if(returnTypeStr[0]){
     215        ///////////////////
     216        // 戻り値を取得
     217        ///////////////////
     218
     219        if( !userProc.IsFunction() ){
     220            // Sub/Macroの場合
     221            compiler.errorMessenger.Output(38,userProc.GetName(),nowLine);
     222        }
     223
     224        if( userProc.HasParentClass() ){
     225            if( userProc.GetName() == userProc.GetParentClassPtr()->GetName() ||
     226                userProc.GetName()[0]=='~'){
     227                //クラスのコンストラクタ、デストラクタがFunction定義の場合はエラーをだす
     228                compiler.errorMessenger.Output(115,NULL,nowLine);
     229            }
     230        }
     231
     232        compiler.StringToType( returnTypeStr, userProc.ReturnType() );
     233        if( userProc.ReturnType().IsNull() )
     234        {
     235            compiler.errorMessenger.Output(3,returnTypeStr,nowLine);
     236        }
     237    }
     238    else{
     239        if( userProc.IsFunction() )
     240        {
     241            // Function定義なのに、戻り値の型がセットされていない
     242            compiler.errorMessenger.Output(-104,userProc.GetName().c_str(),nowLine);
     243
     244            userProc.ReturnType().SetBasicType( DEF_DOUBLE );
     245        }
     246        else
     247        {
     248            //戻り値なしのSub定義
     249            userProc.ReturnType().SetNull();
     250        }
     251    }
     252
     253    //リアルパラメータ領域を取得(_System_LocalThisを考慮して2つだけ多く確保する場合がある)
     254
     255    if( userProc.HasParentClass() && isStatic == false ){
     256        //オブジェクトメンバの場合は、第一パラメータを_System_LocalThis引き渡し用として利用
     257        std::string name = "_System_LocalThis";
     258        Type type( DEF_PTR_VOID );
     259        userProc.RealParams().push_back( new Parameter( name, type ) );
     260    }
     261
     262    if( userProc.ReturnType().IsStruct() ){
     263        //構造体を戻り値として持つ場合
     264        //※第一パラメータ(Thisポインタありの場合は第二パラメータ)を戻り値用の参照宣言にする
     265
     266        std::string name = userProc.GetName();
     267        if(name[0]==1&&name[1]==ESC_OPERATOR){
     268            name="_System_ReturnValue";
     269        }
     270        Type type( DEF_STRUCT, userProc.ReturnType().GetIndex() );
     271        userProc.RealParams().push_back( new Parameter( name, type, true ) );
     272    }
     273
     274    //パラメータをコピー
     275    BOOST_FOREACH( Parameter *pParam, userProc.GetParameters() ){
     276        userProc.RealParams().push_back( new Parameter( *pParam ) );
    148277    }
    149278
     
    318447    // パラメータを解析
    319448    // ※第1パラメータにに指定するデータの例:"( s As String ) As String"
    320     pUserProc->SetParamsAndReturnType( buffer + i, nowLine, isStatic );
     449    SetParamsAndReturnTypeForUserProc( *pUserProc, buffer + i, nowLine, isStatic );
    321450
    322451    pUserProc->_paramStr = buffer + i;
    323452
    324453    return pUserProc;
     454}
     455
     456DllProc *LexicalAnalyzer::ParseDllProc(const NamespaceScopes &namespaceScopes, char *buffer,int nowLine)
     457{
     458    int i2;
     459
     460    int i=0;
     461
     462    //Sub/Function
     463    Procedure::Kind kind = Procedure::Sub;
     464    if(buffer[i]==ESC_SUB){
     465    }
     466    else if(buffer[i]==ESC_FUNCTION){
     467        kind = Procedure::Function;
     468    }
     469    else{
     470        compiler.errorMessenger.Output(1,NULL,nowLine);
     471        return NULL;
     472    }
     473    i++;
     474
     475    //プロシージャ名
     476    char procName[VN_SIZE];
     477    bool isCdecl = false;
     478    for(i2=0;;i++,i2++){
     479        if(buffer[i]==1&&buffer[i+1]==ESC_CDECL){
     480            isCdecl = true;
     481
     482            i+=2;
     483            procName[i2]=0;
     484            break;
     485        }
     486        if(buffer[i]==','){
     487            procName[i2]=0;
     488            break;
     489        }
     490        if(buffer[i]=='\0'){
     491            compiler.errorMessenger.Output(1,NULL,nowLine);
     492            return NULL;
     493        }
     494        procName[i2]=buffer[i];
     495    }
     496    i++;
     497
     498    //ユーザー定義関数との重複チェック
     499    if(GetSubHash(procName)){
     500        compiler.errorMessenger.Output(15,procName,nowLine);
     501        return NULL;
     502    }
     503
     504
     505    //ライブラリ
     506    char dllFileName[MAX_PATH];
     507    i = GetOneParameter( buffer, i, dllFileName );
     508    Type resultType;
     509    _int64 i64data;
     510    if( !StaticCalculation( true, dllFileName, 0, &i64data, resultType ) ){
     511        return NULL;
     512    }
     513    if( resultType.GetBasicType() != typeOfPtrChar ){
     514        compiler.errorMessenger.Output(1,NULL,nowLine);
     515        return NULL;
     516    }
     517    lstrcpy( dllFileName, (char *)i64data );
     518    CharUpper(dllFileName);
     519    if(!strstr(dllFileName,".")){
     520        lstrcat(dllFileName,".DLL");
     521        if(lstrlen(dllFileName)>=16){
     522            compiler.errorMessenger.Output(7,NULL,nowLine);
     523            return NULL;
     524        }
     525    }
     526
     527    //エイリアス
     528    char alias[VN_SIZE];
     529    i = GetOneParameter( buffer, i, alias );
     530    if( alias[0] ){
     531        if( !StaticCalculation( true, alias, 0, &i64data, resultType ) ){
     532            return NULL;
     533        }
     534        if( resultType.GetBasicType() != typeOfPtrChar ){
     535            compiler.errorMessenger.Output(1,NULL,nowLine);
     536            return NULL;
     537        }
     538        lstrcpy( alias, (char *)i64data );
     539    }
     540    else{
     541        //省略されたときは関数名
     542        lstrcpy( alias, procName );
     543    }
     544
     545
     546    // オブジェクトを生成
     547    DllProc *pDllProc = new DllProc( namespaceScopes, procName, kind, isCdecl, dllFileName, alias );
     548
     549    // パラメータを解析
     550    // ※第1パラメータにに指定するデータの例:"( s As String ) As String"
     551    pDllProc->SetParamsAndReturnType( buffer + i, nowLine );
     552
     553    // パラメータのエラーチェック
     554    BOOST_FOREACH( const Parameter *pParam, pDllProc->Params() ){
     555        if( pParam->IsObject() ){
     556            compiler.errorMessenger.Output(25,pParam->GetVarName(),nowLine);
     557        }
     558        if( !pParam->IsRef() ){
     559            if( pParam->IsStruct() ){
     560                compiler.errorMessenger.Output(28,pParam->GetVarName(),nowLine);
     561            }
     562        }
     563    }
     564
     565    //戻り値のエラーチェック
     566    if( pDllProc->IsFunction() ){
     567        // Function定義
     568
     569        if( pDllProc->ReturnType().IsObject() ){
     570            // DLL関数ではオブジェクトを戻り値にできない
     571            compiler.errorMessenger.Output(40,pDllProc->GetName(),nowLine);
     572        }
     573    }
     574
     575    return pDllProc;
    325576}
    326577
     
    411662                if(source[i]=='\0') break;
    412663            }
    413             dllProcs.Add(namespaceScopes,temporary,i);
     664            DllProc *pDllProc = ParseDllProc( namespaceScopes, temporary, i );
     665            dllProcs.Put( pDllProc );
    414666
    415667            continue;
Note: See TracChangeset for help on using the changeset viewer.