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

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

UserProcクラスによるコンパイル中関数管理用メソッドを除去(すべてCompilerクラス内で処理するようにした)。

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 std::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 std::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::pGlobalProc = NULL;
486
487
488bool UserProcs::Insert( UserProc *pUserProc, int nowLine )
489{
490 /////////////////////////////////
491 // ハッシュデータに追加
492 /////////////////////////////////
493
494 if( !Put( pUserProc ) )
495 {
496 // 重複しているため、失敗
497 compiler.errorMessenger.Output(15,pUserProc->GetName().c_str(),nowLine);
498 return false;
499 }
500
501 return true;
502}
503
504void UserProcs::EnumGlobalProcs( const char *simpleName, const char *localName, std::vector<const UserProc *> &subs )
505{
506 ///////////////////////////
507 // グローバル関数を検索
508 ///////////////////////////
509
510 // ハッシュ値を取得
511 UserProc *pUserProc = GetHashArrayElement( simpleName );
512 while(pUserProc){
513 if( pUserProc->IsGlobalProcedure() ){
514 if( pUserProc->IsEqualSymbol( LexicalAnalyzer::FullNameToSymbol( localName ) ) ){
515 subs.push_back( pUserProc );
516 }
517 }
518
519 pUserProc=pUserProc->GetChainNext();
520 }
521}
522
523bool DllProc::SetParamsAndReturnType( const char *sourceOfParams, int nowLine ){
524 int i = 0;
525 int i2,i3,sw;
526 char temporary[8192],temp2[VN_SIZE];
527
528 //ソースコードの位置
529 this->codePos = nowLine;
530
531 //パラメータ
532 if(sourceOfParams[i]!='('){
533 compiler.errorMessenger.Output(1,NULL,nowLine);
534 return 0;
535 }
536 i++;
537
538 while(1){
539 if(sourceOfParams[i]==')') break;
540
541 //ByRef
542 bool isRef;
543 if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYVAL){
544 isRef = false;
545 i+=2;
546 }
547 else if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYREF){
548 isRef = true;
549 i+=2;
550 }
551 else isRef = false;
552
553 //パラメータ名
554 bool isArray = false;
555 Subscripts subscripts;
556 char name[VN_SIZE];
557 sw=0;
558 for(i2=0;;i++,i2++){
559 if(sourceOfParams[i]=='('){
560 if(!sw) sw=1;
561
562 i3=GetStringInPare(name+i2,sourceOfParams+i);
563 i2+=i3-1;
564 i+=i3-1;
565 continue;
566 }
567 if(sourceOfParams[i]=='['){
568 if(!sw) sw=1;
569
570 i3=GetStringInBracket(name+i2,sourceOfParams+i);
571 i2+=i3-1;
572 i+=i3-1;
573 continue;
574 }
575 if(!IsVariableChar(sourceOfParams[i])){
576 name[i2]=0;
577 break;
578 }
579 name[i2]=sourceOfParams[i];
580 }
581 if(sw){
582 //配列パラメータ
583 if( isRef == false ) compiler.errorMessenger.Output(29,NULL,nowLine);
584 isArray = true;
585
586 if((name[i2-2]=='('&&name[i2-1]==')')||
587 (name[i2-2]=='['&&name[i2-1]==']'))
588 {
589 subscripts.push_back( LONG_MAX );
590
591 name[i2-2]=0;
592 }
593 else{
594 GetArrange(name,temp2,subscripts);
595 lstrcpy(name,temp2);
596 }
597
598 i2=lstrlen(name);
599 }
600
601 //型
602 Type type( DEF_NON );
603 if(lstrcmp(name,"...")==0) type.SetBasicType( DEF_ELLIPSE );
604 else if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_AS){
605 i+=2;
606
607 i2=0;
608 while(sourceOfParams[i]=='*'){
609 temporary[i2]=sourceOfParams[i];
610 i++;
611 i2++;
612 }
613 for(;;i++,i2++){
614 if(!IsVariableChar(sourceOfParams[i])){
615 if(sourceOfParams[i]==1&&(sourceOfParams[i+1]==ESC_FUNCTION||sourceOfParams[i+1]==ESC_SUB)){
616 temporary[i2++]=sourceOfParams[i++];
617 temporary[i2]=sourceOfParams[i];
618 continue;
619 }
620 temporary[i2]=0;
621 break;
622 }
623 temporary[i2]=sourceOfParams[i];
624 }
625
626 compiler.StringToType( temporary, type );
627
628 if( type.IsNull() ){
629 compiler.errorMessenger.Output(3,temporary,nowLine);
630 type.SetBasicType( DEF_PTR_VOID );
631 }
632 }
633 else{
634 type.SetBasicType( Type::GetBasicTypeFromSimpleName(temporary) );
635 compiler.errorMessenger.Output(-103,temporary,nowLine);
636 }
637
638 Parameter *pParam = new Parameter( name, type, isRef );
639 if( isArray ){
640 pParam->SetArray( subscripts );
641 }
642
643 //パラメータを追加
644 this->params.push_back( pParam );
645
646 if(sourceOfParams[i]==','){
647 i++;
648 continue;
649 }
650 else if(sourceOfParams[i]==')') continue;
651 else{
652 compiler.errorMessenger.Output(1,NULL,nowLine);
653 break;
654 }
655 }
656 i++;
657
658 if(sourceOfParams[i]){
659 ///////////////////
660 // 戻り値を取得
661 ///////////////////
662
663 i2=lstrlen(sourceOfParams)-2;
664
665 int sw_as=0;
666 for(;i2>0;i2--){
667 if(sourceOfParams[i2]==')') break;
668
669 if(sourceOfParams[i2]==1&&sourceOfParams[i2+1]==ESC_AS){
670 i2+=2;
671 i3=0;
672 while(sourceOfParams[i2]=='*') temporary[i3++]=sourceOfParams[i2++];
673 for(;;i2++,i3++){
674 if(!IsVariableChar(sourceOfParams[i2])){
675 temporary[i3]=0;
676 break;
677 }
678 temporary[i3]=sourceOfParams[i2];
679 }
680 compiler.StringToType( temporary, this->returnType );
681 if( this->returnType.IsNull() ) compiler.errorMessenger.Output(3,temporary,nowLine);
682
683 sw_as=1;
684 break;
685 }
686 }
687 }
688 else{
689 //戻り値なしのSub定義
690 this->returnType.SetNull();
691 }
692
693 return true;
694}
695
696void DllProcs::Add(const NamespaceScopes &namespaceScopes, char *buffer,int nowLine){
697 int i2;
698
699 int i=0;
700
701 //Sub/Function
702 Procedure::Kind kind = Procedure::Sub;
703 if(buffer[i]==ESC_SUB){
704 }
705 else if(buffer[i]==ESC_FUNCTION){
706 kind = Procedure::Function;
707 }
708 else{
709 compiler.errorMessenger.Output(1,NULL,nowLine);
710 return;
711 }
712 i++;
713
714 //プロシージャ名
715 char procName[VN_SIZE];
716 bool isCdecl = false;
717 for(i2=0;;i++,i2++){
718 if(buffer[i]==1&&buffer[i+1]==ESC_CDECL){
719 isCdecl = true;
720
721 i+=2;
722 procName[i2]=0;
723 break;
724 }
725 if(buffer[i]==','){
726 procName[i2]=0;
727 break;
728 }
729 if(buffer[i]=='\0'){
730 compiler.errorMessenger.Output(1,NULL,nowLine);
731 return;
732 }
733 procName[i2]=buffer[i];
734 }
735 i++;
736
737 //ユーザー定義関数との重複チェック
738 if(GetSubHash(procName)){
739 compiler.errorMessenger.Output(15,procName,nowLine);
740 return;
741 }
742
743
744 //ライブラリ
745 char dllFileName[MAX_PATH];
746 i = GetOneParameter( buffer, i, dllFileName );
747 Type resultType;
748 _int64 i64data;
749 if( !StaticCalculation( true, dllFileName, 0, &i64data, resultType ) ){
750 return;
751 }
752 if( resultType.GetBasicType() != typeOfPtrChar ){
753 compiler.errorMessenger.Output(1,NULL,nowLine);
754 return;
755 }
756 lstrcpy( dllFileName, (char *)i64data );
757 CharUpper(dllFileName);
758 if(!strstr(dllFileName,".")){
759 lstrcat(dllFileName,".DLL");
760 if(lstrlen(dllFileName)>=16){
761 compiler.errorMessenger.Output(7,NULL,nowLine);
762 return;
763 }
764 }
765
766 //エイリアス
767 char alias[VN_SIZE];
768 i = GetOneParameter( buffer, i, alias );
769 if( alias[0] ){
770 if( !StaticCalculation( true, alias, 0, &i64data, resultType ) ){
771 return;
772 }
773 if( resultType.GetBasicType() != typeOfPtrChar ){
774 compiler.errorMessenger.Output(1,NULL,nowLine);
775 return;
776 }
777 lstrcpy( alias, (char *)i64data );
778 }
779 else{
780 //省略されたときは関数名
781 lstrcpy( alias, procName );
782 }
783
784
785 // オブジェクトを生成
786 DllProc *pDllProc = new DllProc( namespaceScopes, procName, kind, isCdecl, dllFileName, alias );
787
788 // パラメータを解析
789 // ※第1パラメータにに指定するデータの例:"( s As String ) As String"
790 pDllProc->SetParamsAndReturnType( buffer + i, nowLine );
791
792 // パラメータのエラーチェック
793 BOOST_FOREACH( const Parameter *pParam, pDllProc->Params() ){
794 if( pParam->IsObject() ){
795 compiler.errorMessenger.Output(25,pParam->GetVarName(),nowLine);
796 }
797 if( !pParam->IsRef() ){
798 if( pParam->IsStruct() ){
799 compiler.errorMessenger.Output(28,pParam->GetVarName(),nowLine);
800 }
801 }
802 }
803
804 //戻り値のエラーチェック
805 if( pDllProc->IsFunction() ){
806 // Function定義
807
808 if( pDllProc->ReturnType().IsObject() ){
809 // DLL関数ではオブジェクトを戻り値にできない
810 compiler.errorMessenger.Output(40,pDllProc->GetName(),nowLine);
811 }
812 }
813
814 // ハッシュマップに追加
815 this->Put( pDllProc );
816}
817
818bool ProcPointer::SetParamsAndReturnType( const char *sourceOfParams, int nowLine ){
819 int i = 0;
820 int i2,i3,sw;
821 char temporary[8192],temp2[VN_SIZE];
822
823 //ソースコードの位置
824 this->codePos = nowLine;
825
826 //パラメータ
827 if(sourceOfParams[i]!='('){
828 compiler.errorMessenger.Output(1,NULL,nowLine);
829 return 0;
830 }
831 i++;
832 while(1){
833 if(sourceOfParams[i]==')') break;
834
835 //ByRef
836 bool isRef;
837 if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYVAL){
838 isRef = false;
839 i+=2;
840 }
841 else if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYREF){
842 isRef = true;
843 i+=2;
844 }
845 else isRef = false;
846
847 //パラメータ名
848 bool isArray = false;
849 Subscripts subscripts;
850 char name[VN_SIZE];
851 sw=0;
852 for(i2=0;;i++,i2++){
853 if(sourceOfParams[i]=='('){
854 if(!sw) sw=1;
855
856 i3=GetStringInPare(name+i2,sourceOfParams+i);
857 i2+=i3-1;
858 i+=i3-1;
859 continue;
860 }
861 if(sourceOfParams[i]=='['){
862 if(!sw) sw=1;
863
864 i3=GetStringInBracket(name+i2,sourceOfParams+i);
865 i2+=i3-1;
866 i+=i3-1;
867 continue;
868 }
869 if(!IsVariableChar(sourceOfParams[i])){
870 name[i2]=0;
871 break;
872 }
873 name[i2]=sourceOfParams[i];
874 }
875 if(sw){
876 //配列パラメータ
877 if( isRef == false ) compiler.errorMessenger.Output(29,NULL,nowLine);
878 isArray = true;
879
880 if((name[i2-2]=='('&&name[i2-1]==')')||
881 (name[i2-2]=='['&&name[i2-1]==']'))
882 {
883 subscripts.push_back( LONG_MAX );
884
885 name[i2-2]=0;
886 }
887 else{
888 GetArrange(name,temp2,subscripts);
889 lstrcpy(name,temp2);
890 }
891
892 i2=lstrlen(name);
893 }
894
895 //型
896 Type type( DEF_NON );
897 if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_AS){
898 i+=2;
899
900 i2=0;
901 while(sourceOfParams[i]=='*'){
902 temporary[i2]=sourceOfParams[i];
903 i++;
904 i2++;
905 }
906 for(;;i++,i2++){
907 if(!IsVariableChar(sourceOfParams[i])){
908 if(sourceOfParams[i]==1&&(sourceOfParams[i+1]==ESC_FUNCTION||sourceOfParams[i+1]==ESC_SUB)){
909 temporary[i2++]=sourceOfParams[i++];
910 temporary[i2]=sourceOfParams[i];
911 continue;
912 }
913 temporary[i2]=0;
914 break;
915 }
916 temporary[i2]=sourceOfParams[i];
917 }
918
919 compiler.StringToType( temporary, type );
920
921 if( type.IsNull() ){
922 compiler.errorMessenger.Output(3,temporary,nowLine);
923 type.SetBasicType( DEF_PTR_VOID );
924 }
925 }
926 else{
927 type.SetBasicType( Type::GetBasicTypeFromSimpleName(temporary) );
928 compiler.errorMessenger.Output(-103,temporary,nowLine);
929 }
930
931 Parameter *pParam = new Parameter( name, type, isRef );
932 if( isArray ){
933 pParam->SetArray( subscripts );
934 }
935
936 //パラメータを追加
937 this->params.push_back( pParam );
938
939 if(sourceOfParams[i]==','){
940 i++;
941 continue;
942 }
943 else if(sourceOfParams[i]==')') continue;
944 else{
945 compiler.errorMessenger.Output(1,NULL,nowLine);
946 break;
947 }
948 }
949 i++;
950
951 if(sourceOfParams[i]){
952 ///////////////////
953 // 戻り値を取得
954 ///////////////////
955
956 i2=lstrlen(sourceOfParams)-2;
957
958 int sw_as=0;
959 for(;i2>0;i2--){
960 if(sourceOfParams[i2]==')') break;
961
962 if(sourceOfParams[i2]==1&&sourceOfParams[i2+1]==ESC_AS){
963 i2+=2;
964 i3=0;
965 while(sourceOfParams[i2]=='*') temporary[i3++]=sourceOfParams[i2++];
966 for(;;i2++,i3++){
967 if(!IsVariableChar(sourceOfParams[i2])){
968 temporary[i3]=0;
969 break;
970 }
971 temporary[i3]=sourceOfParams[i2];
972 }
973 compiler.StringToType( temporary, this->returnType );
974 if( this->returnType.IsNull() ) compiler.errorMessenger.Output(3,temporary,nowLine);
975
976 sw_as=1;
977 break;
978 }
979 }
980 }
981 else{
982 //戻り値なしのSub定義
983 this->returnType.SetNull();
984 }
985
986 //戻り値のエラーチェック
987 if( IsFunction() ){
988 // Function定義
989
990 if( this->ReturnType().IsNull() ){
991 // 戻り値がない
992 compiler.errorMessenger.Output(26,this->GetName(),nowLine);
993 }
994 }
995 else{
996 if( !this->ReturnType().IsNull() ){
997 // Sub定義なのに、戻り値がある
998 compiler.errorMessenger.Output(38,this->GetName(),nowLine);
999 }
1000 }
1001
1002 return true;
1003}
1004
1005int ProcPointers::Add( const std::string &typeExpression )
1006{
1007 DWORD dwProcType = (DWORD)typeExpression[2];
1008 const std::string &paramStr = typeExpression.substr( 3 );
1009
1010 Procedure::Kind kind = Procedure::Sub;
1011 if( dwProcType == ESC_FUNCTION ){
1012 kind = Procedure::Function;
1013 }
1014
1015 ProcPointer *pProcPointer = new ProcPointer( kind );
1016
1017 //buffer[0]は'('となっている
1018 extern int cp;
1019 pProcPointer->SetParamsAndReturnType( paramStr.c_str(), cp );
1020
1021 this->push_back( pProcPointer );
1022
1023 return (int)this->size()-1;
1024}
1025
1026void ProcPointers::Clear()
1027{
1028 ProcPointers &procPointers = *this;
1029 BOOST_FOREACH( ProcPointer *pProcPointer, procPointers ){
1030 delete pProcPointer;
1031 }
1032 this->clear();
1033}
Note: See TracBrowser for help on using the repository browser.