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, 15 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.