source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/src/Procedure.cpp@ 523

Last change on this file since 523 was 523, checked in by dai_9181, 16 years ago

ヘッダファイルを整理中

File size: 22.7 KB
RevLine 
[206]1#include "stdafx.h"
2
[193]3#include <Compiler.h>
[206]4#include <Procedure.h>
[184]5
6#include "../common.h"
7#ifdef _AMD64_
[485]8#include "../../compiler_x64/opcode.h"
[184]9#else
[484]10#include "../../compiler_x86/opcode.h"
[184]11#endif
12
[509]13using namespace ActiveBasic::Compiler;
[206]14
[509]15
[382]16bool UserProc::IsEqualForOverride( const Types &actualTypeParametersForThisProc, const UserProc *pUserProc ) const
17{
18 if( this->GetName() == pUserProc->GetName() // 名前空間及び名前が等しい
[383]19 && this->Params().Equals( actualTypeParametersForThisProc, pUserProc->Params() ) ) // パラメータが等しい
[382]20 {
21 if( this->returnType.Equals( pUserProc->returnType ) )
22 {
23 // 戻り値が等しい
24 return true;
25 }
[447]26 else if( this->returnType.IsCovariant( pUserProc->returnType ) )
[382]27 {
[447]28 // 戻り値が共変
29 return true;
30 }
31 else if( this->returnType.IsTypeParameter() )
32 {
[382]33 // 型パラメータだったとき
[447]34
[382]35 if( actualTypeParametersForThisProc[this->returnType.GetFormalTypeIndex()].Equals( pUserProc->returnType ) )
36 {
37 // 戻り値が等しい
38 return true;
39 }
[447]40 else if( actualTypeParametersForThisProc[this->returnType.GetFormalTypeIndex()].IsCovariant( pUserProc->returnType ) )
41 {
42 // 戻り値が共変
43 return true;
44 }
[382]45 }
46 }
47 return false;
48}
49
50
[206]51std::string UserProc::GetFullName() const
52{
53 if( HasParentClass() ){
54 return GetParentClass().GetName() + "." + GetName();
55 }
56
57 return GetName();
58}
[350]59bool UserProc::IsCastOperator() const
60{
61 if( GetName()[0] == 1 && GetName()[1] == ESC_OPERATOR && GetName()[2] == CALC_AS )
62 {
63 return true;
64 }
65 return false;
66}
[206]67const NamespaceScopes &UserProc::GetNamespaceScopes() const
68{
69 if( HasParentClass() ){
70 return GetParentClassPtr()->GetNamespaceScopes();
71 }
[208]72 return Symbol::GetNamespaceScopes();
[206]73}
74const NamespaceScopesCollection &UserProc::GetImportedNamespaces() const
75{
[306]76 if( pParentClass )
77 {
78 return pParentClass->GetImportedNamespaces();
79 }
[206]80 return importedNamespaces;
81}
82bool UserProc::IsVirtual() const
83{
84 if( pMethod == NULL ){
85 return false;
86 }
87 return ( pMethod->IsVirtual() != 0 );
88}
[336]89const CMethod &UserProc::GetMethod() const
90{
91 if( !HasParentClass() )
92 {
93 Jenga::Throw( "グローバル関数に対してUserProc::GetMethodメソッドが呼ばれた" );
94 }
95 return *pMethod;
96}
[206]97
98bool UserProc::SetParamsAndReturnType( const char *sourceOfParams, int nowLine, bool isStatic ){
[184]99 int i = 0;
100 int i2,i3,sw;
101 char temporary[8192],temp2[VN_SIZE];
102
103 //ソースコードの位置
104 this->codePos = nowLine;
105
106 //パラメータ
107 if(sourceOfParams[i]!='('){
[465]108 compiler.errorMessenger.Output(1,NULL,nowLine);
[402]109 return false;
[184]110 }
[402]111 if(sourceOfParams[i + 1]!=')'&& this->pParentClass ){
[184]112 //クラスのメンバ関数の場合のみ、デストラクタにパラメータがある場合にエラーをだす
113 if(this->GetName()[0]=='~'){
[465]114 compiler.errorMessenger.Output(114,NULL,nowLine);
[402]115 return false;
[184]116 }
117 }
[400]118
[402]119 // カッコ内のパラメータ文字列を取得
120 char parametersStr1[8192];
121 char parametersStr2[8192] = "";
122 i += GetStringInPare( parametersStr1, sourceOfParams + i, true );
123 if( sourceOfParams[i] == '(' )
124 {
125 i += GetStringInPare( parametersStr2, sourceOfParams + i, true );
126 }
[400]127
[402]128 // 戻り値文字列を取得
129 char returnTypeStr[VN_SIZE] = "";
130 if( sourceOfParams[i] )
131 {
132 if( sourceOfParams[i] == 1 && sourceOfParams[i+1] == ESC_AS )
133 {
134 if( !this->IsFunction() ){
135 // Sub/Macroの場合
[465]136 compiler.errorMessenger.Output(38,this->GetName(),nowLine);
[402]137 }
[184]138
[402]139 lstrcpy( returnTypeStr, sourceOfParams + i + 2 );
[184]140 }
[402]141 else
142 {
[465]143 compiler.errorMessenger.Output(1,NULL,nowLine);
[402]144 return false;
[184]145 }
[402]146 }
[184]147
[402]148 // パラメータを分割
149 Jenga::Common::Strings parameters;
150 SplitParameter( parametersStr1, parameters );
151 BOOST_FOREACH( const std::string &paramStr, parameters )
152 {
153 int i = 0;
154
155 bool isRef = false;
156 if( paramStr[i] == 1 )
157 {
158 if( paramStr[i+1] == ESC_BYVAL )
159 {
160 isRef = false;
161 i += 2;
162 }
163 else if( paramStr[i+1] == ESC_BYREF )
164 {
165 isRef = true;
166 i += 2;
167 }
168 }
169
[184]170 //パラメータ名
171 bool isArray = false;
[206]172 Subscripts subscripts;
[184]173 char name[VN_SIZE];
174 sw=0;
175 for(i2=0;;i++,i2++){
[402]176 if(paramStr[i]=='('){
[184]177 if(!sw) sw=1;
178
[402]179 i3=GetStringInPare(name+i2,paramStr.c_str()+i);
[184]180 i2+=i3-1;
181 i+=i3-1;
182 continue;
183 }
[402]184 if(paramStr[i]=='['){
[184]185 if(!sw) sw=1;
186
[402]187 i3=GetStringInBracket(name+i2,paramStr.c_str()+i);
[184]188 i2+=i3-1;
189 i+=i3-1;
190 continue;
191 }
[402]192 if(!IsVariableChar(paramStr[i])){
[184]193 name[i2]=0;
194 break;
195 }
[402]196 name[i2]=paramStr[i];
[184]197 }
198 if(sw){
199 //配列パラメータ
[402]200 if( isRef == false )
201 {
[465]202 compiler.errorMessenger.Output(29,NULL,nowLine);
[402]203 }
[184]204 isArray = true;
205
206 if((name[i2-2]=='('&&name[i2-1]==')')||
[206]207 (name[i2-2]=='['&&name[i2-1]==']'))
208 {
209 subscripts.push_back( LONG_MAX );
[184]210
211 name[i2-2]=0;
212 }
213 else{
[206]214 GetArrange(name,temp2,subscripts);
[184]215 lstrcpy(name,temp2);
216 }
217
218 i2=lstrlen(name);
219 }
220
221 Type type( DEF_NON );
222 char initValue[8192] = "";
[402]223 if( paramStr[i] == '=' ){
[184]224 i++;
[402]225 i = GetOneParameter( paramStr.c_str(), i, initValue );
226 if( paramStr[i-1] == ',' )
[397]227 {
228 i--;
229 }
[184]230
231 // TODO: エラー用 fix me!!!
232 //cp = nowLine;
233
[193]234 NumOpe_GetType( initValue, GetStringTypeInfo(), type );
[311]235
236 if( IS_LITERAL(type.GetIndex()) )
237 {
238 type.SetIndex( -1 );
239 }
[184]240 }
[402]241 else if(paramStr[i]==1&&paramStr[i+1]==ESC_AS){
[184]242 // As指定
243 i+=2;
244
245 i2=0;
[438]246 lstrcpy( temporary, paramStr.c_str() + i );
[184]247
[198]248 compiler.StringToType( temporary, type );
[184]249
250 if( type.IsNull() ){
[465]251 compiler.errorMessenger.Output(3,temporary,nowLine);
[184]252 type.SetBasicType( DEF_PTR_VOID );
253 }
254
255 if( type.IsObject() ){
256 if( type.GetClass().IsBlittableType() ){
257 // Blittable型のときは基本型として扱う
258 type = type.GetClass().GetBlittableType();
259 }
260 }
261 }
262 else{
[411]263 type.SetBasicType( Type::GetBasicTypeFromSimpleName(name) );
[465]264 compiler.errorMessenger.Output(-103,name,nowLine);
[184]265 }
266
267 Parameter *pParam = new Parameter( name, type, isRef, initValue );
268 if( isArray ){
[206]269 pParam->SetArray( subscripts );
[184]270 }
271
272 //パラメータを追加
273 this->params.push_back( pParam );
[402]274 }
[184]275
276 this->secondParmNum = (int)this->params.size();
277
[402]278 SplitParameter( parametersStr2, parameters );
279 BOOST_FOREACH( const std::string &paramStr, parameters )
280 {
281 int i = 0;
282
283 bool isRef = false;
284 if( paramStr[i] == 1 )
285 {
286 if( paramStr[i+1] == ESC_BYVAL )
287 {
288 isRef = true;
289 i += 2;
290 }
291 else if( paramStr[i+1] == ESC_BYREF )
292 {
[184]293 isRef = false;
[402]294 i += 2;
[184]295 }
[402]296 }
297
298 //パラメータ名
299 bool isArray = false;
300 Subscripts subscripts;
301 char name[VN_SIZE];
302 sw=0;
303 for(i2=0;;i++,i2++){
304 if(paramStr[i]=='('){
305 if(!sw) sw=1;
306
307 i3=GetStringInPare(name+i2,paramStr.c_str()+i);
308 i2+=i3-1;
309 i+=i3-1;
310 continue;
[184]311 }
[402]312 if(paramStr[i]=='['){
313 if(!sw) sw=1;
[184]314
[402]315 i3=GetStringInBracket(name+i2,paramStr.c_str()+i);
316 i2+=i3-1;
317 i+=i3-1;
318 continue;
319 }
320 if(!IsVariableChar(paramStr[i])){
321 name[i2]=0;
322 break;
323 }
324 name[i2]=paramStr[i];
325 }
326 if(sw){
327 //配列パラメータ
[465]328 if( isRef == false ) compiler.errorMessenger.Output(29,NULL,nowLine);
[402]329 isArray = true;
[184]330
[402]331 if((name[i2-2]=='('&&name[i2-1]==')')||
332 (name[i2-2]=='['&&name[i2-1]==']'))
333 {
334 subscripts.push_back( LONG_MAX );
[184]335
[402]336 name[i2-2]=0;
[184]337 }
[402]338 else{
339 GetArrange(name,temp2,subscripts);
340 lstrcpy(name,temp2);
341 }
[184]342
[402]343 i2=lstrlen(name);
344 }
[184]345
[402]346 Type type( DEF_NON );
347 char initValue[8192] = "";
348 if( paramStr[i] == '=' ){
349 i++;
350 i = GetOneParameter( paramStr.c_str(), i, initValue );
351 if( paramStr[i-1] == ',' )
352 {
353 i--;
354 }
[184]355
[402]356 // TODO: エラー用 fix me!!!
357 //cp = nowLine;
358
359 NumOpe_GetType( initValue, GetStringTypeInfo(), type );
360
361 if( IS_LITERAL(type.GetIndex()) )
362 {
363 type.SetIndex( -1 );
[184]364 }
[402]365 }
366 else if(paramStr[i]==1&&paramStr[i+1]==ESC_AS){
367 // As指定
368 i+=2;
[184]369
[402]370 i2=0;
371 while(paramStr[i]=='*'){
372 temporary[i2]=paramStr[i];
373 i++;
374 i2++;
375 }
376 for(;;i++,i2++){
377 if(!IsVariableChar(paramStr[i])){
378 if(paramStr[i]==1&&(paramStr[i+1]==ESC_FUNCTION||paramStr[i+1]==ESC_SUB)){
379 temporary[i2++]=paramStr[i++];
380 temporary[i2]=paramStr[i];
381 continue;
[184]382 }
[402]383 temporary[i2]=0;
384 break;
[184]385 }
[402]386 temporary[i2]=paramStr[i];
387 }
[184]388
[402]389 compiler.StringToType( temporary, type );
[184]390
[402]391 if( type.IsNull() ){
[465]392 compiler.errorMessenger.Output(3,temporary,nowLine);
[402]393 type.SetBasicType( DEF_PTR_VOID );
[184]394 }
395
[402]396 if( type.IsObject() ){
397 if( type.GetClass().IsBlittableType() ){
398 // Blittable型のときは基本型として扱う
399 type = type.GetClass().GetBlittableType();
400 }
[184]401 }
[402]402 }
403 else{
404 type.SetBasicType( Type::GetBasicTypeFromSimpleName(temporary) );
[465]405 compiler.errorMessenger.Output(-103,temporary,nowLine);
[402]406 }
[184]407
[402]408 Parameter *pParam = new Parameter( name, type, isRef, initValue );
409 if( isArray ){
410 pParam->SetArray( subscripts );
411 }
[184]412
[402]413 //パラメータを追加
414 this->params.push_back( pParam );
[184]415 }
416
[402]417 if(returnTypeStr[0]){
[184]418 ///////////////////
419 // 戻り値を取得
420 ///////////////////
421
422 if( !this->IsFunction() ){
423 // Sub/Macroの場合
[465]424 compiler.errorMessenger.Output(38,this->GetName(),nowLine);
[184]425 }
426
427 if( this->pParentClass ){
428 if( this->GetName() == this->pParentClass->GetName() ||
429 this->GetName()[0]=='~'){
430 //クラスのコンストラクタ、デストラクタがFunction定義の場合はエラーをだす
[465]431 compiler.errorMessenger.Output(115,NULL,nowLine);
[184]432 }
433 }
434
[402]435 compiler.StringToType( returnTypeStr, this->returnType );
436 if( this->returnType.IsNull() )
437 {
[465]438 compiler.errorMessenger.Output(3,returnTypeStr,nowLine);
[184]439 }
[402]440 }
441 else{
442 if( this->IsFunction() )
443 {
444 // Function定義なのに、戻り値の型がセットされていない
[465]445 compiler.errorMessenger.Output(-104,this->GetName().c_str(),nowLine);
[184]446
447 this->returnType.SetBasicType( DEF_DOUBLE );
448 }
[402]449 else
450 {
451 //戻り値なしのSub定義
452 this->returnType.SetNull();
453 }
[184]454 }
455
456 //リアルパラメータ領域を取得(_System_LocalThisを考慮して2つだけ多く確保する場合がある)
457
458 if( this->pParentClass && isStatic == false ){
459 //オブジェクトメンバの場合は、第一パラメータを_System_LocalThis引き渡し用として利用
[523]460 std::string name = "_System_LocalThis";
[184]461 Type type( DEF_PTR_VOID );
462 this->realParams.push_back( new Parameter( name, type ) );
463 }
464
465 if( this->returnType.IsStruct() ){
466 //構造体を戻り値として持つ場合
467 //※第一パラメータ(Thisポインタありの場合は第二パラメータ)を戻り値用の参照宣言にする
468
[523]469 std::string name = this->GetName();
[184]470 if(name[0]==1&&name[1]==ESC_OPERATOR){
471 name="_System_ReturnValue";
472 }
473 Type type( DEF_STRUCT, this->returnType.GetIndex() );
474 this->realParams.push_back( new Parameter( name, type, true ) );
475 }
476
477 //パラメータをコピー
478 BOOST_FOREACH( Parameter *pParam, params ){
479 this->realParams.push_back( new Parameter( *pParam ) );
480 }
481
482 return true;
483}
484
[206]485const UserProc *UserProc::pCompilingUserProc = NULL;
[364]486const UserProc *UserProc::pGlobalProc = NULL;
[206]487
488
489bool UserProcs::Insert( UserProc *pUserProc, int nowLine )
[184]490{
[206]491 /////////////////////////////////
492 // ハッシュデータに追加
493 /////////////////////////////////
494
495 if( !Put( pUserProc ) )
496 {
497 // 重複しているため、失敗
[465]498 compiler.errorMessenger.Output(15,pUserProc->GetName().c_str(),nowLine);
[206]499 return false;
[184]500 }
[206]501
502 return true;
[184]503}
[206]504
505void UserProcs::EnumGlobalProcs( const char *simpleName, const char *localName, std::vector<const UserProc *> &subs )
[184]506{
[206]507 ///////////////////////////
508 // グローバル関数を検索
509 ///////////////////////////
[184]510
[206]511 // ハッシュ値を取得
512 UserProc *pUserProc = GetHashArrayElement( simpleName );
513 while(pUserProc){
[208]514 if( pUserProc->IsGlobalProcedure() ){
[509]515 if( pUserProc->IsEqualSymbol( LexicalAnalyzer::FullNameToSymbol( localName ) ) ){
[206]516 subs.push_back( pUserProc );
517 }
518 }
519
520 pUserProc=pUserProc->GetChainNext();
521 }
[184]522}
523
[206]524bool DllProc::SetParamsAndReturnType( const char *sourceOfParams, int nowLine ){
[184]525 int i = 0;
526 int i2,i3,sw;
527 char temporary[8192],temp2[VN_SIZE];
528
529 //ソースコードの位置
530 this->codePos = nowLine;
531
532 //パラメータ
533 if(sourceOfParams[i]!='('){
[465]534 compiler.errorMessenger.Output(1,NULL,nowLine);
[184]535 return 0;
536 }
537 i++;
538
539 while(1){
540 if(sourceOfParams[i]==')') break;
541
542 //ByRef
543 bool isRef;
544 if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYVAL){
545 isRef = false;
546 i+=2;
547 }
548 else if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYREF){
549 isRef = true;
550 i+=2;
551 }
552 else isRef = false;
553
554 //パラメータ名
555 bool isArray = false;
[206]556 Subscripts subscripts;
[184]557 char name[VN_SIZE];
558 sw=0;
559 for(i2=0;;i++,i2++){
560 if(sourceOfParams[i]=='('){
561 if(!sw) sw=1;
562
563 i3=GetStringInPare(name+i2,sourceOfParams+i);
564 i2+=i3-1;
565 i+=i3-1;
566 continue;
567 }
568 if(sourceOfParams[i]=='['){
569 if(!sw) sw=1;
570
571 i3=GetStringInBracket(name+i2,sourceOfParams+i);
572 i2+=i3-1;
573 i+=i3-1;
574 continue;
575 }
576 if(!IsVariableChar(sourceOfParams[i])){
577 name[i2]=0;
578 break;
579 }
580 name[i2]=sourceOfParams[i];
581 }
582 if(sw){
583 //配列パラメータ
[465]584 if( isRef == false ) compiler.errorMessenger.Output(29,NULL,nowLine);
[184]585 isArray = true;
586
587 if((name[i2-2]=='('&&name[i2-1]==')')||
[206]588 (name[i2-2]=='['&&name[i2-1]==']'))
589 {
590 subscripts.push_back( LONG_MAX );
[184]591
592 name[i2-2]=0;
593 }
594 else{
[206]595 GetArrange(name,temp2,subscripts);
[184]596 lstrcpy(name,temp2);
597 }
598
599 i2=lstrlen(name);
600 }
601
602 //型
603 Type type( DEF_NON );
604 if(lstrcmp(name,"...")==0) type.SetBasicType( DEF_ELLIPSE );
605 else if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_AS){
606 i+=2;
607
608 i2=0;
609 while(sourceOfParams[i]=='*'){
610 temporary[i2]=sourceOfParams[i];
611 i++;
612 i2++;
613 }
614 for(;;i++,i2++){
615 if(!IsVariableChar(sourceOfParams[i])){
616 if(sourceOfParams[i]==1&&(sourceOfParams[i+1]==ESC_FUNCTION||sourceOfParams[i+1]==ESC_SUB)){
617 temporary[i2++]=sourceOfParams[i++];
618 temporary[i2]=sourceOfParams[i];
619 continue;
620 }
621 temporary[i2]=0;
622 break;
623 }
624 temporary[i2]=sourceOfParams[i];
625 }
626
[198]627 compiler.StringToType( temporary, type );
[184]628
629 if( type.IsNull() ){
[465]630 compiler.errorMessenger.Output(3,temporary,nowLine);
[184]631 type.SetBasicType( DEF_PTR_VOID );
632 }
633 }
634 else{
635 type.SetBasicType( Type::GetBasicTypeFromSimpleName(temporary) );
[465]636 compiler.errorMessenger.Output(-103,temporary,nowLine);
[184]637 }
638
639 Parameter *pParam = new Parameter( name, type, isRef );
640 if( isArray ){
[206]641 pParam->SetArray( subscripts );
[184]642 }
643
644 //パラメータを追加
645 this->params.push_back( pParam );
646
647 if(sourceOfParams[i]==','){
648 i++;
649 continue;
650 }
651 else if(sourceOfParams[i]==')') continue;
652 else{
[465]653 compiler.errorMessenger.Output(1,NULL,nowLine);
[184]654 break;
655 }
656 }
657 i++;
658
659 if(sourceOfParams[i]){
660 ///////////////////
661 // 戻り値を取得
662 ///////////////////
663
664 i2=lstrlen(sourceOfParams)-2;
665
666 int sw_as=0;
667 for(;i2>0;i2--){
668 if(sourceOfParams[i2]==')') break;
669
670 if(sourceOfParams[i2]==1&&sourceOfParams[i2+1]==ESC_AS){
671 i2+=2;
672 i3=0;
673 while(sourceOfParams[i2]=='*') temporary[i3++]=sourceOfParams[i2++];
674 for(;;i2++,i3++){
675 if(!IsVariableChar(sourceOfParams[i2])){
676 temporary[i3]=0;
677 break;
678 }
679 temporary[i3]=sourceOfParams[i2];
680 }
[198]681 compiler.StringToType( temporary, this->returnType );
[465]682 if( this->returnType.IsNull() ) compiler.errorMessenger.Output(3,temporary,nowLine);
[184]683
684 sw_as=1;
685 break;
686 }
687 }
688 }
689 else{
690 //戻り値なしのSub定義
691 this->returnType.SetNull();
692 }
693
694 return true;
695}
696
[209]697void DllProcs::Add(const NamespaceScopes &namespaceScopes, char *buffer,int nowLine){
698 int i2;
699
700 int i=0;
701
702 //Sub/Function
703 Procedure::Kind kind = Procedure::Sub;
704 if(buffer[i]==ESC_SUB){
705 }
706 else if(buffer[i]==ESC_FUNCTION){
707 kind = Procedure::Function;
708 }
709 else{
[465]710 compiler.errorMessenger.Output(1,NULL,nowLine);
[209]711 return;
712 }
713 i++;
714
715 //プロシージャ名
716 char procName[VN_SIZE];
717 bool isCdecl = false;
718 for(i2=0;;i++,i2++){
719 if(buffer[i]==1&&buffer[i+1]==ESC_CDECL){
720 isCdecl = true;
721
722 i+=2;
723 procName[i2]=0;
724 break;
725 }
726 if(buffer[i]==','){
727 procName[i2]=0;
728 break;
729 }
730 if(buffer[i]=='\0'){
[465]731 compiler.errorMessenger.Output(1,NULL,nowLine);
[209]732 return;
733 }
734 procName[i2]=buffer[i];
735 }
736 i++;
737
738 //ユーザー定義関数との重複チェック
739 if(GetSubHash(procName)){
[465]740 compiler.errorMessenger.Output(15,procName,nowLine);
[209]741 return;
742 }
743
744
745 //ライブラリ
746 char dllFileName[MAX_PATH];
747 i = GetOneParameter( buffer, i, dllFileName );
748 Type resultType;
749 _int64 i64data;
750 if( !StaticCalculation( true, dllFileName, 0, &i64data, resultType ) ){
751 return;
752 }
753 if( resultType.GetBasicType() != typeOfPtrChar ){
[465]754 compiler.errorMessenger.Output(1,NULL,nowLine);
[209]755 return;
756 }
757 lstrcpy( dllFileName, (char *)i64data );
758 CharUpper(dllFileName);
759 if(!strstr(dllFileName,".")){
760 lstrcat(dllFileName,".DLL");
761 if(lstrlen(dllFileName)>=16){
[465]762 compiler.errorMessenger.Output(7,NULL,nowLine);
[209]763 return;
764 }
765 }
766
767 //エイリアス
768 char alias[VN_SIZE];
769 i = GetOneParameter( buffer, i, alias );
770 if( alias[0] ){
771 if( !StaticCalculation( true, alias, 0, &i64data, resultType ) ){
772 return;
773 }
774 if( resultType.GetBasicType() != typeOfPtrChar ){
[465]775 compiler.errorMessenger.Output(1,NULL,nowLine);
[209]776 return;
777 }
778 lstrcpy( alias, (char *)i64data );
779 }
780 else{
781 //省略されたときは関数名
782 lstrcpy( alias, procName );
783 }
784
785
786 // オブジェクトを生成
787 DllProc *pDllProc = new DllProc( namespaceScopes, procName, kind, isCdecl, dllFileName, alias );
788
789 // パラメータを解析
790 // ※第1パラメータにに指定するデータの例:"( s As String ) As String"
791 pDllProc->SetParamsAndReturnType( buffer + i, nowLine );
792
793 // パラメータのエラーチェック
794 BOOST_FOREACH( const Parameter *pParam, pDllProc->Params() ){
795 if( pParam->IsObject() ){
[465]796 compiler.errorMessenger.Output(25,pParam->GetVarName(),nowLine);
[209]797 }
798 if( !pParam->IsRef() ){
799 if( pParam->IsStruct() ){
[465]800 compiler.errorMessenger.Output(28,pParam->GetVarName(),nowLine);
[209]801 }
802 }
803 }
804
805 //戻り値のエラーチェック
806 if( pDllProc->IsFunction() ){
807 // Function定義
808
809 if( pDllProc->ReturnType().IsObject() ){
810 // DLL関数ではオブジェクトを戻り値にできない
[465]811 compiler.errorMessenger.Output(40,pDllProc->GetName(),nowLine);
[209]812 }
813 }
814
815 // ハッシュマップに追加
816 this->Put( pDllProc );
817}
818
[206]819bool ProcPointer::SetParamsAndReturnType( const char *sourceOfParams, int nowLine ){
[184]820 int i = 0;
821 int i2,i3,sw;
822 char temporary[8192],temp2[VN_SIZE];
823
824 //ソースコードの位置
825 this->codePos = nowLine;
826
827 //パラメータ
828 if(sourceOfParams[i]!='('){
[465]829 compiler.errorMessenger.Output(1,NULL,nowLine);
[184]830 return 0;
831 }
832 i++;
833 while(1){
834 if(sourceOfParams[i]==')') break;
835
836 //ByRef
837 bool isRef;
838 if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYVAL){
839 isRef = false;
840 i+=2;
841 }
842 else if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYREF){
843 isRef = true;
844 i+=2;
845 }
846 else isRef = false;
847
848 //パラメータ名
849 bool isArray = false;
[206]850 Subscripts subscripts;
[184]851 char name[VN_SIZE];
852 sw=0;
853 for(i2=0;;i++,i2++){
854 if(sourceOfParams[i]=='('){
855 if(!sw) sw=1;
856
857 i3=GetStringInPare(name+i2,sourceOfParams+i);
858 i2+=i3-1;
859 i+=i3-1;
860 continue;
861 }
862 if(sourceOfParams[i]=='['){
863 if(!sw) sw=1;
864
865 i3=GetStringInBracket(name+i2,sourceOfParams+i);
866 i2+=i3-1;
867 i+=i3-1;
868 continue;
869 }
870 if(!IsVariableChar(sourceOfParams[i])){
871 name[i2]=0;
872 break;
873 }
874 name[i2]=sourceOfParams[i];
875 }
876 if(sw){
877 //配列パラメータ
[465]878 if( isRef == false ) compiler.errorMessenger.Output(29,NULL,nowLine);
[184]879 isArray = true;
880
881 if((name[i2-2]=='('&&name[i2-1]==')')||
[206]882 (name[i2-2]=='['&&name[i2-1]==']'))
883 {
884 subscripts.push_back( LONG_MAX );
[184]885
886 name[i2-2]=0;
887 }
888 else{
[206]889 GetArrange(name,temp2,subscripts);
[184]890 lstrcpy(name,temp2);
891 }
892
893 i2=lstrlen(name);
894 }
895
896 //型
897 Type type( DEF_NON );
898 if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_AS){
899 i+=2;
900
901 i2=0;
902 while(sourceOfParams[i]=='*'){
903 temporary[i2]=sourceOfParams[i];
904 i++;
905 i2++;
906 }
907 for(;;i++,i2++){
908 if(!IsVariableChar(sourceOfParams[i])){
909 if(sourceOfParams[i]==1&&(sourceOfParams[i+1]==ESC_FUNCTION||sourceOfParams[i+1]==ESC_SUB)){
910 temporary[i2++]=sourceOfParams[i++];
911 temporary[i2]=sourceOfParams[i];
912 continue;
913 }
914 temporary[i2]=0;
915 break;
916 }
917 temporary[i2]=sourceOfParams[i];
918 }
919
[198]920 compiler.StringToType( temporary, type );
[184]921
922 if( type.IsNull() ){
[465]923 compiler.errorMessenger.Output(3,temporary,nowLine);
[184]924 type.SetBasicType( DEF_PTR_VOID );
925 }
926 }
927 else{
928 type.SetBasicType( Type::GetBasicTypeFromSimpleName(temporary) );
[465]929 compiler.errorMessenger.Output(-103,temporary,nowLine);
[184]930 }
931
932 Parameter *pParam = new Parameter( name, type, isRef );
933 if( isArray ){
[206]934 pParam->SetArray( subscripts );
[184]935 }
936
937 //パラメータを追加
938 this->params.push_back( pParam );
939
940 if(sourceOfParams[i]==','){
941 i++;
942 continue;
943 }
944 else if(sourceOfParams[i]==')') continue;
945 else{
[465]946 compiler.errorMessenger.Output(1,NULL,nowLine);
[184]947 break;
948 }
949 }
950 i++;
951
952 if(sourceOfParams[i]){
953 ///////////////////
954 // 戻り値を取得
955 ///////////////////
956
957 i2=lstrlen(sourceOfParams)-2;
958
959 int sw_as=0;
960 for(;i2>0;i2--){
961 if(sourceOfParams[i2]==')') break;
962
963 if(sourceOfParams[i2]==1&&sourceOfParams[i2+1]==ESC_AS){
964 i2+=2;
965 i3=0;
966 while(sourceOfParams[i2]=='*') temporary[i3++]=sourceOfParams[i2++];
967 for(;;i2++,i3++){
968 if(!IsVariableChar(sourceOfParams[i2])){
969 temporary[i3]=0;
970 break;
971 }
972 temporary[i3]=sourceOfParams[i2];
973 }
[198]974 compiler.StringToType( temporary, this->returnType );
[465]975 if( this->returnType.IsNull() ) compiler.errorMessenger.Output(3,temporary,nowLine);
[184]976
977 sw_as=1;
978 break;
979 }
980 }
981 }
982 else{
983 //戻り値なしのSub定義
984 this->returnType.SetNull();
985 }
986
987 //戻り値のエラーチェック
988 if( IsFunction() ){
989 // Function定義
990
991 if( this->ReturnType().IsNull() ){
992 // 戻り値がない
[465]993 compiler.errorMessenger.Output(26,this->GetName(),nowLine);
[184]994 }
995 }
996 else{
997 if( !this->ReturnType().IsNull() ){
998 // Sub定義なのに、戻り値がある
[465]999 compiler.errorMessenger.Output(38,this->GetName(),nowLine);
[184]1000 }
1001 }
1002
1003 return true;
1004}
1005
[523]1006int ProcPointers::Add( const std::string &typeExpression )
[184]1007{
1008 DWORD dwProcType = (DWORD)typeExpression[2];
[523]1009 const std::string &paramStr = typeExpression.substr( 3 );
[184]1010
1011 Procedure::Kind kind = Procedure::Sub;
1012 if( dwProcType == ESC_FUNCTION ){
1013 kind = Procedure::Function;
1014 }
1015
[206]1016 ProcPointer *pProcPointer = new ProcPointer( kind );
[184]1017
1018 //buffer[0]は'('となっている
1019 extern int cp;
1020 pProcPointer->SetParamsAndReturnType( paramStr.c_str(), cp );
1021
1022 this->push_back( pProcPointer );
1023
1024 return (int)this->size()-1;
1025}
1026
[206]1027void ProcPointers::Clear()
[184]1028{
[206]1029 ProcPointers &procPointers = *this;
[184]1030 BOOST_FOREACH( ProcPointer *pProcPointer, procPointers ){
1031 delete pProcPointer;
1032 }
1033 this->clear();
1034}
Note: See TracBrowser for help on using the repository browser.