source: dev/BasicCompiler_Common/VariableOpe.cpp @ 128

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

Blittable型を導入した。

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