source: dev/BasicCompiler_Common/Procedure.cpp @ 131

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

Prototypeクラスを用意した。

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