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, 15 years ago

ヘッダファイルを整理中

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::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 std::string &typeExpression )
1007{
1008    DWORD dwProcType = (DWORD)typeExpression[2];
1009    const std::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.