Changeset 572 in dev for trunk/ab5.0/abdev/BasicCompiler_Common/src/LexicalAnalyzer_Procedure.cpp
- Timestamp:
- May 7, 2008, 10:12:21 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/ab5.0/abdev/BasicCompiler_Common/src/LexicalAnalyzer_Procedure.cpp
r571 r572 146 146 //パラメータを追加 147 147 params.push_back( pParam ); 148 } 149 150 return true; 151 } 152 153 bool 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 ) ); 148 277 } 149 278 … … 318 447 // パラメータを解析 319 448 // ※第1パラメータにに指定するデータの例:"( s As String ) As String" 320 pUserProc->SetParamsAndReturnType(buffer + i, nowLine, isStatic );449 SetParamsAndReturnTypeForUserProc( *pUserProc, buffer + i, nowLine, isStatic ); 321 450 322 451 pUserProc->_paramStr = buffer + i; 323 452 324 453 return pUserProc; 454 } 455 456 DllProc *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; 325 576 } 326 577 … … 411 662 if(source[i]=='\0') break; 412 663 } 413 dllProcs.Add(namespaceScopes,temporary,i); 664 DllProc *pDllProc = ParseDllProc( namespaceScopes, temporary, i ); 665 dllProcs.Put( pDllProc ); 414 666 415 667 continue;
Note:
See TracChangeset
for help on using the changeset viewer.