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

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

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

File size: 24.9 KB
Line 
1#include "stdafx.h"
2
3#include <Compiler.h>
4
5#include "common.h"
6
7
8int MakeWholeType(int size,int bSigned){
9    switch(size){
10        case 1:
11            if(bSigned) return DEF_SBYTE;
12            else return DEF_BYTE;
13            break;
14        case 2:
15            if(bSigned) return DEF_INTEGER;
16            else return DEF_WORD;
17            break;
18        case 4:
19            if(bSigned) return DEF_LONG;
20            else return DEF_DWORD;
21            break;
22        case 8:
23            if(bSigned) return DEF_INT64;
24            else return DEF_QWORD;
25            break;
26    }
27    return 0;
28}
29
30int AutoBigCast(int BaseType,int CalcType){
31    int type;
32    type=CalcType;
33
34    if(BaseType==0||BaseType==-1){
35        //ベースタイプが未定のとき
36        return type;
37    }
38
39    if(!IsWholeNumberType(type)){
40        //整数型ではないときは暗黙の変換は必要なし
41        return type;
42    }
43
44    if(BaseType==DEF_OBJECT||BaseType==DEF_STRUCT){
45        //ベースタイプがオブジェクトのときは暗黙の変換は必要なし
46        return type;
47    }
48
49    int BaseTypeSize;
50    BaseTypeSize=Type(BaseType,-1).GetSize();
51
52    if(IsRealNumberType(BaseType)){
53        if(Type(CalcType,-1).GetSize()<4)
54            type=MakeWholeType(4,IsSignedType(CalcType));
55    }
56    else if(BaseTypeSize>Type(CalcType,-1).GetSize()){
57        //要求される型のほうがサイズが大きいとき
58        type=MakeWholeType(BaseTypeSize,IsSignedType(CalcType));
59    }
60
61    if(!type){
62        extern int cp;
63        compiler.errorMessenger.Output(300,NULL,cp);
64    }
65
66    return type;
67}
68
69BOOL CheckCalcType(int idCalc,int *type,int sp){
70    //演算子の右辺、左辺の型をチェック
71    extern int cp;
72
73    //演算子名を取得
74    char temporary[255];
75    GetCalcName(idCalc,temporary);
76
77    switch(idCalc){
78
79        /////////////////////////////////////
80        // 実数に対する論理演算はエラー
81        /////////////////////////////////////
82
83        case CALC_XOR:
84        case CALC_OR:
85        case CALC_AND:
86            if(IsRealNumberType(type[sp-2])||IsRealNumberType(type[sp-1])){
87                //いずれかの項が実数のとき
88                compiler.errorMessenger.Output(45,temporary,cp);
89                return 0;
90            }
91
92            //As以外の演算子に型名が指定されていないかをチェック
93            if((type[sp-2]&FLAG_CAST)||(type[sp-1]&FLAG_CAST)){
94                compiler.errorMessenger.Output(48,temporary,cp);
95                return 0;
96            }
97            break;
98
99        case CALC_NOT:
100            if(IsRealNumberType(type[sp-1])){
101                //実数のとき
102                compiler.errorMessenger.Output(45,temporary,cp);
103                return 0;
104            }
105
106            //As以外の演算子に型名が指定されていないかをチェック
107            if(type[sp-1]&FLAG_CAST){
108                compiler.errorMessenger.Output(48,temporary,cp);
109                return 0;
110            }
111            break;
112
113
114
115        /////////////////////////////////////
116        // 比較演算はチェック項目なし
117        /////////////////////////////////////
118
119        case CALC_PE:
120        case CALC_QE:
121        case CALC_NOTEQUAL:
122        case CALC_EQUAL:
123        case CALC_P:
124        case CALC_Q:
125            //As以外の演算子に型名が指定されていないかをチェック
126            if((type[sp-2]&FLAG_CAST)||(type[sp-1]&FLAG_CAST)){
127                compiler.errorMessenger.Output(48,temporary,cp);
128                return 0;
129            }
130            break;
131
132
133
134        /////////////////////////////////////
135        // 算術演算をチェック
136        /////////////////////////////////////
137
138        case CALC_ADDITION:
139        case CALC_SUBTRACTION:
140        case CALC_PRODUCT:
141        case CALC_QUOTIENT:
142        case CALC_POWER:
143            //As以外の演算子に型名が指定されていないかをチェック
144            if((type[sp-2]&FLAG_CAST)||(type[sp-1]&FLAG_CAST)){
145                compiler.errorMessenger.Output(48,temporary,cp);
146                return 0;
147            }
148            break;
149
150        case CALC_SHL:
151        case CALC_SHR:
152        case CALC_MOD:
153        case CALC_INTQUOTIENT:
154            if(IsRealNumberType(type[sp-2])||IsRealNumberType(type[sp-1])){
155                //いずれかの項が実数のとき
156                compiler.errorMessenger.Output(45,temporary,cp);
157                return 0;
158            }
159
160            //As以外の演算子に型名が指定されていないかをチェック
161            if((type[sp-2]&FLAG_CAST)||(type[sp-1]&FLAG_CAST)){
162                compiler.errorMessenger.Output(48,temporary,cp);
163                return 0;
164            }
165            break;
166
167        case CALC_AS:
168            if((type[sp-1]&FLAG_CAST)==0){
169                //型名が指定されていないときはエラー
170                compiler.errorMessenger.Output(47,NULL,cp);
171                return 0;
172            }
173            break;
174
175        case CALC_BYVAL:
176            if(type[sp-1]&FLAG_CAST){
177                //型名が指定されていないときはエラー
178                compiler.errorMessenger.Output(47,NULL,cp);
179                return 0;
180            }
181            break;
182
183        case CALC_MINUSMARK:
184            //As以外の演算子に型名が指定されていないかをチェック
185            if(type[sp-1]&FLAG_CAST){
186                compiler.errorMessenger.Output(48,temporary,cp);
187                return 0;
188            }
189            break;
190    }
191    return 1;
192}
193
194int GetReturnType_OperatorProc(int idCalc,const Type &baseType,int *type_stack,LONG_PTR *index_stack,int &sp){
195    Type leftType( type_stack[sp-2], index_stack[sp-2] );
196    Type rightType( type_stack[sp-1] & (~FLAG_CAST), index_stack[sp-1] );
197
198    //オーバーロードされたオペレータ関数を呼び出す
199    const CClass *pobj_c = &leftType.GetClass();
200
201    std::vector<const UserProc *> subs;
202    pobj_c->GetDynamicMethods().Enum( idCalc, subs );
203    if( subs.size() == 0 ){
204        return 0;
205    }
206
207
208    //項の数
209    BOOL bTwoTerm=1;
210    if(idCalc==CALC_AS) bTwoTerm=0;
211
212
213
214    /////////////////////////////////////////////
215    // オーバーロード解決用のパラメータを設定
216    /////////////////////////////////////////////
217
218
219    //_System_LocalThis
220    Parameters params;
221
222    if(bTwoTerm){
223        params.push_back( new Parameter( "", rightType ) );
224    }
225
226
227    //オーバーロードを解決
228    char temporary[255];
229    if(idCalc==CALC_EQUAL) lstrcpy(temporary,"==");
230    else GetCalcName(idCalc,temporary);
231    const UserProc *pUserProc = OverloadSolution( temporary, subs, params, baseType, leftType );
232
233    if(bTwoTerm){
234        delete params[0];
235    }
236
237    if(!pUserProc){
238        return 0;
239    }
240    else{
241        //オーバーロードされていないが、パラメータ個数が一致しないとき
242        if(params.size()!=pUserProc->Params().size()){
243            return 0;
244        }
245    }
246
247    sp--;
248    type_stack[sp-1]=pUserProc->ReturnType().GetBasicType();
249    index_stack[sp-1]=pUserProc->ReturnType().GetIndex();
250
251    return 1;
252}
253
254bool Operator_New_GetType(const char *Parameter,const Type &baseType, Type &resultType ){
255    char TypeName[VN_SIZE],objectSizeStr[VN_SIZE];
256    int i,i2;
257
258    i=0;
259
260    if(Parameter[0]=='['){
261        i=GetStringInBracket(objectSizeStr,Parameter);
262
263        SlideString(objectSizeStr+1,-1);
264        objectSizeStr[i-2]=0;
265    }
266    else objectSizeStr[0]=0;
267
268    for(i2=0;;i++,i2++){
269        if(Parameter[i]=='(' || Parameter[i]=='['){
270            TypeName[i2]=0;
271            break;
272        }
273        TypeName[i2]=Parameter[i];
274        if(Parameter[i]=='\0'){
275            break;
276        }
277    }
278
279    if( !compiler.StringToType( TypeName, resultType ) )
280    {
281        compiler.errorMessenger.Output(3,TypeName,cp);
282        return false;
283    }
284
285    if( !resultType.IsObject() )
286    {
287        compiler.errorMessenger.Output(121,NULL,cp);
288        return false;
289    }
290
291    if( baseType.IsObject() ){
292        resultType.SetBasicType( DEF_OBJECT );
293    }
294    else{
295        resultType.SetBasicType( DEF_PTR_OBJECT );
296    }
297    return true;
298}
299
300bool GetMemberTermType( const Type &leftType, const Type &baseType, Type &resultType, const char *termFull, const char *termLeft, const char *member, bool *pIsVariable )
301{
302    ////////////////////////////////
303    // インデクサ(getアクセサ)
304    ////////////////////////////////
305
306    char VarName[VN_SIZE],ArrayElements[VN_SIZE];
307    GetArrayElement(member,VarName,ArrayElements);
308    if(ArrayElements[0]){
309        Type classType;
310        if( VarName[0] == '\0' )
311        {
312            classType = leftType;
313
314            if( classType.IsObject() )
315            {
316                // 既にuseRegにオブジェクトポインタが格納されており、それに対するインデクサを呼び出す場合
317                // ※「プロパティ値として返ってきたオブジェクトインスタンスのインデクサを呼び出す」場合にここにくる
318            }
319        }
320        else
321        {
322            GetMemberType( leftType, VarName, classType, 0, false );
323        }
324
325        if( classType.IsObject() )
326        {
327            if( !GetReturnTypeOfIndexerGetterProc( classType, resultType ) ){
328                compiler.errorMessenger.Output(1,NULL,cp);
329                return false;
330            }
331
332            return true;
333        }
334    }
335
336
337    ///////////////////////////////////////////////////////////////////
338    // メンバを検索
339    ///////////////////////////////////////////////////////////////////
340    if( GetMemberType( leftType, member, resultType, 0, false ) ){
341        // メンバが見つかったとき
342
343        if( pIsVariable )
344        {
345            *pIsVariable = true;
346        }
347
348        return true;
349    }
350
351
352    ///////////////////////////////////////////////////////////////////
353    // 動的メソッドを検索
354    ///////////////////////////////////////////////////////////////////
355    char methodName[VN_SIZE] ,lpPtrOffset[VN_SIZE], dummy[1];
356    char parameter[VN_SIZE];
357    ReferenceKind refType;
358    PareOrBracket pareOrBracket = None;
359    lstrcpy( methodName, member );
360    GetVarFormatString( methodName, parameter, lpPtrOffset, dummy, refType, &pareOrBracket );
361
362    std::vector<const UserProc *> userProcs;
363    leftType.GetClass().EnumDynamicMethodsOrInterfaceMethods( methodName, userProcs );
364    if(userProcs.size()){
365        //オーバーロードを解決
366        const UserProc *pUserProc = OverloadSolutionWithStrParam(termFull,userProcs,parameter,termLeft);
367
368        if( pUserProc )
369        {
370            if(
371                pUserProc->Params().size() == 0             // 仮引数の個数は0
372                && parameter[0]                             // 実引数は1つ以上
373                && pUserProc->ReturnType().IsObject()       // 戻り値がクラス型の場合
374                && pareOrBracket == Bracket )               // 実引数は[]で囲まれている
375            {
376                // プロパティ値として返ってきたオブジェクトインスタンスのインデクサを呼び出す
377
378                // まずはプロパティ値を取得
379                bool dummyIsVariable;
380                GetMemberTermType( leftType, baseType, resultType, termFull, termLeft, methodName, &dummyIsVariable );
381
382                // 戻り値のオブジェクトインスタンスのインデクサを呼び出す
383                char temporary[VN_SIZE], temp2[VN_SIZE];
384                sprintf( temporary, "[%s]", parameter );
385                sprintf( temp2, "%s.%s", termLeft, methodName );
386                Type classType = resultType;
387                return GetMemberTermType( classType, baseType, resultType, termFull, temp2, temporary, pIsVariable );
388            }
389
390            resultType = pUserProc->ReturnType();
391
392            // 型パラメータを解決
393            ResolveFormalGenericTypeParameter( resultType, leftType, pUserProc );
394
395            return true;
396        }
397    }
398
399    return false;
400}
401
402bool GetTermType( const char *term, const Type &baseType, Type &resultType, bool &isLiteral, bool *pIsClassName, bool *pIsVariable )
403{
404    char parameter[VN_SIZE];
405
406    // Withを解決
407    char termFull[VN_SIZE];
408    if(term[0]=='.'){
409        GetWithName(termFull);
410        lstrcat(termFull,term);
411    }
412    else lstrcpy(termFull,term);
413
414    char termLeft[VN_SIZE];
415    lstrcpy(termLeft,termFull);
416
417    // パース
418    char member[VN_SIZE];
419    ReferenceKind refType;
420    if( SplitMemberName( termFull, termLeft, member, refType ) ){
421        ///////////////////////////////////////////////////////////////////
422        // オブジェクトとメンバに分解できるとき
423        // termLeft.member
424        ///////////////////////////////////////////////////////////////////
425
426        isLiteral = false;
427
428        // オブジェクト側の型を取得
429        bool isClassName = false;
430        Type leftType;
431        if( GetTermType( termLeft, Type(), leftType, isLiteral, &isClassName ) ){
432            if( isClassName == false && compiler.GetObjectModule().meta.GetBlittableTypes().IsExist( leftType ) ){
433                // 左側のオブジェクト部分がBlittable型のとき
434
435                char temporary[VN_SIZE];
436                lstrcpy( temporary, termLeft );
437                sprintf( termLeft, "%s(%s)",
438                    compiler.GetObjectModule().meta.GetBlittableTypes().Find( leftType ).GetCreateStaticMethodFullName().c_str(),
439                    temporary );
440
441                if( !GetTermType( termLeft, Type(), leftType, isLiteral, &isClassName ) ){
442                    goto globalArea;
443                }
444            }
445        }
446        else{
447            goto globalArea;
448        }
449
450        if( isClassName ){
451            // 静的メンバ/メソッドの場合
452            goto globalArea;
453        }
454
455        if( !leftType.HasMember() ){
456            // メンバを持たない型の場合
457            return false;
458        }
459
460        return GetMemberTermType( leftType, baseType, resultType, termFull, termLeft, member, pIsVariable );
461    }
462
463
464    //////////////////////////////////////////////
465    // クラス名かどうかをチェック(静的メンバ用)
466    //////////////////////////////////////////////
467
468    if( pIsClassName ){
469        if( compiler.GetObjectModule().meta.GetClasses().Find( termFull ) ){
470            *pIsClassName = true;
471            return true;
472        }
473    }
474
475
476    /////////////////////////////////////////////////////////////////
477    // グローバル属性
478    /////////////////////////////////////////////////////////////////
479globalArea:
480
481
482    if(lstrcmpi(termFull,"This")==0)
483    {
484        if( !compiler.IsCompilingClass() )
485        {
486            return false;
487        }
488
489        //Thisオブジェクト
490        resultType.SetType( DEF_OBJECT, &compiler.GetCompilingClass() );
491        isLiteral = false;
492        return true;
493    }
494
495
496    //////////////////////////////////////
497    // 関数(DLL、ユーザー定義、組み込み)
498    //////////////////////////////////////
499    char procName[VN_SIZE];
500    char temporary[8192];
501
502    int i2=GetCallProcName(termFull,procName);
503    if(termFull[i2]=='('){
504        int i4=GetStringInPare_RemovePare(parameter,termFull+i2+1);
505
506        void *pProc;
507        int idProc=GetProc(procName,(void **)&pProc);
508
509        if(idProc){
510            //閉じカッコ")"に続く文字がNULLでないとき
511            if(termFull[i2+1+i4+1]!='\0'){
512                compiler.errorMessenger.Output(42,NULL,cp);
513            }
514
515
516            ////////////////
517            // 呼び出し
518            ////////////////
519
520            if( !CallProc(idProc,pProc,procName,parameter, baseType, resultType, false ) ){
521                return false;
522            }
523            if( resultType.IsNull() ){
524                //戻り値が存在しないとき
525                return false;
526            }
527
528            isLiteral = false;
529
530            return true;
531        }
532        else
533        {
534            ConstMacro *pConstMacro = compiler.GetObjectModule().meta.GetGlobalConstMacros().Find( procName );
535            if( pConstMacro )
536            {
537                if( pConstMacro->GetCalcBuffer( parameter, temporary ) )
538                {
539                    /////////////////////////
540                    // マクロ関数
541                    /////////////////////////
542
543                    //閉じカッコ")"に続く文字がNULLでないときはエラーにする
544                    if(termFull[i2+1+i4+1]!='\0') compiler.errorMessenger.Output(42,NULL,cp);
545
546                    //マクロ関数の場合
547                    if( !NumOpe_GetType(temporary,Type(),resultType) ){
548                        return false;
549                    }
550
551                    if( !IS_LITERAL( resultType.GetIndex() ) ){
552                        //リテラル値ではなかったとき
553                        isLiteral = false;
554                    }
555
556                    return true;
557                }
558            }
559        }
560    }
561
562
563    ////////////////////////////////
564    // インデクサ(getアクセサ)
565    ////////////////////////////////
566
567    char VarName[VN_SIZE],ArrayElements[VN_SIZE];
568    GetArrayElement(termFull,VarName,ArrayElements);
569    if(ArrayElements[0]){
570        Type classType;
571        GetVarType(VarName,classType,false);
572        if( classType.IsObject() ){
573            if( !GetReturnTypeOfIndexerGetterProc( classType, resultType ) ){
574                compiler.errorMessenger.Output(1,NULL,cp);
575                return false;
576            }
577
578            isLiteral = false;
579
580            return true;
581        }
582    }
583
584
585    ////////////////////////////////
586    // 変数
587    ////////////////////////////////
588
589    if( GetVarType( termFull, resultType, false ) ){
590        if( resultType.GetBasicType() & FLAG_PTR ){
591            //配列ポインタ
592            resultType.SetBasicType( GetPtrType( resultType.GetBasicType()^FLAG_PTR ) );
593        }
594
595        isLiteral = false;
596
597        if( pIsVariable )
598        {
599            // 変数である
600            *pIsVariable = true;
601        }
602
603        return true;
604    }
605
606
607    /////////////////////////////////
608    // プロパティ用のメソッド
609    /////////////////////////////////
610
611    //配列要素を排除
612    GetArrayElement(termFull,VarName,ArrayElements);
613
614    if(GetSubHash(VarName,0)){
615        GetReturnTypeOfPropertyMethod(termFull,NULL,resultType);
616
617        isLiteral = false;
618
619        return true;
620    }
621
622
623    return false;
624}
625
626bool GetTermType( const char *term, Type &resultType )
627{
628    bool isLiteral;
629    return GetTermType( term, Type(), resultType, isLiteral );
630}
631
632bool GetTermTypeOnlyVariable( const char *term, Type &resultType )
633{
634    bool isLiteral, isVariable = false;
635    bool result = GetTermType( term, Type(), resultType, isLiteral, NULL, &isVariable );
636    return ( result && isVariable );
637}
638
639bool NumOpe_GetType( const char *expression, const Type &baseType, Type &resultType, bool *pIsLiteralCalculation ){
640    extern int cp;
641    int i,i3;
642
643    //リテラル値のみの計算かどうかを判別するためのフラグ
644    bool dummyBool;
645    if( pIsLiteralCalculation == NULL )
646    {
647        pIsLiteralCalculation = &dummyBool;
648    }
649    *pIsLiteralCalculation = true;
650
651    if(expression[0]=='\0'){
652        compiler.errorMessenger.Output(1,NULL,cp);
653        return false;
654    }
655
656    if(expression[0]==1&& ( expression[1]==ESC_NEW || expression[1] == ESC_SYSTEM_STATIC_NEW ) ){
657        //New演算子(オブジェクト生成)
658        *pIsLiteralCalculation = false;
659        return Operator_New_GetType(expression+2,baseType, resultType );
660    }
661
662    if( expression[0] == '[' ){
663        if( !baseType.IsPointer() ){
664            return false;
665        }
666
667        resultType = baseType;
668        return true;
669    }
670
671
672    /////////////////////////////////
673    // 式要素を逆ポーランド式で取得
674    /////////////////////////////////
675
676    char *values[255];
677    long calc[255];
678    long stack[255];
679    int pnum;
680    if(!GetNumOpeElements(expression,&pnum,values,calc,stack)){
681        for(i=0;i<pnum;i++){
682            if(values[i]) HeapDefaultFree(values[i]);
683        }
684        return false;
685    }
686
687
688
689    ////////////////////////////////
690    // 演算部分のコード生成を開始
691    ////////////////////////////////
692
693    BOOL bError;
694    bError=0;
695
696    int sp;
697    int type_stack[255];
698    LONG_PTR index_stack[255];
699    bool isNothing_stack[255];
700    _int64 i64data;
701    int idCalc;
702    for(i=0,sp=0;i<pnum;i++){
703        idCalc=calc[i]%100;
704
705        if(idCalc){
706            if(type_stack[sp-2]==DEF_OBJECT){
707                if( idCalc == CALC_AS
708                    && type_stack[sp-1] == ( DEF_OBJECT | FLAG_CAST )
709                    && index_stack[sp-1] == index_stack[sp-2]
710                    || isNothing_stack[sp-2] ){
711                        // 同一の型、またはNothingに対するAsはAs演算子を呼び出さない
712                }
713                else if( idCalc == CALC_AS
714                    && type_stack[sp-1] == ( DEF_OBJECT | FLAG_CAST )
715                    && ( ((CClass *)index_stack[sp-1])->IsEqualsOrSubClass( (CClass *)index_stack[sp-2] ) || ((CClass *)index_stack[sp-2])->IsEqualsOrSubClass( (CClass *)index_stack[sp-1] )
716                    )){
717                        // ダウンキャストを許可する
718                }
719                else if( idCalc == CALC_AS ){
720                    // NumOpe_GetTypeではすべてのキャストを許可する
721                }
722                else{
723                    //オーバーロードされたオペレータを呼び出す
724                    if(!GetReturnType_OperatorProc(idCalc,baseType,type_stack,index_stack,sp)){
725                        goto error;
726                    }
727
728                    continue;
729                }
730            }
731
732            if(!CheckCalcType(idCalc,type_stack,sp)) goto error;
733        }
734
735        switch(idCalc){
736            //数値
737            case 0:
738                index_stack[sp]=-1;
739                isNothing_stack[sp] = false;
740
741                char *term;
742                term = values[i];
743
744                if( calc[i+1]%100 == CALC_AS ){
745                    // As演算子の右辺値
746                    //型名
747                    if( compiler.StringToType( term, resultType ) ){
748
749                        if( resultType.IsObject() ){
750                            if( resultType.GetClass().IsBlittableType() ){
751                                // Blittable型のときは基本型として扱う
752                                // ※ただし、コンパイル中のメソッドがBlittable型クラスに属していないこと
753                                if( compiler.IsLocalAreaCompiling()
754                                    && compiler.GetCompilingUserProc().HasParentClass()
755                                    && compiler.GetCompilingUserProc().GetParentClass().IsBlittableType() )
756                                {
757                                    // コンパイル中のメソッドがBlittable型クラスに属している
758                                }
759                                else{
760                                    resultType = resultType.GetClass().GetBlittableType();
761                                }
762                            }
763                        }
764
765                        resultType.SetBasicType( resultType.GetBasicType() | FLAG_CAST );
766                    }
767                    else{
768                        compiler.errorMessenger.Output(3, term, cp );
769                        goto error;
770                    }
771
772                    type_stack[sp] = resultType.GetBasicType();
773                    index_stack[sp] = resultType.GetIndex();
774                    sp++;
775
776                    break;
777                }
778
779                if(term[0]=='\"'){
780StrLiteral:
781
782                    if( !baseType.IsPointer() ){
783                        //要求タイプがオブジェクト、または未定のとき
784                        type_stack[sp]=DEF_OBJECT;
785                        index_stack[sp]=(LONG_PTR)compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr();
786                        *pIsLiteralCalculation = false;
787
788                        sp++;
789                        break;
790                    }
791
792                    type_stack[sp]=typeOfPtrChar;
793                    *pIsLiteralCalculation = false;
794                }
795                else if((term[0]=='e'||term[0]=='E')&&
796                    (term[1]=='x'||term[1]=='X')&&
797                    term[2]=='\"'){
798                    //拡張版リテラル文字列(エスケープシーケンス可能)
799                    goto StrLiteral;
800                }
801                else if(IsVariableTopChar(term[0])||
802                    term[0]=='*'||
803                    (term[0]=='.'&&IsVariableTopChar(term[1])))
804                {
805                    //////////////////
806                    // 何らかの識別子
807
808                    bool isLiteral = true;
809                    if( GetTermType( term, baseType, resultType, isLiteral ) ){
810                        type_stack[sp] = resultType.GetBasicType();
811                        index_stack[sp] = resultType.GetIndex();
812
813                        if( !isLiteral ){
814                            *pIsLiteralCalculation = false;
815                        }
816
817                        sp++;
818                        break;
819                    }
820
821
822                    // Nothing
823                    if( lstrcmp( term, "Nothing" ) == 0 ){
824                        isNothing_stack[sp] = true;
825
826                        type_stack[sp] = DEF_OBJECT;
827                        if( baseType.IsObject() ){
828                            index_stack[sp] = baseType.GetIndex();
829                        }
830                        else{
831                            index_stack[sp] = (LONG_PTR)compiler.GetObjectModule().meta.GetClasses().GetObjectClassPtr();
832                        }
833                        *pIsLiteralCalculation = false;
834                        sp++;
835                        break;
836                    }
837
838
839                    //////////////
840                    // 定数の場合
841                    //////////////
842
843                    i3 = compiler.GetObjectModule().meta.GetGlobalConsts().GetBasicType(term);
844                    if(i3){
845                        if( compiler.GetObjectModule().meta.GetGlobalConsts().IsStringPtr( term ) ){
846                            //リテラル文字列
847                            goto StrLiteral;
848                        }
849
850                        type_stack[sp]=i3;
851                        if(IsRealNumberType(i3)){
852                            //実数
853                            goto Literal;
854                        }
855                        else if(IsWholeNumberType(i3)){
856                            //整数
857                            goto Literal;
858                        }
859                        else if(Is64Type(i3)){
860                            //64ビット整数値
861                            goto Literal;
862                        }
863                        else{
864                            compiler.errorMessenger.Output(1,NULL,0);
865                            goto error;
866                        }
867                    }
868
869
870                    /////////////////////////////////
871                    // プロパティ用のメソッド
872                    /////////////////////////////////
873
874                    //配列要素を排除
875                    char VarName[VN_SIZE],ArrayElements[VN_SIZE];
876                    GetArrayElement(term,VarName,ArrayElements);
877
878                    if(GetSubHash(VarName,0)){
879                        compiler.errorMessenger.OutputFatalError();
880                        Type tempType;
881                        GetReturnTypeOfPropertyMethod(term,NULL,tempType);
882
883                        //大きな型への暗黙の変換
884                        type_stack[sp]=tempType.GetBasicType();
885
886                        index_stack[sp]=tempType.GetIndex();
887                        *pIsLiteralCalculation = false;
888
889                        sp++;
890                        break;
891                    }
892
893
894
895                    //該当する識別子が見当たらないときはエラー扱いにする
896                    bError=1;
897                    compiler.errorMessenger.Output(3,term,cp);
898                    type_stack[sp]=DEF_DOUBLE;
899                }
900                else{
901                    //リテラル値
902                    int base_type = 0;
903                    if( !baseType.IsNull() ) base_type = baseType.GetBasicType();
904                    type_stack[sp]=GetLiteralValue(term,&i64data,base_type);
905Literal:
906                    if((long)i64data==0&&index_stack[sp]==-1) index_stack[sp]=LITERAL_NULL;
907                }
908
909                sp++;
910                break;
911
912            //論理演算子
913            case CALC_XOR:
914            case CALC_OR:
915            case CALC_AND:
916                sp--;
917                type_stack[sp-1]=NeutralizationType(type_stack[sp-1],index_stack[sp-1],type_stack[sp],index_stack[sp]);
918                break;
919            case CALC_NOT:
920                //values[sp-1]=Not values[sp-1]
921                //NOT演算子
922                break;
923
924            //比較演算子
925            case CALC_PE:       //values[sp-2] <= values[sp-1]
926            case CALC_QE:       //values[sp-2] >= values[sp-1]
927            case CALC_P:        //values[sp-2] <  values[sp-1]
928            case CALC_Q:        //values[sp-2] >  values[sp-1]
929            case CALC_NOTEQUAL: //values[sp-2] <> values[sp-1]
930            case CALC_EQUAL:    //values[sp-2] =  values[sp-1] 
931                sp--;
932                type_stack[sp-1]=DEF_LONG;
933                break;
934
935            //ビットシフト
936            case CALC_SHL:  //values[sp-2] << values[sp-1]
937            case CALC_SHR:  //values[sp-2] >> values[sp-1]
938                sp--;
939                break;
940
941            //算術演算
942            case CALC_ADDITION:
943            case CALC_SUBTRACTION:
944            case CALC_PRODUCT:
945                sp--;
946                type_stack[sp-1]=NeutralizationType(type_stack[sp-1],index_stack[sp-1],type_stack[sp],index_stack[sp]);
947                break;
948            case CALC_MOD:
949                //values[sp-2]%=values[sp-1]
950                //剰余演算
951                sp--;
952                type_stack[sp-1]=NeutralizationType(type_stack[sp-1],index_stack[sp-1],type_stack[sp],index_stack[sp]);
953                break;
954            case CALC_QUOTIENT:
955                //values[sp-2]/=values[sp-1];
956                //除算
957                sp--;
958                type_stack[sp-1]=NeutralizationType(type_stack[sp-1],index_stack[sp-1],type_stack[sp],index_stack[sp]);
959                break;
960            case CALC_INTQUOTIENT:
961                //values[sp-2]/=values[sp-1]
962                //整数除算
963                sp--;
964                type_stack[sp-1]=NeutralizationType(type_stack[sp-1],index_stack[sp-1],type_stack[sp],index_stack[sp]);
965                break;
966            case CALC_MINUSMARK:
967                //values[sp-1]=-values[sp-1]
968                //符号反転
969                break;
970            case CALC_POWER:
971                //べき乗演算(浮動小数点演算のみ)
972                sp--;
973                //未完成
974                break;
975            case CALC_AS:
976                //キャスト
977                type_stack[sp-2]=type_stack[sp-1]&(~FLAG_CAST);
978                index_stack[sp-2]=index_stack[sp-1];
979
980                sp--;
981                break;
982
983            case CALC_BYVAL:
984                //ポインタ型→参照型
985                if( PTR_LEVEL( type_stack[sp-1] ) <= 0 ){
986                    //ポインタ型ではないとき
987                    compiler.errorMessenger.Output( 3, NULL, cp );
988                    goto error;
989                }
990
991                type_stack[sp-1] = PTR_LEVEL_DOWN( type_stack[sp-1] );
992                break;
993        }
994    }
995
996    if(bError) goto error;
997
998    if(sp!=1){
999        compiler.errorMessenger.Output(1,NULL,cp);
1000        goto error;
1001    }
1002
1003    if( *pIsLiteralCalculation ){
1004        //右辺値が数値の定数式の場合
1005        int base_type = 0;
1006        if( !baseType.IsNull() ) base_type = baseType.GetBasicType();
1007        Type tempType;
1008        StaticCalculation(true, expression,base_type,&i64data,tempType);
1009
1010        type_stack[0]=tempType.GetBasicType();
1011        index_stack[0]=tempType.GetIndex();
1012    }
1013    else{
1014        //右辺値が数値の定数式ではないとき
1015        if(IS_LITERAL(index_stack[0])) index_stack[0]=-1;
1016    }
1017
1018    resultType.SetType( type_stack[0], index_stack[0] );
1019
1020    bool isSuccessful = true;
1021    goto finish;
1022
1023
1024    //////////////////
1025    // エラー処理
1026    //////////////////
1027
1028error:
1029    isSuccessful = false;
1030    goto finish;
1031
1032
1033finish:
1034    for(i=0;i<pnum;i++){
1035        if(values[i]) HeapDefaultFree(values[i]);
1036    }
1037    return isSuccessful;
1038}
Note: See TracBrowser for help on using the repository browser.