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

Last change on this file since 514 was 511, checked in by dai_9181, 17 years ago

幾つかの構文解析系の処理をLexicalAnalyzerに実装し直した

File size: 22.7 KB
Line 
1#include "stdafx.h"
2
3#include <Compiler.h>
4#include <Procedure.h>
5
6#include "../common.h"
7#ifdef _AMD64_
8#include "../../compiler_x64/opcode.h"
9#else
10#include "../../compiler_x86/opcode.h"
11#endif
12
13using namespace ActiveBasic::Compiler;
14
15
16bool UserProc::IsEqualForOverride( const Types &actualTypeParametersForThisProc, const UserProc *pUserProc ) const
17{
18 if( this->GetName() == pUserProc->GetName() // 名前空間及び名前が等しい
19 && this->Params().Equals( actualTypeParametersForThisProc, pUserProc->Params() ) ) // パラメータが等しい
20 {
21 if( this->returnType.Equals( pUserProc->returnType ) )
22 {
23 // 戻り値が等しい
24 return true;
25 }
26 else if( this->returnType.IsCovariant( pUserProc->returnType ) )
27 {
28 // 戻り値が共変
29 return true;
30 }
31 else if( this->returnType.IsTypeParameter() )
32 {
33 // 型パラメータだったとき
34
35 if( actualTypeParametersForThisProc[this->returnType.GetFormalTypeIndex()].Equals( pUserProc->returnType ) )
36 {
37 // 戻り値が等しい
38 return true;
39 }
40 else if( actualTypeParametersForThisProc[this->returnType.GetFormalTypeIndex()].IsCovariant( pUserProc->returnType ) )
41 {
42 // 戻り値が共変
43 return true;
44 }
45 }
46 }
47 return false;
48}
49
50
51std::string UserProc::GetFullName() const
52{
53 if( HasParentClass() ){
54 return GetParentClass().GetName() + "." + GetName();
55 }
56
57 return GetName();
58}
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}
67const NamespaceScopes &UserProc::GetNamespaceScopes() const
68{
69 if( HasParentClass() ){
70 return GetParentClassPtr()->GetNamespaceScopes();
71 }
72 return Symbol::GetNamespaceScopes();
73}
74const NamespaceScopesCollection &UserProc::GetImportedNamespaces() const
75{
76 if( pParentClass )
77 {
78 return pParentClass->GetImportedNamespaces();
79 }
80 return importedNamespaces;
81}
82bool UserProc::IsVirtual() const
83{
84 if( pMethod == NULL ){
85 return false;
86 }
87 return ( pMethod->IsVirtual() != 0 );
88}
89const CMethod &UserProc::GetMethod() const
90{
91 if( !HasParentClass() )
92 {
93 Jenga::Throw( "グローバル関数に対してUserProc::GetMethodメソッドが呼ばれた" );
94 }
95 return *pMethod;
96}
97
98bool UserProc::SetParamsAndReturnType( const char *sourceOfParams, int nowLine, bool isStatic ){
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]!='('){
108 compiler.errorMessenger.Output(1,NULL,nowLine);
109 return false;
110 }
111 if(sourceOfParams[i + 1]!=')'&& this->pParentClass ){
112 //クラスのメンバ関数の場合のみ、デストラクタにパラメータがある場合にエラーをだす
113 if(this->GetName()[0]=='~'){
114 compiler.errorMessenger.Output(114,NULL,nowLine);
115 return false;
116 }
117 }
118
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 }
127
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の場合
136 compiler.errorMessenger.Output(38,this->GetName(),nowLine);
137 }
138
139 lstrcpy( returnTypeStr, sourceOfParams + i + 2 );
140 }
141 else
142 {
143 compiler.errorMessenger.Output(1,NULL,nowLine);
144 return false;
145 }
146 }
147
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
170 //パラメータ名
171 bool isArray = false;
172 Subscripts subscripts;
173 char name[VN_SIZE];
174 sw=0;
175 for(i2=0;;i++,i2++){
176 if(paramStr[i]=='('){
177 if(!sw) sw=1;
178
179 i3=GetStringInPare(name+i2,paramStr.c_str()+i);
180 i2+=i3-1;
181 i+=i3-1;
182 continue;
183 }
184 if(paramStr[i]=='['){
185 if(!sw) sw=1;
186
187 i3=GetStringInBracket(name+i2,paramStr.c_str()+i);
188 i2+=i3-1;
189 i+=i3-1;
190 continue;
191 }
192 if(!IsVariableChar(paramStr[i])){
193 name[i2]=0;
194 break;
195 }
196 name[i2]=paramStr[i];
197 }
198 if(sw){
199 //配列パラメータ
200 if( isRef == false )
201 {
202 compiler.errorMessenger.Output(29,NULL,nowLine);
203 }
204 isArray = true;
205
206 if((name[i2-2]=='('&&name[i2-1]==')')||
207 (name[i2-2]=='['&&name[i2-1]==']'))
208 {
209 subscripts.push_back( LONG_MAX );
210
211 name[i2-2]=0;
212 }
213 else{
214 GetArrange(name,temp2,subscripts);
215 lstrcpy(name,temp2);
216 }
217
218 i2=lstrlen(name);
219 }
220
221 Type type( DEF_NON );
222 char initValue[8192] = "";
223 if( paramStr[i] == '=' ){
224 i++;
225 i = GetOneParameter( paramStr.c_str(), i, initValue );
226 if( paramStr[i-1] == ',' )
227 {
228 i--;
229 }
230
231 // TODO: エラー用 fix me!!!
232 //cp = nowLine;
233
234 NumOpe_GetType( initValue, GetStringTypeInfo(), type );
235
236 if( IS_LITERAL(type.GetIndex()) )
237 {
238 type.SetIndex( -1 );
239 }
240 }
241 else if(paramStr[i]==1&&paramStr[i+1]==ESC_AS){
242 // As指定
243 i+=2;
244
245 i2=0;
246 lstrcpy( temporary, paramStr.c_str() + i );
247
248 compiler.StringToType( temporary, type );
249
250 if( type.IsNull() ){
251 compiler.errorMessenger.Output(3,temporary,nowLine);
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{
263 type.SetBasicType( Type::GetBasicTypeFromSimpleName(name) );
264 compiler.errorMessenger.Output(-103,name,nowLine);
265 }
266
267 Parameter *pParam = new Parameter( name, type, isRef, initValue );
268 if( isArray ){
269 pParam->SetArray( subscripts );
270 }
271
272 //パラメータを追加
273 this->params.push_back( pParam );
274 }
275
276 this->secondParmNum = (int)this->params.size();
277
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 {
293 isRef = false;
294 i += 2;
295 }
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;
311 }
312 if(paramStr[i]=='['){
313 if(!sw) sw=1;
314
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 //配列パラメータ
328 if( isRef == false ) compiler.errorMessenger.Output(29,NULL,nowLine);
329 isArray = true;
330
331 if((name[i2-2]=='('&&name[i2-1]==')')||
332 (name[i2-2]=='['&&name[i2-1]==']'))
333 {
334 subscripts.push_back( LONG_MAX );
335
336 name[i2-2]=0;
337 }
338 else{
339 GetArrange(name,temp2,subscripts);
340 lstrcpy(name,temp2);
341 }
342
343 i2=lstrlen(name);
344 }
345
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 }
355
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 );
364 }
365 }
366 else if(paramStr[i]==1&&paramStr[i+1]==ESC_AS){
367 // As指定
368 i+=2;
369
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;
382 }
383 temporary[i2]=0;
384 break;
385 }
386 temporary[i2]=paramStr[i];
387 }
388
389 compiler.StringToType( temporary, type );
390
391 if( type.IsNull() ){
392 compiler.errorMessenger.Output(3,temporary,nowLine);
393 type.SetBasicType( DEF_PTR_VOID );
394 }
395
396 if( type.IsObject() ){
397 if( type.GetClass().IsBlittableType() ){
398 // Blittable型のときは基本型として扱う
399 type = type.GetClass().GetBlittableType();
400 }
401 }
402 }
403 else{
404 type.SetBasicType( Type::GetBasicTypeFromSimpleName(temporary) );
405 compiler.errorMessenger.Output(-103,temporary,nowLine);
406 }
407
408 Parameter *pParam = new Parameter( name, type, isRef, initValue );
409 if( isArray ){
410 pParam->SetArray( subscripts );
411 }
412
413 //パラメータを追加
414 this->params.push_back( pParam );
415 }
416
417 if(returnTypeStr[0]){
418 ///////////////////
419 // 戻り値を取得
420 ///////////////////
421
422 if( !this->IsFunction() ){
423 // Sub/Macroの場合
424 compiler.errorMessenger.Output(38,this->GetName(),nowLine);
425 }
426
427 if( this->pParentClass ){
428 if( this->GetName() == this->pParentClass->GetName() ||
429 this->GetName()[0]=='~'){
430 //クラスのコンストラクタ、デストラクタがFunction定義の場合はエラーをだす
431 compiler.errorMessenger.Output(115,NULL,nowLine);
432 }
433 }
434
435 compiler.StringToType( returnTypeStr, this->returnType );
436 if( this->returnType.IsNull() )
437 {
438 compiler.errorMessenger.Output(3,returnTypeStr,nowLine);
439 }
440 }
441 else{
442 if( this->IsFunction() )
443 {
444 // Function定義なのに、戻り値の型がセットされていない
445 compiler.errorMessenger.Output(-104,this->GetName().c_str(),nowLine);
446
447 this->returnType.SetBasicType( DEF_DOUBLE );
448 }
449 else
450 {
451 //戻り値なしのSub定義
452 this->returnType.SetNull();
453 }
454 }
455
456 //リアルパラメータ領域を取得(_System_LocalThisを考慮して2つだけ多く確保する場合がある)
457
458 if( this->pParentClass && isStatic == false ){
459 //オブジェクトメンバの場合は、第一パラメータを_System_LocalThis引き渡し用として利用
460 string name = "_System_LocalThis";
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
469 string name = this->GetName();
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
485const UserProc *UserProc::pCompilingUserProc = NULL;
486const UserProc *UserProc::pGlobalProc = NULL;
487
488
489bool UserProcs::Insert( UserProc *pUserProc, int nowLine )
490{
491 /////////////////////////////////
492 // ハッシュデータに追加
493 /////////////////////////////////
494
495 if( !Put( pUserProc ) )
496 {
497 // 重複しているため、失敗
498 compiler.errorMessenger.Output(15,pUserProc->GetName().c_str(),nowLine);
499 return false;
500 }
501
502 return true;
503}
504
505void UserProcs::EnumGlobalProcs( const char *simpleName, const char *localName, std::vector<const UserProc *> &subs )
506{
507 ///////////////////////////
508 // グローバル関数を検索
509 ///////////////////////////
510
511 // ハッシュ値を取得
512 UserProc *pUserProc = GetHashArrayElement( simpleName );
513 while(pUserProc){
514 if( pUserProc->IsGlobalProcedure() ){
515 if( pUserProc->IsEqualSymbol( LexicalAnalyzer::FullNameToSymbol( localName ) ) ){
516 subs.push_back( pUserProc );
517 }
518 }
519
520 pUserProc=pUserProc->GetChainNext();
521 }
522}
523
524bool DllProc::SetParamsAndReturnType( const char *sourceOfParams, int nowLine ){
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]!='('){
534 compiler.errorMessenger.Output(1,NULL,nowLine);
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;
556 Subscripts subscripts;
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 //配列パラメータ
584 if( isRef == false ) compiler.errorMessenger.Output(29,NULL,nowLine);
585 isArray = true;
586
587 if((name[i2-2]=='('&&name[i2-1]==')')||
588 (name[i2-2]=='['&&name[i2-1]==']'))
589 {
590 subscripts.push_back( LONG_MAX );
591
592 name[i2-2]=0;
593 }
594 else{
595 GetArrange(name,temp2,subscripts);
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
627 compiler.StringToType( temporary, type );
628
629 if( type.IsNull() ){
630 compiler.errorMessenger.Output(3,temporary,nowLine);
631 type.SetBasicType( DEF_PTR_VOID );
632 }
633 }
634 else{
635 type.SetBasicType( Type::GetBasicTypeFromSimpleName(temporary) );
636 compiler.errorMessenger.Output(-103,temporary,nowLine);
637 }
638
639 Parameter *pParam = new Parameter( name, type, isRef );
640 if( isArray ){
641 pParam->SetArray( subscripts );
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{
653 compiler.errorMessenger.Output(1,NULL,nowLine);
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 }
681 compiler.StringToType( temporary, this->returnType );
682 if( this->returnType.IsNull() ) compiler.errorMessenger.Output(3,temporary,nowLine);
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
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{
710 compiler.errorMessenger.Output(1,NULL,nowLine);
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'){
731 compiler.errorMessenger.Output(1,NULL,nowLine);
732 return;
733 }
734 procName[i2]=buffer[i];
735 }
736 i++;
737
738 //ユーザー定義関数との重複チェック
739 if(GetSubHash(procName)){
740 compiler.errorMessenger.Output(15,procName,nowLine);
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 ){
754 compiler.errorMessenger.Output(1,NULL,nowLine);
755 return;
756 }
757 lstrcpy( dllFileName, (char *)i64data );
758 CharUpper(dllFileName);
759 if(!strstr(dllFileName,".")){
760 lstrcat(dllFileName,".DLL");
761 if(lstrlen(dllFileName)>=16){
762 compiler.errorMessenger.Output(7,NULL,nowLine);
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 ){
775 compiler.errorMessenger.Output(1,NULL,nowLine);
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() ){
796 compiler.errorMessenger.Output(25,pParam->GetVarName(),nowLine);
797 }
798 if( !pParam->IsRef() ){
799 if( pParam->IsStruct() ){
800 compiler.errorMessenger.Output(28,pParam->GetVarName(),nowLine);
801 }
802 }
803 }
804
805 //戻り値のエラーチェック
806 if( pDllProc->IsFunction() ){
807 // Function定義
808
809 if( pDllProc->ReturnType().IsObject() ){
810 // DLL関数ではオブジェクトを戻り値にできない
811 compiler.errorMessenger.Output(40,pDllProc->GetName(),nowLine);
812 }
813 }
814
815 // ハッシュマップに追加
816 this->Put( pDllProc );
817}
818
819bool ProcPointer::SetParamsAndReturnType( const char *sourceOfParams, int nowLine ){
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]!='('){
829 compiler.errorMessenger.Output(1,NULL,nowLine);
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;
850 Subscripts subscripts;
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 //配列パラメータ
878 if( isRef == false ) compiler.errorMessenger.Output(29,NULL,nowLine);
879 isArray = true;
880
881 if((name[i2-2]=='('&&name[i2-1]==')')||
882 (name[i2-2]=='['&&name[i2-1]==']'))
883 {
884 subscripts.push_back( LONG_MAX );
885
886 name[i2-2]=0;
887 }
888 else{
889 GetArrange(name,temp2,subscripts);
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
920 compiler.StringToType( temporary, type );
921
922 if( type.IsNull() ){
923 compiler.errorMessenger.Output(3,temporary,nowLine);
924 type.SetBasicType( DEF_PTR_VOID );
925 }
926 }
927 else{
928 type.SetBasicType( Type::GetBasicTypeFromSimpleName(temporary) );
929 compiler.errorMessenger.Output(-103,temporary,nowLine);
930 }
931
932 Parameter *pParam = new Parameter( name, type, isRef );
933 if( isArray ){
934 pParam->SetArray( subscripts );
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{
946 compiler.errorMessenger.Output(1,NULL,nowLine);
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 }
974 compiler.StringToType( temporary, this->returnType );
975 if( this->returnType.IsNull() ) compiler.errorMessenger.Output(3,temporary,nowLine);
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 // 戻り値がない
993 compiler.errorMessenger.Output(26,this->GetName(),nowLine);
994 }
995 }
996 else{
997 if( !this->ReturnType().IsNull() ){
998 // Sub定義なのに、戻り値がある
999 compiler.errorMessenger.Output(38,this->GetName(),nowLine);
1000 }
1001 }
1002
1003 return true;
1004}
1005
1006int ProcPointers::Add( const string &typeExpression )
1007{
1008 DWORD dwProcType = (DWORD)typeExpression[2];
1009 const string &paramStr = typeExpression.substr( 3 );
1010
1011 Procedure::Kind kind = Procedure::Sub;
1012 if( dwProcType == ESC_FUNCTION ){
1013 kind = Procedure::Function;
1014 }
1015
1016 ProcPointer *pProcPointer = new ProcPointer( kind );
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
1027void ProcPointers::Clear()
1028{
1029 ProcPointers &procPointers = *this;
1030 BOOST_FOREACH( ProcPointer *pProcPointer, procPointers ){
1031 delete pProcPointer;
1032 }
1033 this->clear();
1034}
Note: See TracBrowser for help on using the repository browser.