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

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

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

File size: 26.5 KB
Line 
1#include "stdafx.h"
2
3#include <Compiler.h>
4#include <LexicalScope.h>
5#include <Variable.h>
6
7#include "../BasicCompiler_Common/common.h"
8
9#ifdef _AMD64_
10#include "../compiler_x64/opcode.h"
11#else
12#include "../compiler_x86/opcode.h"
13#endif
14
15using namespace ActiveBasic::Compiler;
16
17BOOL IsPtrType(int type){
18    if(type==-1) return 0;
19
20    if(PTR_LEVEL(type)||type==DEF_PTR_VOID||type==DEF_PTR_PROC||
21        (type&FLAG_PTR) ) return 1;
22
23    return 0;
24}
25BOOL IsSignedType(int type){
26    switch(type){
27        case DEF_SBYTE:
28        case DEF_INTEGER:
29        case DEF_LONG:
30        case DEF_INT64:
31        case DEF_SINGLE:
32        case DEF_DOUBLE:
33        case DEF_CHAR:
34            return 1;
35        default:
36            break;
37    }
38    return 0;
39}
40BOOL IsNaturalWholeNumberType(int type){
41    switch(type){
42        case DEF_SBYTE:
43        case DEF_BYTE:
44        case DEF_INTEGER:
45        case DEF_WORD:
46        case DEF_LONG:
47        case DEF_DWORD:
48        case DEF_INT64:
49        case DEF_QWORD:
50        case DEF_CHAR:
51            return 1;
52        default:
53            break;
54    }
55    return 0;
56}
57BOOL IsWholeNumberType(int type){
58    return (
59        IsNaturalWholeNumberType(type)
60        || IsPtrType(type)
61        || type == DEF_BOOLEAN
62        );
63}
64BOOL IsRealNumberType(int type){
65    switch(type){
66        case DEF_DOUBLE:
67        case DEF_SINGLE:
68            return 1;
69        default:
70            break;
71    }
72    return 0;
73}
74BOOL Is64Type(int type){
75    switch(type){
76        case DEF_INT64:
77        case DEF_QWORD:
78            return 1;
79        default:
80            break;
81    }
82#ifdef _AMD64_
83    return IsPtrType(type);
84#else
85    return 0;
86#endif
87}
88int GetSignedType(int type){
89    switch(type){
90        case DEF_BYTE:
91            return DEF_SBYTE;
92        case DEF_WORD:
93            return DEF_INTEGER;
94        case DEF_DWORD:
95            return DEF_LONG;
96        case DEF_QWORD:
97            return DEF_INT64;
98        default:
99            break;
100    }
101#ifdef _AMD64_
102    if(IsPtrType(type)) return DEF_INT64;
103#else
104    if(IsPtrType(type)) return DEF_LONG;
105#endif
106    return type;
107}
108int GetUnsignedType(int type){
109    switch(type){
110        case DEF_SBYTE:
111            return DEF_BYTE;
112        case DEF_INTEGER:
113            return DEF_WORD;
114        case DEF_LONG:
115            return DEF_DWORD;
116        case DEF_INT64:
117            return DEF_QWORD;
118        case DEF_CHAR:
119            if( compiler.IsUnicode() ) return DEF_WORD;
120            return DEF_BYTE;
121    }
122    return type;
123}
124int GetPtrType(int type){
125    return MAKE_PTR_TYPE(NATURAL_TYPE(type),PTR_LEVEL(type)+1);
126}
127BOOL GetTypeName(int type,LONG_PTR lpIndex,char *name){
128    if(PTR_LEVEL(type)){
129        //ポインタ型
130        name[0]='*';
131        return GetTypeName(MAKE_PTR_TYPE(NATURAL_TYPE(type),PTR_LEVEL(type)-1),lpIndex,name+1);
132    }
133
134    //整数型
135    if(type==DEF_SBYTE)             lstrcpy(name,"SByte");
136    else if(type==DEF_BYTE)         lstrcpy(name,"Byte");
137    else if(type==DEF_INTEGER)      lstrcpy(name,"Integer");
138    else if(type==DEF_WORD)         lstrcpy(name,"Word");
139    else if(type==DEF_LONG)         lstrcpy(name,"Long");
140    else if(type==DEF_DWORD)        lstrcpy(name,"DWord");
141    else if(type==DEF_INT64)        lstrcpy(name,"Int64");
142    else if(type==DEF_QWORD)        lstrcpy(name,"QWord");
143
144    //実数型
145    else if(type==DEF_SINGLE)       lstrcpy(name,"Single");
146    else if(type==DEF_DOUBLE)       lstrcpy(name,"Double");
147
148    //文字型
149    //else if(type==DEF_CHAR)               lstrcpy(name,"Char");
150
151    //bool型
152    else if(type==DEF_BOOLEAN)      lstrcpy(name,"Boolean");
153
154    //オブジェクト
155    else if(type==DEF_OBJECT || type==DEF_STRUCT){
156        if(lpIndex==0) lstrcpy(name,"non");
157        else{
158            lstrcpy(name,((CClass *)lpIndex)->GetName().c_str());
159        }
160    }
161
162    //ポインタ型
163    else if(type==DEF_PTR_VOID)     lstrcpy(name,"VoidPtr");
164
165    else if(type==DEF_PTR_PROC){
166        if(lpIndex==-1) lstrcpy(name,"VoidPtr");
167        else{
168            if( compiler.GetObjectModule().meta.GetProcPointers()[lpIndex]->ReturnType().IsNull() )
169                lstrcpy(name,"*Sub");
170            else lstrcpy(name,"*Function");
171        }
172    }
173
174    else{
175        extern int cp;
176        compiler.errorMessenger.Output(1,NULL,cp);
177        return 0;
178    }
179    return 1;
180}
181
182Type GetStringTypeInfo(){
183    Type type( DEF_OBJECT, *compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr() );
184    return type;
185}
186
187void GetWithName(char *buffer){
188    extern WITHINFO WithInfo;
189    int i;
190
191    buffer[0]=0;
192    for(i=0;i<WithInfo.num;i++)
193        lstrcat(buffer,WithInfo.ppName[i]);
194}
195
196
197void GetArrange(char *variable,char *variAnswer, Subscripts &subscripts ){
198    extern int cp;
199    int i,i2,i4;
200    double dbl;
201    _int64 i64data;
202    BOOL bBracket;
203    char temporary[VN_SIZE];
204
205    for(i=0;;i++){
206        if(variable[i]=='('||variable[i]=='['){
207            if(variable[i]=='[') bBracket=1;
208            else bBracket=0;
209
210            variAnswer[i]=0;
211            for(i++,i2=0;;i++,i2++){
212                if(variable[i]==','){
213                    temporary[i2]=0;
214
215                    Type resultType;
216                    if( !StaticCalculation(true, temporary,0,&i64data,resultType) ){
217                        return;
218                    }
219                    if(resultType.IsReal()){
220                        memcpy(&dbl,&i64data,sizeof(double));
221                        i64data=(_int64)dbl;
222                    }
223
224                    if(i64data<0)
225                    {
226                        //error
227                        subscripts.push_back( 0 );
228                    }
229                    else
230                    {
231                        subscripts.push_back( (int)i64data );
232                    }
233                    i2=-1;
234                    continue;
235                }
236                if(variable[i]=='('){
237                    i4=GetStringInPare(temporary+i2,variable+i);
238                    i2+=i4-1;
239                    i+=i4-1;
240                    continue;
241                }
242                if(variable[i]=='['){
243                    i4=GetStringInBracket(temporary+i2,variable+i);
244                    i2+=i4-1;
245                    i+=i4-1;
246                    continue;
247                }
248                if(variable[i]==')'&&bBracket==0||
249                    variable[i]==']'&&bBracket){
250                    temporary[i2]=0;
251                    if(i2==0){
252                        subscripts.push_back( -2 );
253                        break;
254                    }
255
256                    Type resultType;
257                    if( !StaticCalculation(true, temporary,0,&i64data,resultType) ){
258                        return;
259                    }
260                    if(resultType.IsReal()){
261                        memcpy(&dbl,&i64data,sizeof(double));
262                        i64data=(_int64)dbl;
263                    }
264
265                    if(i64data<0){
266                        //error
267                        subscripts.push_back( 0 );
268                    }
269                    else
270                    {
271                        subscripts.push_back( (int)i64data );
272                    }
273                    break;
274                }
275                if(variable[i]=='\"'){
276                    compiler.errorMessenger.Output(1,NULL,cp);
277                    return;
278                }
279                temporary[i2]=variable[i];
280            }
281            break;
282        }
283        variAnswer[i]=variable[i];
284        if(variable[i]=='\0'){
285            break;
286        }
287    }
288}
289
290
291BOOL GetVarFormatString( char *buffer,char *array,char *array2,char *NestMember,ReferenceKind &refType, PareOrBracket *pPareOrBracket ){
292    extern int cp;
293    int i,i2,i3;
294    char cPare_Open,cPare_Close;
295
296    array[0]=0;
297    array2[0]=0;
298    NestMember[0]=0;
299    for(i=0;;i++){
300        if(buffer[i]=='\"'){
301            for(i++;;i++){
302                if(IsDBCSLeadByte(buffer[i])){
303                    i++;
304                    continue;
305                }
306                if(buffer[i]=='\"') break;
307            }
308        }
309        if(buffer[i]=='['||buffer[i]=='('){
310            if(buffer[i]=='['){
311                cPare_Open='[';
312                cPare_Close=']';
313            }
314            else{
315                cPare_Open='(';
316                cPare_Close=')';
317            }
318
319            if( pPareOrBracket )
320            {
321                // []なのか、()なのかを伝える
322                if( cPare_Open == '[' )
323                {
324                    *pPareOrBracket = Bracket;
325                }
326                else
327                {
328                    *pPareOrBracket = Pare;
329                }
330            }
331
332            buffer[i]=0;
333            for(i++,i2=0;;i++,i2++){
334                if(buffer[i]==cPare_Open){
335                    if(cPare_Open=='[') i3=GetStringInBracket(array+i2,buffer+i);
336                    else i3=GetStringInPare(array+i2,buffer+i);
337                    i+=i3-1;
338                    i2+=i3-1;
339                    continue;
340                }
341                if(buffer[i]==cPare_Close){
342                    array[i2]=0;
343                    break;
344                }
345                array[i2]=buffer[i];
346            }
347            if(buffer[i+1]==cPare_Open){
348                for(i+=2,i2=0;;i++,i2++){
349                    if(buffer[i]==cPare_Open){
350                        if(cPare_Open=='[') i3=GetStringInBracket(array2+i2,buffer+i);
351                        else i3=GetStringInPare(array2+i2,buffer+i);
352                        i+=i3-1;
353                        i2+=i3-1;
354                        continue;
355                    }
356                    if(buffer[i]==cPare_Close){
357                        array2[i2]=0;
358                        break;
359                    }
360                    array2[i2]=buffer[i];
361                }
362                if(buffer[i+1]==cPare_Open){
363                    compiler.errorMessenger.Output(14,buffer,cp);
364                    return 0;
365                }
366            }
367            continue;
368        }
369        if(buffer[i]=='.'){
370            lstrcpy(NestMember,buffer+i+1);
371            refType = RefDot;
372            buffer[i]=0;
373            break;
374        }
375        if(buffer[i]==1&&buffer[i+1]==ESC_PSMEM){
376            lstrcpy(NestMember,buffer+i+2);
377            refType = RefPointer;
378            buffer[i]=0;
379            break;
380        }
381        if(buffer[i]=='\0') break;
382    }
383    return 1;
384}
385
386void GetArrayElement( const char *buffer,char *variable,char *array_element){
387    array_element[0]=0;
388
389    if(buffer[lstrlen(buffer)-1]!=']'){
390        lstrcpy(variable,buffer);
391        return;
392    }
393
394    int i,i2;
395    for(i=0;;i++){
396        if(buffer[i]=='\0') break;
397        if(buffer[i]=='['){
398            i2=GetStringInBracket(array_element,buffer+i);
399            i+=i2-1;
400            continue;
401        }
402    }
403
404    lstrcpy(variable,buffer);
405    variable[lstrlen(variable)-lstrlen(array_element)]=0;
406
407    RemoveStringBracket(array_element);
408}
409
410BOOL CheckVarNameError(char *name,int nowLine){
411    int i2;
412
413    if(!IsVariableTopChar(name[0])){
414        compiler.errorMessenger.Output(1,NULL,nowLine);
415        return 0;
416    }
417    for(i2=1;;i2++){
418        if(name[i2]=='\0') break;
419        if(!IsVariableChar(name[i2])){
420            compiler.errorMessenger.Output(1,NULL,nowLine);
421            return 0;
422        }
423    }
424    return 1;
425}
426
427int JumpSubScripts( const Subscripts &subscripts ){
428    //DIMで定義された並んだ配列の数だけアドレスを進める
429    int i, i2;
430    for( i=0,i2=1; i<(int)subscripts.size(); i++ ){
431        i2 *= subscripts[i] + 1;
432    }
433    return i2;
434}
435
436
437bool GetMemberType( const Type &classType, const char *lpszMember, Type &resultType, BOOL bPrivateAccess, bool isErrorEnabled)
438{
439    const CClass &objClass = classType.GetClass();
440
441    extern int cp;
442
443    //クラス、配列の構成要素を解析する
444    char VarName[VN_SIZE];      //変数名
445    char array[VN_SIZE];        //第1次配列
446    char lpPtrOffset[VN_SIZE];      //第2次配列
447    char NestMember[VN_SIZE];   //入れ子メンバ
448    ReferenceKind refType = RefNon;
449    lstrcpy(VarName,lpszMember);
450    if(!GetVarFormatString(VarName,array,lpPtrOffset,NestMember,refType)) return false;
451
452    const CMember *pMember = objClass.FindDynamicMember( VarName );
453    if( !pMember ){
454        if(isErrorEnabled) compiler.errorMessenger.Output(103,VarName,cp);
455        return false;
456    }
457
458    //アクセシビリティをチェック
459    if( compiler.IsCompilingClass() && &objClass == &compiler.GetCompilingClass() ){
460        //同一クラスオブジェクトの場合はプライベートアクセスを容認する
461        if( pMember->IsNoneAccess() ){
462            if(isErrorEnabled) compiler.errorMessenger.Output(107,VarName,cp);
463            return false;
464        }
465    }
466    else{
467        if(( bPrivateAccess==0 && pMember->IsPrivate() )||
468            pMember->IsNoneAccess() ){
469            if(isErrorEnabled) compiler.errorMessenger.Output(107,VarName,cp);
470            return false;
471        }
472        else if( bPrivateAccess==0 && pMember->IsProtected() ){
473            if(isErrorEnabled) compiler.errorMessenger.Output(108,VarName,cp);
474            return false;
475        }
476    }
477
478    resultType = pMember->GetType();
479
480    // 型パラメータを解決
481    ResolveFormalGenericTypeParameter( resultType, classType );
482
483
484    //ポインタ変数の場合
485    if( resultType.IsPointer() ){
486        if( pMember->GetSubscripts().size() == 0 ){
487            lstrcpy(lpPtrOffset,array);
488            array[0]=0;
489        }
490    }
491    else{
492        if(lpPtrOffset[0]){
493            if(isErrorEnabled) compiler.errorMessenger.Output(16,lpszMember,cp);
494            return false;
495        }
496    }
497
498    if(array[0]){
499        //配列オフセット
500        if( pMember->GetSubscripts().size() <= 0 )
501        {
502            // 配列ではないメンバに配列指定をした
503            return false;
504        }
505    }
506    else if( pMember->GetSubscripts().size() > 0 ){
507        resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR );
508    }
509
510    if( refType != RefNon ){
511        //入れ子構造の場合
512
513        return GetMemberType( pMember->GetType(),
514            NestMember,
515            resultType,
516            0,
517            isErrorEnabled);
518    }
519
520    if(lpPtrOffset[0]){
521        if( resultType.PtrLevel() ){
522            resultType.PtrLevelDown();
523        }
524        else{
525            //エラー
526            if(isErrorEnabled) compiler.errorMessenger.Output(1,NULL,cp);
527            return false;
528        }
529    }
530
531    return true;
532}
533bool GetVarType( const char *nameBuffer, Type &resultType, bool isErrorEnabled){
534    char variable[VN_SIZE];
535
536    if(nameBuffer[0]=='.'){
537        GetWithName(variable);
538        lstrcat(variable,nameBuffer);
539    }
540    else lstrcpy(variable,nameBuffer);
541
542    // 名前空間を分離
543    char namespaceStr[VN_SIZE]="", simpleName[VN_SIZE];
544    compiler.GetObjectModule().meta.GetNamespaces().SplitNamespace( variable, namespaceStr, simpleName );
545
546    // 先頭オブジェクトまたはクラス名と入れ子メンバに分割
547    ReferenceKind refType;
548    char member[VN_SIZE],array[VN_SIZE],lpPtrOffset[VN_SIZE];
549    GetVarFormatString(simpleName,array,lpPtrOffset,member,refType);
550
551    // 名前空間を分離していた場合は結合
552    char VarName[VN_SIZE];
553    if( namespaceStr[0] ){
554        sprintf( VarName, "%s.%s", namespaceStr, simpleName );
555    }
556    else{
557        lstrcpy( VarName, simpleName );
558    }
559
560    const Variable *pVar = NULL;
561
562    if( compiler.IsLocalAreaCompiling() ){
563        /////////////////
564        // ローカル変数
565        /////////////////
566
567        pVar = compiler.GetCompilingUserProc().GetLocalVars().BackSearch( LexicalAnalyzer::FullNameToSymbol( VarName ) );
568        if( pVar ){
569            goto ok;
570        }
571    }
572
573    if( compiler.IsCompilingClass() ){
574        ///////////////////////
575        // クラスメンバの参照
576        ///////////////////////
577
578        if(lstrcmpi(variable,"This")==0){
579            //Thisオブジェクト
580            resultType.SetType( DEF_OBJECT, &compiler.GetCompilingClass() );
581            return true;
582        }
583
584        if(memicmp(variable,"This.",5)==0){
585            //Thisオブジェクトのメンバを参照するとき
586            SlideString(variable+5,-5);
587            lstrcpy(VarName,variable);
588        }
589        else{
590            //クラス内の動的メンバを参照するとき(通常)
591
592            if( !compiler.GetCompilingClass().HasDynamicMember( VarName ) )
593            {
594                goto NonClassMember;
595            }
596        }
597
598        return GetMemberType(
599            Type( DEF_OBJECT, compiler.GetCompilingClass() ),
600            variable,
601            resultType,
602            1,
603            isErrorEnabled
604        );
605    }
606
607NonClassMember:
608
609    //////////////////////////
610    // 静的ローカル変数
611    // ※"Static.Object.Method.Variable"
612    //////////////////////////
613
614    char temporary[VN_SIZE];
615    if( compiler.IsLocalAreaCompiling() ){
616        GetNowStaticVarFullName(VarName,temporary);
617
618        pVar = compiler.GetObjectModule().meta.GetGlobalVars().Find( LexicalAnalyzer::FullNameToSymbol( temporary ) );
619        if( pVar ){
620            goto ok;
621        }
622    }
623
624
625    //////////////////////////
626    // クラスの静的メンバ
627    //////////////////////////
628
629    if(member[0]){
630        lstrcpy(temporary,member);
631        char tempMember[VN_SIZE];
632        char tempArray[VN_SIZE];
633        {
634            ReferenceKind refType;
635            GetVarFormatString(temporary,tempArray,lpPtrOffset,tempMember,refType);
636        }
637
638        int typeDefIndex = compiler.GetObjectModule().meta.GetTypeDefs().GetIndex( VarName );
639        if( typeDefIndex != -1 ){
640            // TypeDef後の型名だったとき
641            lstrcpy( VarName, compiler.GetObjectModule().meta.GetTypeDefs()[typeDefIndex].GetBaseName().c_str() );
642        }
643
644        char temp2[VN_SIZE];
645        sprintf(temp2,"%s.%s",VarName,temporary);
646
647        pVar = compiler.GetObjectModule().meta.GetGlobalVars().Find( LexicalAnalyzer::FullNameToSymbol( temp2 ) );
648        if( pVar ){
649            lstrcpy(member,tempMember);
650            lstrcpy(array,tempArray);
651            goto ok;
652        }
653    }
654
655    if( compiler.IsCompilingClass() ){
656        //自身のクラスから静的メンバを参照する場合
657        char temp2[VN_SIZE];
658        sprintf(temp2,"%s.%s",compiler.GetCompilingClass().GetName().c_str(),VarName);
659
660        pVar = compiler.GetObjectModule().meta.GetGlobalVars().Find( LexicalAnalyzer::FullNameToSymbol( temp2 ) );
661        if( pVar ){
662            goto ok;
663        }
664    }
665
666
667    ////////////////////
668    // グローバル変数
669    ////////////////////
670
671    pVar = compiler.GetObjectModule().meta.GetGlobalVars().BackSearch( LexicalAnalyzer::FullNameToSymbol( VarName ) );
672    if( pVar ){
673        goto ok;
674    }
675
676    //変数として見つからなかったとき
677    if(isErrorEnabled) compiler.errorMessenger.Output(3,variable,cp);
678    return false;
679
680ok:
681
682    //ポインタ変数の場合
683    if( pVar->GetType().IsPointer() ){
684        if( !pVar->IsArray() ){
685            lstrcpy(lpPtrOffset,array);
686            array[0]=0;
687        }
688    }
689    else{
690        if(lpPtrOffset[0]){
691            if(isErrorEnabled) compiler.errorMessenger.Output(16,variable,cp);
692            return false;
693        }
694    }
695
696    resultType = pVar->GetType();
697
698    if(member[0]){
699        if( NATURAL_TYPE( resultType.GetBasicType() )==DEF_OBJECT
700            || NATURAL_TYPE( resultType.GetBasicType() )==DEF_STRUCT)
701        {
702            return GetMemberType(resultType,member,resultType,0,isErrorEnabled);
703        }
704    }
705
706    if( array[0] == 0 && pVar->GetSubscripts().size() > 0 ){
707        //配列の先頭ポインタを示す場合
708        resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR );
709    }
710
711    if(lpPtrOffset[0]){
712        if( resultType.PtrLevel() ){
713            resultType.PtrLevelDown();
714        }
715        else{
716            //エラー
717            if(isErrorEnabled) compiler.errorMessenger.Output(1,NULL,cp);
718            return false;
719        }
720    }
721
722    return true;
723}
724
725bool GetVarOffsetReadOnly(const char *NameBuffer,RELATIVE_VAR *pRelativeVar,Type &resultType, Subscripts *pResultSubscripts )
726{
727    //読み取り専用で変数へアクセス
728    return GetVarOffset(
729        true,       //エラー表示有効
730        false,      //書き込みアクセスは無し
731        NameBuffer,
732        pRelativeVar,
733        resultType,
734        pResultSubscripts
735    );
736}
737bool GetVarOffsetReadWrite(const char *NameBuffer,RELATIVE_VAR *pRelativeVar,Type &resultType, Subscripts *pResultSubscripts )
738{
739    //読み書き両用で変数へアクセス
740    return GetVarOffset(
741        true,       //エラー表示有効
742        true,       //書き込みアクセス
743        NameBuffer,
744        pRelativeVar,
745        resultType,
746        pResultSubscripts
747    );
748}
749
750
751
752bool GetDimentionFormat( const char *buffer,
753                        char *VarName,
754                        Subscripts &subscripts,
755                        Type &type,
756                        char *InitBuf,
757                        char *ConstractParameter ){
758    int i,i2,i3,IsStr;
759    char variable[VN_SIZE],temporary[8192];
760
761    for(i=0;;i++){
762        if((buffer[i]==1&&buffer[i+1]==ESC_AS)||
763            buffer[i]=='='||
764            buffer[i]=='\0'){
765            variable[i]=0;
766            break;
767        }
768        variable[i]=buffer[i];
769    }
770
771    if(buffer[i]=='='){
772        ////////////////////////////////////
773        // 初期化データが指定されいるとき
774        ////////////////////////////////////
775        i++;
776
777        if( buffer[i]=='[' ){
778            // 構造初期データの場合
779
780            i3=GetStringInBracket(InitBuf,buffer+i);
781            i+=i3;
782        }
783        else{
784            // 代入初期データの場合
785
786            for(i2=0,IsStr=0;;i++,i2++){
787                if(buffer[i]=='\"') IsStr^=1;
788                if(buffer[i]=='('&&IsStr==0){
789                    i3=GetStringInPare(InitBuf+i2,buffer+i);
790                    i+=i3-1;
791                    i2+=i3-1;
792                    continue;
793                }
794                if(buffer[i]=='['&&IsStr==0){
795                    i3=GetStringInBracket(InitBuf+i2,buffer+i);
796                    i+=i3-1;
797                    i2+=i3-1;
798                    continue;
799                }
800                if((buffer[i]==','&&IsStr==0)||
801                    buffer[i]=='\0'){
802                    InitBuf[i2]=0;
803                    break;
804                }
805                InitBuf[i2]=buffer[i];
806            }
807        }
808    }
809    else{
810        //初期化データなし
811        InitBuf[0]=0;
812    }
813
814    ConstractParameter[0]=0;
815    if(buffer[i]==1&&buffer[i+1]==ESC_AS){
816        /////////////////////////////
817        // "As ~" による型指定あり
818        /////////////////////////////
819
820        for(i+=2,i2=0;;i++,i2++){
821            if(buffer[i]=='('||buffer[i]=='\0'){
822                temporary[i2]=0;
823                break;
824            }
825            temporary[i2]=buffer[i];
826        }
827        if(temporary[0]=='*'&&
828            temporary[1]==1&&
829            (temporary[2]==ESC_FUNCTION||temporary[2]==ESC_SUB)){
830            if(buffer[i]!='('){
831                compiler.errorMessenger.Output(10,temporary,cp);
832                return false;
833            }
834            i3=GetStringInPare(temporary+3,buffer+i);
835            i+=i3;
836            i2+=i3;
837
838            if(temporary[2]==ESC_FUNCTION&&buffer[i]==1&&buffer[i+1]==ESC_AS){
839                temporary[i2++]=buffer[i++];
840                temporary[i2++]=buffer[i++];
841                for(;;i++,i2++){
842                    if(!IsVariableChar(buffer[i])){
843                        temporary[i2]=0;
844                        break;
845                    }
846                    temporary[i2]=buffer[i];
847                }
848            }
849        }
850
851        if( !compiler.StringToType( temporary, type ) ){
852            compiler.errorMessenger.Output(3,temporary,cp);
853            return false;
854        }
855
856        if(buffer[i]=='('){
857            //コンストラクタに渡すパラメータを取得
858            i2=GetStringInPare(ConstractParameter,buffer+i);
859            i+=i2;
860            RemoveStringPare(ConstractParameter);
861
862            if( !type.IsObject() ){
863                compiler.errorMessenger.Output(112,variable,cp);
864                return false;
865            }
866        }
867    }
868    else{
869        /////////////////
870        // As指定なし
871        /////////////////
872
873        if( InitBuf[0] == '\0' ){
874            //As指定も、初期値指定もない場合
875            type.SetBasicType( Type::GetBasicTypeFromSimpleName(variable) );
876
877            i2=lstrlen(variable)-1;
878            if(i2>=0){
879                if(!(variable[i2]=='#'||variable[i2]=='!'||variable[i2]=='%'||variable[i2]=='$'))
880                    compiler.errorMessenger.Output(-103,variable,cp);
881            }
882        }
883        else{
884            //初期値の型を判別して自動的に型情報を付加する
885            if( !NumOpe_GetType( InitBuf, GetStringTypeInfo(), type ) ){
886                // エラーの場合
887                return false;
888            }
889
890            if( IS_LITERAL( type.GetIndex() ) ){
891                type.SetIndex( -1 );
892            }
893        }
894
895    }
896
897    if( InitBuf[0] != '\0' && ConstractParameter[0] != '\0' ){
898        //初期値とコンストラクタパラメータが同時に呼び出されているとき
899        compiler.errorMessenger.Output(132, NULL, cp);
900    }
901
902    GetArrange(variable,VarName,subscripts);
903    return true;
904}
905
906BOOL GetNowStaticVarFullName(char *VarName,char *FullName){
907    if( compiler.IsGlobalAreaCompiling() ){
908        // グローバル領域をコンパイル中のとき
909        return 0;
910    }
911
912    const UserProc &proc = compiler.GetCompilingUserProc();
913
914    //Static識別
915    lstrcpy(FullName,"Static%");
916
917    //クラス名
918    if( compiler.IsCompilingClass() ){
919        lstrcat(FullName,compiler.GetCompilingClass().GetName().c_str());
920        lstrcat(FullName,"%");
921    }
922
923    //関数(またはメソッド)名
924    lstrcat(FullName,proc.GetName().c_str());
925    lstrcat(FullName,"%");
926
927    //ID
928    char temp[255];
929    sprintf(temp,"%x",proc.GetId());
930    lstrcat(FullName,temp);
931    lstrcat(FullName,"%");
932
933    //変数名
934    lstrcat(FullName,VarName);
935
936    return 1;
937}
938
939
940void AddGlobalVariable( const char *name, const Subscripts &subscripts, const Type &type,const char *InitBuf,const char *ConstractParameter,DWORD dwFlag){
941    /////////////////////////
942    // グローバル変数を追加
943    /////////////////////////
944
945    if( compiler.GetObjectModule().meta.GetGlobalVars().DuplicateCheck( LexicalAnalyzer::FullNameToSymbol( name ) ) ){
946        //2重定義のエラー
947        compiler.errorMessenger.Output(15,name,cp);
948        return;
949    }
950
951    bool isConst = ( dwFlag & DIMFLAG_CONST ) ? true:false;
952
953    Variable *pVar = new Variable(
954        compiler.GetNamespaceSupporter().GetLivingNamespaceScopes(),
955        name,
956        type,
957        isConst,
958        false,
959        ConstractParameter,
960        ( InitBuf[0] != 0 || dwFlag == DIMFLAG_INITDEBUGVAR )
961    );
962
963    if( subscripts.size() > 0 ){
964        //配列あり
965        pVar->SetArray( subscripts );
966    }
967
968    //レキシカルスコープ
969    pVar->SetScopeLevel( compiler.codeGenerator.lexicalScopes.GetNowLevel() );
970    pVar->SetScopeStartAddress( compiler.codeGenerator.lexicalScopes.GetStartAddress() );
971    pVar->isLiving = true;
972
973    //エラー用
974    pVar->source_code_address=cp;
975
976    // 変数を追加
977    compiler.GetObjectModule().meta.GetGlobalVars().Add( pVar );
978
979    if(InitBuf[0]){
980        int result = 0;
981        if( !pVar->GetType().IsObject() ){
982            result = SetInitGlobalData(pVar->GetOffsetAddress(),
983                pVar->GetType(),
984                pVar->GetSubscripts(),
985                InitBuf);
986        }
987
988        if(!result){
989            //動的な式だった場合は代入演算を行う
990
991            //初期代入時のみ、書き込みアクセスを許可する
992            if( isConst ){
993                pVar->ConstOff();
994            }
995
996            //代入
997            char temporary[8192];
998            sprintf(temporary,"%s=%s",name,InitBuf);
999            OpcodeCalc(temporary);
1000
1001            //アクセス制限を元に戻す
1002            if( isConst ){
1003                pVar->ConstOn();
1004            }
1005        }
1006    }
1007
1008
1009    if( type.IsObject() ){
1010        //デストラクタの利用フラグをオンにする
1011        const CMethod *method = type.GetClass().GetDestructorMethod();
1012        if( method ){
1013            method->GetUserProc().Using();
1014        }
1015    }
1016}
1017
1018void dim(char *Parameter,DWORD dwFlags){
1019    extern HANDLE hHeap;
1020    int i2;
1021    char VarName[VN_SIZE];
1022
1023    i2 = 0;
1024
1025    if( Parameter[i2] == 1 && Parameter[i2+1] == ESC_BYREF ){
1026        //参照型
1027        compiler.errorMessenger.OutputFatalError();
1028        Parameter += 2;
1029    }
1030
1031    if(dwFlags & DIMFLAG_CONST){
1032
1033        //////////////////////////////////
1034        // 定数変数の場合を考慮
1035        //////////////////////////////////
1036        for(;;i2++){
1037            if(Parameter[i2] == '=' ||
1038                Parameter[i2] == 1 && Parameter[i2] == ESC_AS ||
1039                Parameter[i2] =='('){
1040                    VarName[i2] = 0;
1041                    break;
1042            }
1043            VarName[i2] = Parameter[i2];
1044        }
1045
1046        //定数と2重定義されていないる場合は抜け出す
1047        if(compiler.GetObjectModule().meta.GetGlobalConsts().GetBasicType(VarName)){
1048            return;
1049        }
1050
1051        //定数マクロとして定義されている場合は抜け出す
1052        if( compiler.GetObjectModule().meta.GetGlobalConstMacros().IsExist( VarName ) )
1053        {
1054            return;
1055        }
1056    }
1057
1058
1059    //構文を解析
1060    Type type;
1061    char InitBuf[8192];
1062    char ConstractParameter[VN_SIZE];
1063    Subscripts subscripts;
1064    if(!GetDimentionFormat(Parameter, VarName,subscripts,type,InitBuf,ConstractParameter))
1065        return;
1066
1067
1068    //定数と2重定義されていないかを調べる
1069    if(compiler.GetObjectModule().meta.GetGlobalConsts().GetBasicType(VarName)){
1070        compiler.errorMessenger.Output(15,VarName,cp);
1071        return;
1072    }
1073
1074    //定数マクロとして定義されている場合
1075    if( compiler.GetObjectModule().meta.GetGlobalConstMacros().IsExist( VarName ) ){
1076        compiler.errorMessenger.Output(15,VarName,cp);
1077        return;
1078    }
1079
1080    if( type.IsObject() ){
1081        if( type.GetClass().IsBlittableType() ){
1082            // Blittable型のときは基本型として扱う
1083            // ※ただし、コンパイル中のメソッドがBlittable型クラスに属していないこと
1084            if( compiler.IsLocalAreaCompiling()
1085                && compiler.GetCompilingUserProc().HasParentClass()
1086                && compiler.GetCompilingUserProc().GetParentClass().IsBlittableType() )
1087            {
1088                // コンパイル中のメソッドがBlittable型クラスに属している
1089            }
1090            else{
1091                type = type.GetClass().GetBlittableType();
1092            }
1093        }
1094    }
1095
1096    if(dwFlags&DIMFLAG_STATIC)
1097    {
1098        if( compiler.IsGlobalAreaCompiling() )
1099        {
1100            compiler.errorMessenger.Output(60,NULL,cp);
1101            return;
1102        }
1103
1104        /////////////////////
1105        // Static変数
1106        // ※"Static.Object.Method.Variable"
1107        /////////////////////
1108
1109        char temporary[VN_SIZE];
1110        GetNowStaticVarFullName(VarName,temporary);
1111
1112        dim( temporary,subscripts,type,InitBuf,ConstractParameter,dwFlags );
1113
1114        /*
1115        Note: 静的変数のコンストラクタ呼び出しは
1116            _System_InitStaticLocalVariables関数内で一括して行う
1117        */
1118    }
1119    else{
1120        dim( VarName,subscripts,type,InitBuf,ConstractParameter,dwFlags );
1121    }
1122}
1123void OpcodeDim(char *Parameter,DWORD dwFlags){
1124    int i,i2,i3,IsStr=0;
1125    char temporary[8192];
1126
1127    for(i=0,i2=0;;i++,i2++){
1128        if(Parameter[i]=='\"') IsStr^=1;
1129        if(Parameter[i]=='('&&IsStr==0){
1130            i3=GetStringInPare(temporary+i2,Parameter+i);
1131            i+=i3-1;
1132            i2+=i3-1;
1133            continue;
1134        }
1135        if(Parameter[i]=='['&&IsStr==0){
1136            i3=GetStringInBracket(temporary+i2,Parameter+i);
1137            i+=i3-1;
1138            i2+=i3-1;
1139            continue;
1140        }
1141        if( Parameter[i] == '<' && IsStr == 0 )
1142        {
1143            if( IsGenericTypeSourcePart( Parameter + i ) )
1144            {
1145                // ジェネリクス構文
1146                i3=GetStringInGenericBracket(temporary+i2,Parameter+i);
1147                i+=i3-1;
1148                i2+=i3-1;
1149                continue;
1150            }
1151            else
1152            {
1153                // 一般構文
1154            }
1155        }
1156        if((Parameter[i]==','&&IsStr==0)||
1157            Parameter[i]=='\0'){
1158            temporary[i2]=0;
1159
1160            dim(temporary,dwFlags);
1161
1162            if(Parameter[i]=='\0') break;
1163            i2=-1;
1164            continue;
1165        }
1166        temporary[i2]=Parameter[i];
1167    }
1168}
1169
1170void DebugVariable(void)
1171{
1172    char temporary[255];
1173    if( compiler.GetObjectModule().meta.GetGlobalVars().Find( LexicalAnalyzer::FullNameToSymbol( "_DebugSys_dwThreadID" ) ) == NULL )
1174    {
1175        // 未定義の場合は定義する
1176        sprintf(temporary,"_DebugSys_dwThreadID[255]%c%cDWord",1,ESC_AS);
1177        OpcodeDim(temporary,DIMFLAG_INITDEBUGVAR);
1178        sprintf(temporary,"_DebugSys_ProcNum[255]%c%cDWord",1,ESC_AS);
1179        OpcodeDim(temporary,DIMFLAG_INITDEBUGVAR);
1180        sprintf(temporary,"_DebugSys_lplpObp[255]%c%c*ULONG_PTR",1,ESC_AS);
1181        OpcodeDim(temporary,DIMFLAG_INITDEBUGVAR);
1182        sprintf(temporary,"_DebugSys_lplpSpBase[255]%c%c*ULONG_PTR",1,ESC_AS);
1183        OpcodeDim(temporary,DIMFLAG_INITDEBUGVAR);
1184    }
1185}
Note: See TracBrowser for help on using the repository browser.