Changeset 572 in dev for trunk


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

ParseDllProc/SetParamsAndReturnTypeForUserProcを実装。

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

Legend:

Unmodified
Added
Removed
  • trunk/ab5.0/abdev/BasicCompiler_Common/include/LexicalAnalyzer.h

    r571 r572  
    5656    // グローバルプロシージャを収集する
    5757    static bool AnalyzeParameter( Parameters &params, const Jenga::Common::Strings &parameterStrings, int nowLine );
     58    static bool SetParamsAndReturnTypeForUserProc( UserProc &userProc, const char *sourceOfParams, int nowLine, bool isStatic );
    5859    static UserProc* ParseUserProc( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, char *buffer,int nowLine,bool isVirtual,CClass *pobj_c, bool isStatic, char *interfaceName = NULL );
     60    static DllProc *ParseDllProc(const NamespaceScopes &namespaceScopes, char *buffer,int nowLine);
    5961    static void CollectProcedures( const char *source, UserProcs &userProcs, DllProcs &dllProcs );
    6062
  • trunk/ab5.0/abdev/BasicCompiler_Common/include/Procedure.h

    r537 r572  
    2020    mutable bool isUsing;
    2121
    22 protected:
    23 
    2422    // パラメータ
    2523    Parameters params;
     24
     25protected:
    2626
    2727    // 戻り値の型
     
    9191        return codePos;
    9292    }
     93    void SetCodePos( int codePos )
     94    {
     95        this->codePos = codePos;
     96    }
    9397
    9498    const Parameters &Params() const
     
    96100        return params;
    97101    }
     102    Parameters &GetParameters()
     103    {
     104        return params;
     105    }
    98106    const Type &ReturnType() const
     107    {
     108        return returnType;
     109    }
     110    Type &ReturnType()
    99111    {
    100112        return returnType;
     
    238250        return secondParmNum;
    239251    }
     252    void SetSecondParmNum( int secondParmNum )
     253    {
     254        this->secondParmNum = secondParmNum;
     255    }
    240256    const Parameters &RealParams() const
     257    {
     258        return realParams;
     259    }
     260    Parameters &RealParams()
    241261    {
    242262        return realParams;
     
    481501            boost::serialization::base_object<Jenga::Common::Hashmap<DllProc>>(*this));
    482502    }
    483 
    484 public:
    485     void Add(const NamespaceScopes &namespaceScopes, char *buffer,int nowLine);
    486503};
    487504
  • trunk/ab5.0/abdev/BasicCompiler_Common/src/Delegate.cpp

    r571 r572  
    1111    Jenga::Common::Strings parameterStrings;
    1212    SplitParameter( paramStr, parameterStrings );
    13     ActiveBasic::Compiler::LexicalAnalyzer::AnalyzeParameter( params, parameterStrings, sourceIndex );
     13    ActiveBasic::Compiler::LexicalAnalyzer::AnalyzeParameter( this->GetParameters(), parameterStrings, sourceIndex );
    1414
    1515    // 動的パラメータを作る
    16     dynamicParams = params;
     16    dynamicParams = this->GetParameters();
    1717    dynamicParams.insert( dynamicParams.begin(), new Parameter( "_System_LocalThis", Type( DEF_PTR_VOID ) ) );
    1818
  • 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;
  • trunk/ab5.0/abdev/BasicCompiler_Common/src/Procedure.cpp

    r571 r572  
    9494    }
    9595    return *pMethod;
    96 }
    97 
    98 bool UserProc::SetParamsAndReturnType( const char *sourceOfParams, int nowLine, bool isStatic ){
    99     int i = 0;
    100 
    101     //ソースコードの位置
    102     this->codePos = nowLine;
    103 
    104     //パラメータ
    105     if(sourceOfParams[i]!='('){
    106         compiler.errorMessenger.Output(1,NULL,nowLine);
    107         return false;
    108     }
    109     if(sourceOfParams[i + 1]!=')'&& this->pParentClass ){
    110         //クラスのメンバ関数の場合のみ、デストラクタにパラメータがある場合にエラーをだす
    111         if(this->GetName()[0]=='~'){
    112             compiler.errorMessenger.Output(114,NULL,nowLine);
    113             return false;
    114         }
    115     }
    116 
    117     // カッコ内のパラメータ文字列を取得
    118     char parametersStr1[8192];
    119     char parametersStr2[8192] = "";
    120     i += GetStringInPare( parametersStr1, sourceOfParams + i, true );
    121     if( sourceOfParams[i] == '(' )
    122     {
    123         i += GetStringInPare( parametersStr2, sourceOfParams + i, true );
    124     }
    125 
    126     // 戻り値文字列を取得
    127     char returnTypeStr[VN_SIZE] = "";
    128     if( sourceOfParams[i] )
    129     {
    130         if( sourceOfParams[i] == 1 && sourceOfParams[i+1] == ESC_AS )
    131         {
    132             if( !this->IsFunction() ){
    133                 // Sub/Macroの場合
    134                 compiler.errorMessenger.Output(38,this->GetName(),nowLine);
    135             }
    136 
    137             lstrcpy( returnTypeStr, sourceOfParams + i + 2 );
    138         }
    139         else
    140         {
    141             compiler.errorMessenger.Output(1,NULL,nowLine);
    142             return false;
    143         }
    144     }
    145 
    146     Jenga::Common::Strings parameters;
    147 
    148     // パラメータ
    149     SplitParameter( parametersStr1, parameters );
    150     ActiveBasic::Compiler::LexicalAnalyzer::AnalyzeParameter( params, parameters, nowLine );
    151 
    152     // 省略可能パラメータ(古い仕様。非推奨)
    153     this->secondParmNum = (int)this->params.size();
    154     SplitParameter( parametersStr2, parameters );
    155     ActiveBasic::Compiler::LexicalAnalyzer::AnalyzeParameter( params, parameters, nowLine );
    156 
    157 
    158     if(returnTypeStr[0]){
    159         ///////////////////
    160         // 戻り値を取得
    161         ///////////////////
    162 
    163         if( !this->IsFunction() ){
    164             // Sub/Macroの場合
    165             compiler.errorMessenger.Output(38,this->GetName(),nowLine);
    166         }
    167 
    168         if( this->pParentClass ){
    169             if( this->GetName() == this->pParentClass->GetName() ||
    170                 this->GetName()[0]=='~'){
    171                 //クラスのコンストラクタ、デストラクタがFunction定義の場合はエラーをだす
    172                 compiler.errorMessenger.Output(115,NULL,nowLine);
    173             }
    174         }
    175 
    176         compiler.StringToType( returnTypeStr, this->returnType );
    177         if( this->returnType.IsNull() )
    178         {
    179             compiler.errorMessenger.Output(3,returnTypeStr,nowLine);
    180         }
    181     }
    182     else{
    183         if( this->IsFunction() )
    184         {
    185             // Function定義なのに、戻り値の型がセットされていない
    186             compiler.errorMessenger.Output(-104,this->GetName().c_str(),nowLine);
    187 
    188             this->returnType.SetBasicType( DEF_DOUBLE );
    189         }
    190         else
    191         {
    192             //戻り値なしのSub定義
    193             this->returnType.SetNull();
    194         }
    195     }
    196 
    197     //リアルパラメータ領域を取得(_System_LocalThisを考慮して2つだけ多く確保する場合がある)
    198 
    199     if( this->pParentClass && isStatic == false ){
    200         //オブジェクトメンバの場合は、第一パラメータを_System_LocalThis引き渡し用として利用
    201         std::string name = "_System_LocalThis";
    202         Type type( DEF_PTR_VOID );
    203         this->realParams.push_back( new Parameter( name, type ) );
    204     }
    205 
    206     if( this->returnType.IsStruct() ){
    207         //構造体を戻り値として持つ場合
    208         //※第一パラメータ(Thisポインタありの場合は第二パラメータ)を戻り値用の参照宣言にする
    209 
    210         std::string name = this->GetName();
    211         if(name[0]==1&&name[1]==ESC_OPERATOR){
    212             name="_System_ReturnValue";
    213         }
    214         Type type( DEF_STRUCT, this->returnType.GetIndex() );
    215         this->realParams.push_back( new Parameter( name, type, true ) );
    216     }
    217 
    218     //パラメータをコピー
    219     BOOST_FOREACH( Parameter *pParam, params ){
    220         this->realParams.push_back( new Parameter( *pParam ) );
    221     }
    222 
    223     return true;
    22496}
    22597
     
    383255
    384256        //パラメータを追加
    385         this->params.push_back( pParam );
     257        this->GetParameters().push_back( pParam );
    386258
    387259        if(sourceOfParams[i]==','){
     
    435307}
    436308
    437 void DllProcs::Add(const NamespaceScopes &namespaceScopes, char *buffer,int nowLine){
    438     int i2;
    439 
    440     int i=0;
    441 
    442     //Sub/Function
    443     Procedure::Kind kind = Procedure::Sub;
    444     if(buffer[i]==ESC_SUB){
    445     }
    446     else if(buffer[i]==ESC_FUNCTION){
    447         kind = Procedure::Function;
    448     }
    449     else{
    450         compiler.errorMessenger.Output(1,NULL,nowLine);
    451         return;
    452     }
    453     i++;
    454 
    455     //プロシージャ名
    456     char procName[VN_SIZE];
    457     bool isCdecl = false;
    458     for(i2=0;;i++,i2++){
    459         if(buffer[i]==1&&buffer[i+1]==ESC_CDECL){
    460             isCdecl = true;
    461 
    462             i+=2;
    463             procName[i2]=0;
    464             break;
    465         }
    466         if(buffer[i]==','){
    467             procName[i2]=0;
    468             break;
    469         }
    470         if(buffer[i]=='\0'){
    471             compiler.errorMessenger.Output(1,NULL,nowLine);
    472             return;
    473         }
    474         procName[i2]=buffer[i];
    475     }
    476     i++;
    477 
    478     //ユーザー定義関数との重複チェック
    479     if(GetSubHash(procName)){
    480         compiler.errorMessenger.Output(15,procName,nowLine);
    481         return;
    482     }
    483 
    484 
    485     //ライブラリ
    486     char dllFileName[MAX_PATH];
    487     i = GetOneParameter( buffer, i, dllFileName );
    488     Type resultType;
    489     _int64 i64data;
    490     if( !StaticCalculation( true, dllFileName, 0, &i64data, resultType ) ){
    491         return;
    492     }
    493     if( resultType.GetBasicType() != typeOfPtrChar ){
    494         compiler.errorMessenger.Output(1,NULL,nowLine);
    495         return;
    496     }
    497     lstrcpy( dllFileName, (char *)i64data );
    498     CharUpper(dllFileName);
    499     if(!strstr(dllFileName,".")){
    500         lstrcat(dllFileName,".DLL");
    501         if(lstrlen(dllFileName)>=16){
    502             compiler.errorMessenger.Output(7,NULL,nowLine);
    503             return;
    504         }
    505     }
    506 
    507     //エイリアス
    508     char alias[VN_SIZE];
    509     i = GetOneParameter( buffer, i, alias );
    510     if( alias[0] ){
    511         if( !StaticCalculation( true, alias, 0, &i64data, resultType ) ){
    512             return;
    513         }
    514         if( resultType.GetBasicType() != typeOfPtrChar ){
    515             compiler.errorMessenger.Output(1,NULL,nowLine);
    516             return;
    517         }
    518         lstrcpy( alias, (char *)i64data );
    519     }
    520     else{
    521         //省略されたときは関数名
    522         lstrcpy( alias, procName );
    523     }
    524 
    525 
    526     // オブジェクトを生成
    527     DllProc *pDllProc = new DllProc( namespaceScopes, procName, kind, isCdecl, dllFileName, alias );
    528 
    529     // パラメータを解析
    530     // ※第1パラメータにに指定するデータの例:"( s As String ) As String"
    531     pDllProc->SetParamsAndReturnType( buffer + i, nowLine );
    532 
    533     // パラメータのエラーチェック
    534     BOOST_FOREACH( const Parameter *pParam, pDllProc->Params() ){
    535         if( pParam->IsObject() ){
    536             compiler.errorMessenger.Output(25,pParam->GetVarName(),nowLine);
    537         }
    538         if( !pParam->IsRef() ){
    539             if( pParam->IsStruct() ){
    540                 compiler.errorMessenger.Output(28,pParam->GetVarName(),nowLine);
    541             }
    542         }
    543     }
    544 
    545     //戻り値のエラーチェック
    546     if( pDllProc->IsFunction() ){
    547         // Function定義
    548 
    549         if( pDllProc->ReturnType().IsObject() ){
    550             // DLL関数ではオブジェクトを戻り値にできない
    551             compiler.errorMessenger.Output(40,pDllProc->GetName(),nowLine);
    552         }
    553     }
    554 
    555     // ハッシュマップに追加
    556     this->Put( pDllProc );
    557 }
    558 
    559309bool ProcPointer::SetParamsAndReturnType( const char *sourceOfParams, int nowLine ){
    560310    int i = 0;
     
    676426
    677427        //パラメータを追加
    678         this->params.push_back( pParam );
     428        this->GetParameters().push_back( pParam );
    679429
    680430        if(sourceOfParams[i]==','){
Note: See TracChangeset for help on using the changeset viewer.