source: dev/trunk/ab5.0/abdev/compiler_x86/NumOpe.cpp @ 673

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

・オーバーロード解決時、戻り値に型パラメータだった場合に型解決されずに、正しいオーバーロード解決が行われない不具合を修正。
・演算子メソッドの戻り値が型パラメータだったとき、型解決が行われない不具合を修正。

File size: 33.8 KB
Line 
1#include "stdafx.h"
2
3#include <Compiler.h>
4
5#include "../BasicCompiler_Common/common.h"
6#include "Opcode.h"
7
8using namespace ActiveBasic::Compiler;
9
10void PushReturnValue( const Type &type )
11{
12    //関数の戻り値をスタックへプッシュする
13    //※この処理内では、esi、ediは使用不可
14
15    if( type.IsObject() || type.IsStruct() )
16    {
17        //push eax
18        compiler.codeGenerator.op_push(REG_EAX);
19    }
20    else if( type.IsDouble() )
21    {
22        //sub esp,8
23        compiler.codeGenerator.op_sub_esp(8);
24
25        //fstp qword ptr[esp]
26        compiler.codeGenerator.op_fstp_basereg( DEF_DOUBLE, REG_ESP );
27    }
28    else if( type.IsSingle() )
29    {
30        //sub esp,4
31        compiler.codeGenerator.op_sub_esp(4);
32
33        //fstp dword ptr[esp]
34        compiler.codeGenerator.op_fstp_basereg( DEF_SINGLE, REG_ESP );
35    }
36    else if( type.Is64() )
37    {
38        //push edx
39        compiler.codeGenerator.op_push(REG_EDX);
40
41        //push eax
42        compiler.codeGenerator.op_push(REG_EAX);
43    }
44    else if( type.IsInteger() || ( compiler.IsUnicode() && type.GetBasicType() == DEF_CHAR ) )
45    {
46        //movsx ebx,ax
47        compiler.codeGenerator.op_movsx_R32R16( REG_EBX, REG_EAX );
48
49        //push ebx
50        compiler.codeGenerator.op_push(REG_EBX);
51    }
52    else if( type.IsSByte() || ( !compiler.IsUnicode() && type.GetBasicType() == DEF_CHAR ) )
53    {
54        //movsx ebx,al
55        compiler.codeGenerator.op_movsx_R32R8( REG_EBX, REG_EAX );
56
57        //push ebx
58        compiler.codeGenerator.op_push(REG_EBX);
59    }
60    else if( type.IsLong() || type.IsDWord() || type.IsWord() || type.IsByte() || type.IsBoolean() || type.IsPointer() )
61    {
62        //push eax
63        compiler.codeGenerator.op_push(REG_EAX);
64    }
65    else{
66        compiler.errorMessenger.OutputFatalError();
67    }
68}
69
70void NewStringObject( const char *str ){
71    ///////////////////////////////////////////////////////
72    // lpszTextを元にStringオブジェクトを生成し、
73    // オブジェクトポインタをregに格納する
74    ///////////////////////////////////////////////////////
75
76    char *parameter = (char *)malloc( lstrlen( str ) + 32 );
77    sprintf( parameter, "%s%c%c*Char", str, 1, ESC_AS );
78
79    Operator_New( *compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr(), "", parameter, Type( DEF_OBJECT, *compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr() ) );
80
81    free( parameter );
82}
83
84void ExtendRegToBigType( int reg, int bigBasicType, int baseBasicType ){
85    if( reg != REG_EAX ){
86        compiler.errorMessenger.OutputFatalError();
87    }
88    switch( Type::GetBasicSize( bigBasicType ) ){
89        case sizeof(_int64):
90            ExtendTypeTo64(baseBasicType);
91            break;
92        case sizeof(long):
93            ExtendTypeTo32(baseBasicType,reg);
94            break;
95        case sizeof(short):
96            ExtendTypeTo16(baseBasicType,reg);
97            break;
98    }
99}
100
101
102
103bool VarToReg( RELATIVE_VAR &relativeVar, const Type &baseType, Type &resultType ){
104    const int useReg = REG_EAX;
105
106    //大きな型への暗黙の変換
107    int bigType = AutoBigCast(baseType.GetBasicType(),resultType.GetBasicType());
108
109    if(resultType.GetBasicType()&FLAG_PTR){
110        //配列ポインタ
111        resultType.SetBasicType( GetPtrType(resultType.GetBasicType()^FLAG_PTR) );
112
113        SetVarPtrToReg(useReg, &relativeVar);
114    }
115    else if( resultType.IsStruct() ){
116        //構造体ポインタをeaxへ格納(構造体は値型)
117        SetVarPtrToReg(useReg, &relativeVar);
118    }
119    else if( resultType.IsReal() ){
120        // 実数
121        SetReg_RealVariable( resultType.GetBasicType(), &relativeVar );
122    }
123    else if( resultType.IsWhole() || resultType.IsObject()){
124        //整数型
125        SetReg_WholeVariable(resultType,&relativeVar,useReg);
126    }
127    else if( resultType.IsStruct() ){
128        //構造体ポインタをUseRegへ格納(構造体は値型)
129        SetVarPtrToReg(useReg,&relativeVar);
130    }
131    else{
132        return false;
133    }
134
135    if( resultType.GetBasicType() != bigType ){
136        // 大きな型へ変換された場合
137        // ※レジスタの値をキャストする
138        ExtendRegToBigType( useReg, bigType, resultType.GetBasicType() );
139
140        resultType.SetBasicType( bigType );
141    }
142
143    return true;
144}
145bool TermMemberOpe( const Type &leftType, bool &isNeedHeapFreeStructure, const Type &baseType, Type &resultType, const char *termFull, const char *termLeft, const char *member, bool &isVariable, RELATIVE_VAR &relativeVar )
146{
147    const CClass &objClass = leftType.GetClass();
148
149    const int useReg = REG_EAX;
150
151
152    ////////////////////////////////
153    // インデクサ(getアクセサ)
154    ////////////////////////////////
155    char VarName[VN_SIZE],ArrayElements[VN_SIZE];
156    GetArrayElement(member,VarName,ArrayElements);
157    if(ArrayElements[0]){
158        Type classType;
159        if( VarName[0] == '\0' )
160        {
161            classType = leftType;
162
163            if( classType.IsObject() )
164            {
165                // 既にuseRegにオブジェクトポインタが格納されており、それに対するインデクサを呼び出す場合
166                // ※「プロパティ値として返ってきたオブジェクトインスタンスのインデクサを呼び出す」場合にここにくる
167
168                //オブジェクトポインタをスタックに入れておく
169                //push useReg
170                compiler.codeGenerator.op_push( useReg );
171            }
172        }
173        else
174        {
175            GetMemberType( leftType, VarName, classType, 0, false );
176
177            if( classType.IsObject() )
178            {
179                // クラス型のメンバに対するインデクサを呼び出す場合
180
181                //オブジェクトポインタをecxにコピー
182                compiler.codeGenerator.op_mov_RR( REG_ECX, useReg );
183
184                RELATIVE_VAR tempRelativeVar;
185                tempRelativeVar.dwKind=VAR_DIRECTMEM;
186
187                if( !_member_offset(
188                    true,   //エラー表示あり
189                    false,  //読み込み専用
190                    leftType,
191                    VarName,&tempRelativeVar,classType,0)){
192                        return false;
193                }
194
195                // オブジェクトメンバのポインタをeaxにコピー
196                if( !VarToReg( tempRelativeVar, baseType, resultType ) ){
197                    compiler.errorMessenger.Output(11,termFull,cp);
198                }
199
200
201                //オブジェクトポインタをスタックに入れておく
202                //push eax
203                compiler.codeGenerator.op_push( REG_EAX );
204            }
205        }
206
207        if( classType.IsObject() )
208        {
209            char objectFullName[VN_SIZE], dummyArrayElements[VN_SIZE];
210            GetArrayElement(termFull,objectFullName,dummyArrayElements);
211
212            CallIndexerGetterProc(/*UseReg,*/classType,objectFullName, ArrayElements,resultType, PROCFLAG_NEW );
213
214            compiler.codeGenerator.op_pop();
215
216            return true;
217        }
218    }
219
220
221    ///////////////////////////////////////////////////////////////////
222    // メンバを検索
223    ///////////////////////////////////////////////////////////////////
224    if( GetMemberType( leftType, member, resultType, 0, false ) ){
225        // メンバが見つかったとき
226
227        if( isNeedHeapFreeStructure )
228        {
229            if( !leftType.IsStruct() )
230            {
231                compiler.errorMessenger.OutputFatalError();
232            }
233
234            // 親となる構造体が一時メモリに存在していた場合、後ほど解放する必要がある
235            compiler.codeGenerator.op_AddNeedFreeTempStructure( useReg );
236            isNeedHeapFreeStructure = false;
237        }
238
239        //オブジェクトポインタをecxにコピー
240        compiler.codeGenerator.op_mov_RR( REG_ECX, useReg );
241
242        relativeVar.dwKind=VAR_DIRECTMEM;
243
244        if( !_member_offset(
245            true,   //エラー表示あり
246            false,  //読み込み専用
247            leftType,
248            member,&relativeVar,resultType,0)){
249                return false;
250        }
251
252        // 変数として扱う
253        isVariable = true;
254
255        return true;
256    }
257
258
259    ///////////////////////////////////////////////////////////////////
260    // 動的メソッドを検索
261    ///////////////////////////////////////////////////////////////////
262    std::vector<const UserProc *> userProcs;
263
264    char methodName[VN_SIZE], lpPtrOffset[VN_SIZE], parameter[VN_SIZE], dummy[1];
265    ReferenceKind refType;
266    PareOrBracket pareOrBracket = None;
267    lstrcpy( methodName, member );
268    GetVarFormatString( methodName, parameter, lpPtrOffset, dummy, refType, &pareOrBracket );
269
270    objClass.EnumDynamicMethodsOrInterfaceMethods( methodName, userProcs );
271    if(userProcs.size()){
272        //オーバーロードを解決
273        const UserProc *pUserProc = OverloadSolutionWithStrParam(termFull,userProcs,parameter,termLeft);
274
275        if( pUserProc )
276        {
277            if(
278                pUserProc->Params().size() == 0             // 仮引数の個数は0
279                && parameter[0]                             // 実引数は1つ以上
280                && pUserProc->ReturnType().IsObject()       // 戻り値がクラス型の場合
281                && pareOrBracket == Bracket )               // 実引数は[]で囲まれている
282            {
283                // プロパティ値として返ってきたオブジェクトインスタンスのインデクサを呼び出す
284
285                // まずはプロパティ値を取得
286                bool dummyIsVariable;
287                RELATIVE_VAR dummyRelativeVar;
288                TermMemberOpe( leftType, isNeedHeapFreeStructure, baseType, resultType, termFull, termLeft, methodName, dummyIsVariable, dummyRelativeVar );
289
290                // 戻り値のオブジェクトインスタンスのインデクサを呼び出す
291                char temporary[VN_SIZE], temp2[VN_SIZE];
292                sprintf( temporary, "[%s]", parameter );
293                sprintf( temp2, "%s.%s", termLeft, methodName );
294                Type classType = resultType;
295                return TermMemberOpe( classType, isNeedHeapFreeStructure, baseType, resultType, termFull, temp2, temporary, isVariable, relativeVar );
296            }
297
298            resultType = pUserProc->ReturnType();
299
300            {
301                //オブジェクトポインタをスタックに入れておく
302                //push reg
303                compiler.codeGenerator.op_push( useReg );
304
305                if( !Opcode_CallProc(parameter,pUserProc,PROCFLAG_NEW,termLeft) ){
306
307                    return false;
308                }
309
310                compiler.codeGenerator.op_pop();
311
312                /////////////////////
313                // 戻り値の処理
314                /////////////////////
315
316                //大きな型への暗黙の変換
317                int bigType = AutoBigCast(baseType.GetBasicType(), resultType.GetBasicType() );
318
319                if( resultType.GetBasicType() != bigType ){
320                    // 大きな型へ変換された場合
321                    // ※レジスタの値をキャストする
322                    ExtendRegToBigType( REG_EAX, bigType, resultType.GetBasicType() );
323
324                    resultType.SetBasicType( bigType );
325                }
326
327                //SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg);
328
329                // 型パラメータを解決
330                ResolveFormalGenericTypeParameter( resultType, leftType, pUserProc );
331            }
332           
333            return true;
334        }
335    }
336    else if( pareOrBracket == Pare )
337    {
338        // 関数ポインタ
339        compiler.errorMessenger.OutputFatalError();
340
341        ///////////////////////////////////////////////////////////////////
342        // メンバを検索
343        ///////////////////////////////////////////////////////////////////
344        if( GetMemberType( leftType, methodName, resultType, 0, false ) ){
345            // メンバが見つかったとき
346        }
347    }
348
349    compiler.errorMessenger.OutputFatalError();
350
351    return false;
352}
353bool _TermOpe( const char *term, const Type &baseType, Type &resultType, bool &isLiteral, bool &isNeedHeapFreeStructure, bool *pIsClassName, bool isProcedureCallOnly, bool &isVariable, RELATIVE_VAR &relativeVar, bool isWriteAccess )
354{
355    char parameter[VN_SIZE];
356
357    // Withを解決
358    char termFull[VN_SIZE];
359    if(term[0]=='.'){
360        GetWithName(termFull);
361        lstrcat(termFull,term);
362    }
363    else lstrcpy(termFull,term);
364
365    char termLeft[VN_SIZE];
366    lstrcpy(termLeft,termFull);
367
368    // パース
369    char member[VN_SIZE];
370    ReferenceKind refType;
371    if( SplitMemberName( termFull, termLeft, member, refType ) ){
372        ///////////////////////////////////////////////////////////////////
373        // オブジェクトとメンバに分解できるとき
374        // termLeft.member
375        ///////////////////////////////////////////////////////////////////
376
377        isLiteral = false;
378
379        // オブジェクト側の型を取得
380        bool isClassName = false;
381        Type leftType;
382        if( GetTermType( termLeft, Type(), leftType, isLiteral, &isClassName ) ){
383            if( isClassName == false && compiler.GetObjectModule().meta.GetBlittableTypes().IsExist( leftType ) ){
384                // 左側のオブジェクト部分がBlittable型のとき
385
386                char temporary[VN_SIZE];
387                lstrcpy( temporary, termLeft );
388                sprintf( termLeft, "%s(%s)",
389                    compiler.GetObjectModule().meta.GetBlittableTypes().Find( leftType ).GetCreateStaticMethodFullName().c_str(),
390                    temporary );
391            }
392        }
393
394        if( !TermOpe( termLeft, baseType, leftType, isLiteral, isNeedHeapFreeStructure, &isClassName ) ){
395            goto globalArea;
396        }
397
398        if( isClassName ){
399            // 静的メンバ/メソッドの場合
400            goto globalArea;
401        }
402
403        if( !leftType.HasMember() ){
404            // メンバを持たない型の場合
405            if( isProcedureCallOnly )
406            {
407                compiler.errorMessenger.Output(1,NULL,cp);
408            }
409            return false;
410        }
411
412        return TermMemberOpe( leftType, isNeedHeapFreeStructure, baseType, resultType, termFull, termLeft, member, isVariable, relativeVar );
413    }
414globalArea:
415
416
417    //////////////////////////////////////////////
418    // クラス名かどうかをチェック(静的メンバ用)
419    //////////////////////////////////////////////
420
421    if( pIsClassName ){
422        if( compiler.GetObjectModule().meta.FindClassSupportedTypeDef( LexicalAnalyzer::FullNameToSymbol( termFull ) ) ){
423            *pIsClassName = true;
424            return true;
425        }
426    }
427
428
429    /////////////////////////////////////////////////////////////////
430    // グローバル属性エリア
431    /////////////////////////////////////////////////////////////////
432
433    const int useReg = REG_EAX;
434
435
436    if(lstrcmpi(termFull,"This")==0 && isProcedureCallOnly == false ){
437        if( !compiler.IsCompilingClass() )
438        {
439            compiler.errorMessenger.Output(142,NULL,cp);
440            return false;
441        }
442
443        //Thisオブジェクト
444        resultType.SetType( DEF_OBJECT, &compiler.GetCompilingClass() );
445
446        SetThisPtrToReg( useReg );
447
448        isLiteral = false;
449
450        return true;
451    }
452
453
454    //////////////////////////////////////
455    // 関数(DLL、ユーザー定義、組み込み)
456    //////////////////////////////////////
457    char procName[VN_SIZE];
458    char temporary[8192];
459
460    int i2=GetCallProcName(termFull,procName);
461    if(termFull[i2]=='('){
462        int i4=GetStringInPare_RemovePare(parameter,termFull+i2+1);
463
464        void *pInfo;
465        int idProc=GetProc(procName,(void **)&pInfo);
466
467        if(idProc)
468        {
469            if(termFull[i2+1+i4+1]!='\0')
470            {
471                //閉じカッコ")"に続く文字がNULLでないとき
472                compiler.errorMessenger.Output(42,NULL,cp);
473            }
474
475
476            {
477                ////////////////
478                // 呼び出し
479                ////////////////
480
481                CallProc(idProc,pInfo,procName,parameter, baseType,resultType);
482
483
484                /////////////////////
485                // 戻り値の処理
486                /////////////////////
487
488                //大きな型への暗黙の変換
489                int bigType = AutoBigCast(baseType.GetBasicType(), resultType.GetBasicType() );
490
491                /*
492                ※後でNumOpe内でプッシュする
493                //スタックへプッシュ
494                PushReturnValue( resultType.GetBasicType() );
495                */
496
497                if( resultType.GetBasicType() != bigType ){
498                    // 大きな型へ変換された場合
499                    // ※レジスタの値をキャストする
500                    ExtendRegToBigType( useReg, bigType, resultType.GetBasicType() );
501
502                    resultType.SetBasicType( bigType );
503                }
504
505                //SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg);
506            }
507
508
509            if(resultType.IsStruct())
510            {
511                //構造体が戻ったときはヒープ領域にインスタンスが格納されている
512                //※後にfreeする必要あり
513                // TODO: 解放はGCに任せる
514                isNeedHeapFreeStructure = true;
515            }
516
517            isLiteral = false;
518
519            return true;
520        }
521
522        ConstMacro *pConstMacro = compiler.GetObjectModule().meta.GetGlobalConstMacros().Find(
523            ActiveBasic::Compiler::LexicalAnalyzer::FullNameToSymbol( procName )
524        );
525        if( pConstMacro )
526        {
527            if( ActiveBasic::Compiler::LexicalAnalyzer::ConstMacroToExpression( *pConstMacro, parameter, temporary ) )
528            {
529                /////////////////////////
530                // マクロ関数
531                /////////////////////////
532
533                //閉じカッコ")"に続く文字がNULLでないときはエラーにする
534                if(termFull[i2+1+i4+1]!='\0') compiler.errorMessenger.Output(42,NULL,cp);
535
536                //マクロ関数の場合
537                NumOpe(useReg, temporary,Type(),resultType);
538
539                if(!IS_LITERAL(resultType.GetIndex())){
540                    //リテラル値ではなかったとき
541                    isLiteral = false;
542                }
543
544                return true;
545            }
546        }
547    }
548    else if( isProcedureCallOnly ){
549        // 関数呼び出し以外は受け付けない
550        return false;
551    }
552
553
554    ////////////////////////////////
555    // インデクサ(getアクセサ)
556    ////////////////////////////////
557
558    char VarName[VN_SIZE],ArrayElements[VN_SIZE];
559    GetArrayElement(termFull,VarName,ArrayElements);
560    if(ArrayElements[0]){
561        Type classType;
562        GetVarType(VarName,classType,false);
563        if( classType.IsObject() )
564        {
565            CallIndexerGetterProc(/*UseReg,*/classType,VarName, ArrayElements,resultType);
566
567            isLiteral = false;
568
569            return true;
570        }
571    }
572
573
574    ////////////////////////////////
575    // 変数
576    ////////////////////////////////
577
578    if(GetVarOffset(
579        false,  //エラー表示なし
580        isWriteAccess,
581        termFull,
582        &relativeVar,resultType)){
583        //////////
584        // 変数
585        //////////
586
587        // 変数として扱う
588        isVariable = true;
589
590        isLiteral = false;
591
592        return true;
593    }
594
595
596    /////////////////////////////////
597    // プロパティ用のメソッド
598    /////////////////////////////////
599
600    //配列要素を排除
601    GetArrayElement(termFull,VarName,ArrayElements);
602
603    if(GetSubHash(VarName,0)){
604
605        {
606            CallPropertyMethod(termFull,NULL,resultType);
607
608            //大きな型への暗黙の変換
609            int bigType = AutoBigCast(baseType.GetBasicType(), resultType.GetBasicType() );
610
611            if( resultType.GetBasicType() != bigType ){
612                // 大きな型へ変換された場合
613                // ※レジスタの値をキャストする
614                ExtendRegToBigType( REG_EAX, bigType, resultType.GetBasicType() );
615
616                resultType.SetBasicType( bigType );
617            }
618
619            //SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg);
620        }
621
622
623        if(resultType.IsStruct())
624        {
625            //構造体が戻ったときはヒープ領域にインスタンスが格納されている
626            //※後にfreeする必要あり
627            // TODO: 解放はGCに任せる
628            isNeedHeapFreeStructure = true;
629        }
630
631        isLiteral = false;
632
633        return true;
634    }
635
636    if( isProcedureCallOnly )
637    {
638        compiler.errorMessenger.Output(3, termFull, cp );
639    }
640
641    return false;
642}
643
644bool TermOpe( const char *term, const Type &baseType, Type &resultType, bool &isLiteral, bool &isNeedHeapFreeStructure, bool *pIsClassName, bool isProcedureCallOnly, bool isWriteAccess )
645{
646    RELATIVE_VAR relativeVar;
647    bool isVariable = false;
648    bool result = _TermOpe( term, baseType, resultType, isLiteral, isNeedHeapFreeStructure, pIsClassName, isProcedureCallOnly, isVariable, relativeVar, isWriteAccess );
649
650    if( isVariable )
651    {
652        // 変数の場合はeaxに変数ポインタを格納する
653        if( !VarToReg( relativeVar, baseType, resultType ) ){
654            compiler.errorMessenger.Output(11,term,cp);
655        }
656    }
657
658    return result;
659}
660bool TermOpeOnlyVariable( const char *term, Type &resultType, RELATIVE_VAR &relativeVar, bool isWriteAccess )
661{
662    bool isLiteral, isVariable = false, isNeedHeapFreeStructure = false;
663    bool result = _TermOpe( term, Type(), resultType, isLiteral, isNeedHeapFreeStructure, NULL, false, isVariable, relativeVar, isWriteAccess );
664
665    if( !isVariable )
666    {
667        compiler.errorMessenger.OutputFatalError();
668    }
669
670    return result;
671}
672
673
674bool NumOpe( int reg,
675            const char *expression,
676            const Type &baseType,
677            Type &resultType,
678            bool *pbIsNeedHeapFreeStructure ){
679
680    if( !NumOpe( expression, baseType, resultType, pbIsNeedHeapFreeStructure ) )
681    {
682        return false;
683    }
684
685    if( reg != REG_EAX ){
686        // TODO: 未実装
687        compiler.errorMessenger.OutputFatalError();
688    }
689
690    if( resultType.IsReal() ){
691        //fld ptr[esp]
692        compiler.codeGenerator.op_fld_ptr_esp( resultType.GetBasicType() );
693
694        //add esp,size
695        compiler.codeGenerator.op_add_esp( resultType.GetBasicSize() );
696    }
697    else{
698        //pop eax
699        compiler.codeGenerator.op_pop(REG_EAX);
700
701        if( resultType.Is64() ){
702            //pop edx
703            compiler.codeGenerator.op_pop(REG_EDX);
704        }
705    }
706    return true;
707}
708bool NumOpe( const char *expression,
709            const Type &baseType,
710            Type &resultType,
711            bool *pbIsNeedHeapFreeStructure )
712{
713    int i,i2,i3;
714    char temporary[1024],temp2[1024];
715
716    if(expression[0]=='\0'){
717        compiler.errorMessenger.Output(1,NULL,cp);
718        return false;
719    }
720
721    if( !baseType.IsNull() && expression[0] == '[' ){
722        // リテラル配列の場合
723
724        int dataTableOffset;
725        if( !ActiveBasic::Compiler::DataTableGenerator::MakeLiteralArrayBuffer( compiler.GetObjectModule().dataTable, expression, baseType, dataTableOffset ) )
726        {
727            return false;
728        }
729
730        //mov eax,i2
731        compiler.codeGenerator.op_mov_RV(REG_EAX,dataTableOffset, Schedule::DataTable );
732
733        resultType = baseType;
734
735        //push eax
736        compiler.codeGenerator.op_push( REG_EAX );
737
738        return true;
739    }
740
741    bool isLiteralCalculation;
742    if( NumOpe_GetType( expression, baseType, resultType, &isLiteralCalculation ) )
743    {
744        if( isLiteralCalculation )
745        {
746            //右辺値が数値の定数式の場合
747            _int64 i64data;
748            StaticCalculation(true, expression,baseType.GetBasicType(),&i64data,resultType);
749
750            if( resultType.GetBasicSize() == sizeof(_int64) ){
751                //64ビット(符号有り整数/実数)
752
753                //push HILONG(i64data)
754                compiler.codeGenerator.op_push_V((long)*(long *)(((char *)(&i64data))+4));
755
756                //push LOLONG(i64data)
757                compiler.codeGenerator.op_push_V(*(long *)(&i64data));
758            }
759            else if( resultType.IsSingle() ){
760                //single実数
761
762                double dbl;
763                memcpy(&dbl,&i64data,sizeof(_int64));
764
765                float flt;
766                flt=(float)dbl;
767                long l;
768                memcpy(&l,&flt,sizeof(long));
769
770                //push flt
771                compiler.codeGenerator.op_push_V(l);
772            }
773            else{
774                //整数(符号有り/無し)
775
776                long l = (long)i64data;
777
778                if(resultType.GetBasicSize()==sizeof(char)) l = l & 0x000000FF;
779                if(resultType.GetBasicSize()==sizeof(short)) l = l & 0x0000FFFF;
780
781                //push term
782                compiler.codeGenerator.op_push_V(l);
783            }
784            return true;
785        }
786    }
787
788    if(expression[0]==1 )
789    {
790        if( expression[1]==ESC_NEW ){
791            //New演算子(オブジェクト生成)
792
793            if( !Operator_New( expression+2, baseType, resultType ) ){
794                return false;
795            }
796
797            return true;
798        }
799        else if( expression[1] == ESC_SYSTEM_STATIC_NEW )
800        {
801            // 静的領域にオブジェクトを作る
802
803            // 静的領域にオブジェクトを生成
804            int dataTableOffset;
805            if( !ActiveBasic::Compiler::DataTableGenerator::MakeConstObjectToProcessStaticBuffer( compiler.GetObjectModule().dataTable, expression + 2, resultType, dataTableOffset ) )
806            {
807                return false;
808            }
809
810            // push value
811            compiler.codeGenerator.op_push_V( dataTableOffset, Schedule::DataTable );
812
813            return true;
814        }
815    }
816
817
818    /////////////////////////////////
819    // 式要素を逆ポーランド式で取得
820    /////////////////////////////////
821
822    char *values[255];
823    long calc[255];
824    long stack[255];
825    int pnum;
826    if(!GetNumOpeElements(expression,&pnum,values,calc,stack)){
827        for(i=0;i<pnum;i++){
828            if(values[i]) HeapDefaultFree(values[i]);
829        }
830        return false;
831    }
832
833
834    BOOL bError;
835    bError=0;
836
837    //リテラル値のみの計算かどうかを判別するためのフラグ
838    BOOL bLiteralCalculation=1;
839
840    double dbl;
841    int sp;
842    int type_stack[255];
843    bool isNothing_stack[255];
844    LONG_PTR index_stack[255];
845    bool isNeedHeapFreeStructureStack[255];
846    _int64 i64data;
847    for(i=0,sp=0;i<pnum;i++){
848        int idCalc;
849        idCalc=calc[i]%100;
850
851        if(idCalc){
852            if(type_stack[sp-2]==DEF_OBJECT){
853                if( idCalc == CALC_AS
854                    && type_stack[sp-1] == ( DEF_OBJECT | FLAG_CAST )
855                    && index_stack[sp-1] == index_stack[sp-2]
856                    || isNothing_stack[sp-2] ){
857                        // 同一の型、またはNothingに対するAsはAs演算子を呼び出さない
858                }
859                else if( idCalc == CALC_AS
860                    && type_stack[sp-1] == ( DEF_OBJECT | FLAG_CAST )
861                    && ( ((CClass *)index_stack[sp-1])->IsEqualsOrSubClass( (CClass *)index_stack[sp-2] ) || ((CClass *)index_stack[sp-2])->IsEqualsOrSubClass( (CClass *)index_stack[sp-1] )
862                    )){
863                        // ダウンキャストを許可する
864                }
865                else{
866                    //オーバーロードされたオペレータを呼び出す
867                    i2=CallOperatorProc(idCalc,baseType,type_stack,index_stack,isNeedHeapFreeStructureStack,sp);
868                    if(i2==0){
869                        if(idCalc==CALC_EQUAL) lstrcpy(temp2,"==");
870                        else GetCalcName(idCalc,temp2);
871                        sprintf(temporary,"Operator %s",temp2);
872                        compiler.errorMessenger.Output(27,temporary,cp);
873                        goto error;
874                    }
875                    else if(i2==-1) goto error;
876
877                    continue;
878                }
879            }
880
881            if(!CheckCalcType(idCalc,type_stack,sp)) goto error;
882        }
883
884        switch(idCalc){
885            //数値
886            case 0:
887                index_stack[sp]=-1;
888                isNothing_stack[sp] = false;
889                isNeedHeapFreeStructureStack[sp] = false;
890
891                char *term;
892                term=values[i];
893
894                if( calc[i+1]%100 == CALC_AS ){
895                    // As演算子の右辺値
896                    //型名
897                    if( compiler.StringToType( term, resultType ) ){
898                        resultType.SetBasicType( resultType.GetBasicType() | FLAG_CAST );
899                    }
900                    else{
901                        compiler.errorMessenger.Output(3, term, cp );
902                        goto error;
903                    }
904
905                    type_stack[sp] = resultType.GetBasicType();
906                    index_stack[sp] = resultType.GetIndex();
907                    sp++;
908
909                    break;
910                }
911
912                if( (term[0]=='e'||term[0]=='E')
913                    && (term[1]=='x'||term[1]=='X')
914                    && term[2]=='\"'
915                    || term[0] == '\"' )
916                {
917                    bool isEx = true;
918                    if( term[0] == '\"' )
919                    {
920                        isEx = false;
921                    }
922
923                    if( isEx )
924                    {
925                        // 拡張版リテラル文字列(エスケープシーケンス可能)
926                        if(!RemoveStringQuotes(term+2)){
927                            compiler.errorMessenger.Output(43,NULL,cp);
928                            goto error;
929                        }
930                        i3=FormatString_EscapeSequence(term+2);
931                        term+=2;
932                    }
933                    else
934                    {
935                        // 通常文字列
936                        if(!RemoveStringQuotes(term)){
937                            compiler.errorMessenger.Output(43,NULL,cp);
938                            goto error;
939                        }
940                        i3=lstrlen(term);
941                    }
942
943                    if( !baseType.IsPointer() )
944                    {
945                        //要求タイプがオブジェクト、または未定のとき
946
947                        //String型オブジェクトを生成
948                        i2 = ActiveBasic::Compiler::DataTableGenerator::MakeConstStringObjectToProcessStaticBuffer( compiler.GetObjectModule().dataTable, term );
949
950                        // push value
951                        compiler.codeGenerator.op_push_V( i2, Schedule::DataTable );
952
953                        type_stack[sp]=DEF_OBJECT;
954                        index_stack[sp]=(LONG_PTR)compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr();
955                        bLiteralCalculation=0;
956
957                        sp++;
958                        break;
959                    }
960StrLiteral:
961                    type_stack[sp]=typeOfPtrChar;
962                    bLiteralCalculation=0;
963
964                    if( compiler.IsUnicode() )
965                    {
966                        i2 = compiler.GetObjectModule().dataTable.AddWString( Jenga::Common::ToWString( std::string( term, i3 ) ) );
967                    }
968                    else
969                    {
970                        i2 = compiler.GetObjectModule().dataTable.AddString( std::string( term, i3 ) );
971                    }
972
973                    //push DataSize
974                    compiler.codeGenerator.op_push_V( i2, Schedule::DataTable );
975                }
976                else if(IsVariableTopChar(term[0])||
977                    term[0]=='*'||
978                    (term[0]=='.'&&IsVariableTopChar(term[1]))){
979                    //////////////////
980                    // 何らかの識別子
981
982                    bool isLiteral;
983                    if( TermOpe( term, baseType, resultType, isLiteral, isNeedHeapFreeStructureStack[sp] ) ){
984                        if(resultType.IsNull()){
985                            //戻り値が存在しないとき
986                            for(i2=0;;i2++){
987                                if(term[i2]=='('||term[i2]=='\0'){
988                                    term[i2]=0;
989                                    break;
990                                }
991                            }
992                            compiler.errorMessenger.Output(38,term,cp);
993
994                            goto error;
995                        }
996
997                        type_stack[sp] = resultType.GetBasicType();
998                        index_stack[sp] = resultType.GetIndex();
999
1000                        if( !isLiteral ){
1001                            bLiteralCalculation=0;
1002                        }
1003
1004                        if( resultType.GetBasicType() & FLAG_CAST ){
1005                            // 型名のみ
1006                            compiler.errorMessenger.OutputFatalError();
1007                        }
1008                        else{
1009                            if( resultType.IsReal() ){
1010                                //sub esp,size
1011                                //fstp ptr[esp]
1012                                compiler.codeGenerator.op_fstp_push( resultType );
1013                            }
1014                            else{
1015                                if( resultType.Is64() ){
1016                                    //push edx
1017                                    compiler.codeGenerator.op_push( REG_EDX );
1018                                }
1019                                else{
1020                                    ExtendTypeTo32( resultType.GetBasicType(), REG_EAX );
1021                                }
1022
1023                                //push eax
1024                                compiler.codeGenerator.op_push( REG_EAX );
1025                            }
1026                        }
1027
1028                        sp++;
1029                        break;
1030                    }
1031
1032
1033                    // Nothing
1034                    if( lstrcmp( term, "Nothing" ) == 0 ){
1035                        isNothing_stack[sp] = true;
1036
1037                        if( baseType.IsObject() ){
1038                            type_stack[sp] = DEF_OBJECT;
1039                            index_stack[sp] = baseType.GetIndex();
1040                        }
1041                        else{
1042                            type_stack[sp] = baseType.GetBasicType();
1043                            index_stack[sp] = baseType.GetIndex();
1044                        }
1045
1046                        bLiteralCalculation = 0;
1047
1048                        //push 0
1049                        compiler.codeGenerator.op_push_V( 0 );
1050
1051                        sp++;
1052                        break;
1053                    }
1054
1055
1056                    //////////////
1057                    // 定数の場合
1058                    //////////////
1059
1060                    i3 = compiler.GetObjectModule().meta.GetGlobalConsts().GetBasicType(
1061                        ActiveBasic::Compiler::LexicalAnalyzer::FullNameToSymbol( term )
1062                    );
1063                    if(i3){
1064                        if( compiler.GetObjectModule().meta.GetGlobalConsts().IsStringPtr( ActiveBasic::Compiler::LexicalAnalyzer::FullNameToSymbol( term ), compiler.IsUnicode() ) ){
1065                            //リテラル文字列
1066
1067                            if( baseType.IsObject() || baseType.IsNull() )
1068                            {
1069                                //要求タイプがオブジェクト、または未定のとき
1070
1071                                //String型オブジェクトを生成
1072                                NewStringObject(term);
1073
1074                                type_stack[sp]=DEF_OBJECT;
1075                                index_stack[sp]=(LONG_PTR)compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr();
1076                                bLiteralCalculation=0;
1077
1078                                sp++;
1079                                break;
1080                            }
1081
1082                            double dbl = compiler.GetObjectModule().meta.GetGlobalConsts().GetDoubleData(
1083                                ActiveBasic::Compiler::LexicalAnalyzer::FullNameToSymbol( term )
1084                            );
1085                            memcpy(&i64data,&dbl,sizeof(double));
1086
1087                            //バイト数
1088                            i3=lstrlen((char *)i64data);
1089
1090                            memcpy(term,(char *)i64data,i3);
1091                            term[i3]=0;
1092                            goto StrLiteral;
1093                        }
1094
1095                        type_stack[sp]=i3;
1096                        if(IsRealNumberType(i3)){
1097                            //実数
1098                            double dbl = compiler.GetObjectModule().meta.GetGlobalConsts().GetDoubleData(
1099                                ActiveBasic::Compiler::LexicalAnalyzer::FullNameToSymbol( term )
1100                            );
1101                            memcpy(&i64data,&dbl,sizeof(double));
1102                            goto Literal;
1103                        }
1104                        else if(IsWholeNumberType(i3)){
1105                            //整数
1106                            i64data = compiler.GetObjectModule().meta.GetGlobalConsts().GetWholeData(
1107                                ActiveBasic::Compiler::LexicalAnalyzer::FullNameToSymbol( term )
1108                            );
1109                            goto Literal;
1110                        }
1111                        else{
1112                            compiler.errorMessenger.Output(300,NULL,cp);
1113                            goto error;
1114                        }
1115                    }
1116
1117
1118                    //該当する識別子が見当たらないときはエラー扱いにする
1119                    bError=1;
1120                    compiler.errorMessenger.Output(3,term,cp);
1121                    type_stack[sp]=DEF_DOUBLE;
1122                }
1123                else{
1124                    //リテラル値
1125                    type_stack[sp]=GetLiteralValue(term,&i64data,baseType.GetBasicType());
1126Literal:
1127                    if(type_stack[sp]==DEF_INT64||
1128                        type_stack[sp]==DEF_QWORD||
1129                        type_stack[sp]==DEF_DOUBLE){
1130                        //64ビット(符号有り整数/実数)
1131
1132                        //push HILONG(dbl)
1133                        compiler.codeGenerator.op_push_V((long)*(long *)(((char *)(&i64data))+4));
1134
1135                        //push LOLONG(dbl)
1136                        compiler.codeGenerator.op_push_V(*(long *)(&i64data));
1137                    }
1138                    else if(type_stack[sp]==DEF_SINGLE){
1139                        //single実数
1140
1141                        float flt;
1142                        memcpy(&dbl,&i64data,sizeof(double));
1143                        flt=(float)dbl;
1144                        memcpy(&i3,&flt,sizeof(long));
1145
1146                        //push term
1147                        compiler.codeGenerator.op_push_V(i3);
1148                    }
1149                    else{
1150                        //その他
1151
1152                        //push term
1153                        compiler.codeGenerator.op_push_V((long)i64data);
1154
1155                        if((long)i64data==0) index_stack[sp]=LITERAL_NULL;
1156                    }
1157
1158
1159                    //リテラル値の種類
1160                    if(Is64Type(type_stack[sp])==0&&IsRealNumberType(type_stack[sp])==0){
1161                        //整数(符号有り/無し)
1162
1163                        index_stack[sp]=GetLiteralIndex(i64data);
1164                    }
1165                }
1166                sp++;
1167                break;
1168
1169            //論理演算子
1170            case CALC_XOR:
1171                //value[sp-2] xor= value[sp-1]
1172                //xor演算
1173                if(!Calc_Xor(type_stack,index_stack,&sp)) goto error;
1174                break;
1175            case CALC_OR:
1176                //value[sp-2] or= value[sp-1]
1177                //or演算
1178                if(!Calc_Or(type_stack,index_stack,&sp)) goto error;
1179                break;
1180            case CALC_AND:
1181                //value[sp-2] and= value[sp-1]
1182                //and演算
1183                if(!Calc_And(type_stack,index_stack,&sp)) goto error;
1184                break;
1185            case CALC_NOT:
1186                //value[sp-1]=Not value[sp-1]
1187                //NOT演算子
1188                if(!Calc_Not(type_stack,sp)) goto error;
1189                break;
1190
1191            //比較演算子
1192            case CALC_PE:
1193                //value[sp-2]<=value[sp-1]
1194                if(!Calc_Relation_PE(type_stack,index_stack,&sp)) goto error;
1195                break;
1196            case CALC_QE:
1197                //value[sp-2]>=value[sp-1]
1198                if(!Calc_Relation_QE(type_stack,index_stack,&sp)) goto error;
1199                break;
1200            case CALC_P:
1201                //value[sp-2]<value[sp-1]
1202                if(!Calc_Relation_P(type_stack,index_stack,&sp)) goto error;
1203                break;
1204            case CALC_Q:
1205                //value[sp-2]>value[sp-1]
1206                if(!Calc_Relation_Q(type_stack,index_stack,&sp)) goto error;
1207                break;
1208            case CALC_NOTEQUAL:
1209                //value[sp-2]<>value[sp-1]
1210                if(!Calc_Relation_NotEqual(type_stack,&sp)) goto error;
1211                break;
1212            case CALC_EQUAL:
1213                //value[sp-2]=value[sp-1]
1214                if(!Calc_Relation_Equal(type_stack,&sp)) goto error;
1215                break;
1216
1217            //ビットシフト
1218            case CALC_SHL:
1219                //value[sp-2]=value[sp-2]<<value[sp-1]
1220                if(!Calc_SHL(type_stack,&sp)) goto error;
1221                break;
1222            case CALC_SHR:
1223                //value[sp-2]=value[sp-2]>>value[sp-1]
1224                if(!Calc_SHR(type_stack,&sp)) goto error;
1225                break;
1226
1227            //算術演算
1228            case CALC_ADDITION:
1229            case CALC_SUBTRACTION:
1230            case CALC_PRODUCT:
1231                if(!CalcTwoTerm_Arithmetic(idCalc,type_stack,index_stack,&sp)) goto error;
1232                break;
1233
1234            case CALC_MOD:
1235                //value[sp-2]%=value[sp-1]
1236                //剰余演算
1237                if(!Calc_Mod(type_stack,&sp)) goto error;
1238                break;
1239            case CALC_QUOTIENT:
1240                //value[sp-2]/=value[sp-1];
1241                //除算
1242                if(!Calc_Divide(type_stack,&sp,baseType.GetBasicType())) goto error;
1243                break;
1244            case CALC_INTQUOTIENT:
1245                //value[sp-2]/=value[sp-1]
1246                //整数除算
1247                if(!Calc_IntDivide(type_stack,index_stack,&sp)) goto error;
1248                break;
1249            case CALC_MINUSMARK:
1250                //value[sp-1]=-value[sp-1]
1251                //符号反転
1252                if(!Calc_MinusMark(type_stack,sp)) goto error;
1253                index_stack[sp-1]=-1;
1254                break;
1255            case CALC_POWER:
1256                //べき乗演算(浮動小数点演算のみ)
1257                if(!Calc_Power(type_stack,&sp)) goto error;
1258                break;
1259            case CALC_AS:
1260                //キャスト
1261                if(!Calc_Cast(type_stack,index_stack,&sp)) goto error;
1262                break;
1263
1264            case CALC_BYVAL:
1265                //ポインタ型→参照型
1266                if( PTR_LEVEL( type_stack[sp-1] ) <= 0 ){
1267                    //ポインタ型ではないとき
1268                    compiler.errorMessenger.Output( 1, NULL, cp );
1269                    goto error;
1270                }
1271
1272                type_stack[sp-1] = PTR_LEVEL_DOWN( type_stack[sp-1] );
1273
1274                break;
1275
1276            default:
1277                compiler.errorMessenger.Output(300,NULL,cp);
1278                goto error;
1279        }
1280    }
1281
1282    if(bError) goto error;
1283
1284    if(sp!=1){
1285        compiler.errorMessenger.Output(1,NULL,cp);
1286        goto error;
1287    }
1288
1289    if(bLiteralCalculation){
1290        //右辺値が数値の定数式の場合
1291        compiler.errorMessenger.OutputFatalError();
1292    }
1293    else{
1294        //右辺値が数値の定数式ではないとき
1295        if(IS_LITERAL(index_stack[0])) index_stack[0]=-1;
1296    }
1297
1298    if(pbIsNeedHeapFreeStructure)
1299    {
1300        *pbIsNeedHeapFreeStructure = isNeedHeapFreeStructureStack[0];
1301    }
1302
1303    resultType.SetType( type_stack[0], index_stack[0] );
1304
1305    bool isSuccessful = true;
1306    goto finish;
1307
1308
1309error:
1310    isSuccessful = false;
1311    goto finish;
1312
1313
1314finish:
1315
1316    for(i=0;i<pnum;i++){
1317        if(values[i]) HeapDefaultFree(values[i]);
1318    }
1319
1320    // 強制終了を防ぐためのダミー(原因不明)
1321    if( lstrcmp( expression, "-1/t" ) == 0 )
1322    {
1323    }
1324
1325    return isSuccessful;
1326}
Note: See TracBrowser for help on using the repository browser.