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

Last change on this file since 745 was 745, checked in by dai, 15 years ago
  • Compiler::AddStringToDataTableメソッドを実装。
  • ToWStringメソッドの内部予備バッファを増やした。
File size: 33.6 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( sp>=2 && type_stack[sp-2]==DEF_OBJECT )
853            {
854                if( idCalc == CALC_AS
855                    && type_stack[sp-1] == ( DEF_OBJECT | FLAG_CAST )
856                    && index_stack[sp-1] == index_stack[sp-2]
857                    || isNothing_stack[sp-2] ){
858                        // 同一の型、またはNothingに対するAsはAs演算子を呼び出さない
859                }
860                else if( idCalc == CALC_AS
861                    && type_stack[sp-1] == ( DEF_OBJECT | FLAG_CAST )
862                    && ( ((CClass *)index_stack[sp-1])->IsEqualsOrSubClass( (CClass *)index_stack[sp-2] ) || ((CClass *)index_stack[sp-2])->IsEqualsOrSubClass( (CClass *)index_stack[sp-1] )
863                    )){
864                        // ダウンキャストを許可する
865                }
866                else{
867                    //オーバーロードされたオペレータを呼び出す
868                    i2=CallOperatorProc(idCalc,baseType,type_stack,index_stack,isNeedHeapFreeStructureStack,sp);
869                    if(i2==0){
870                        if(idCalc==CALC_EQUAL) lstrcpy(temp2,"==");
871                        else GetCalcName(idCalc,temp2);
872                        sprintf(temporary,"Operator %s",temp2);
873                        compiler.errorMessenger.Output(27,temporary,cp);
874                        goto error;
875                    }
876                    else if(i2==-1) goto error;
877
878                    continue;
879                }
880            }
881
882            if(!CheckCalcType(idCalc,type_stack,sp)) goto error;
883        }
884
885        switch(idCalc){
886            //数値
887            case 0:
888                index_stack[sp]=-1;
889                isNothing_stack[sp] = false;
890                isNeedHeapFreeStructureStack[sp] = false;
891
892                char *term;
893                term=values[i];
894
895                if( calc[i+1]%100 == CALC_AS ){
896                    // As演算子の右辺値
897                    //型名
898                    if( compiler.StringToType( term, resultType ) ){
899                        resultType.SetBasicType( resultType.GetBasicType() | FLAG_CAST );
900                    }
901                    else{
902                        compiler.errorMessenger.Output(3, term, cp );
903                        goto error;
904                    }
905
906                    type_stack[sp] = resultType.GetBasicType();
907                    index_stack[sp] = resultType.GetIndex();
908                    sp++;
909
910                    break;
911                }
912
913                if( (term[0]=='e'||term[0]=='E')
914                    && (term[1]=='x'||term[1]=='X')
915                    && term[2]=='\"'
916                    || term[0] == '\"' )
917                {
918                    bool isEx = true;
919                    if( term[0] == '\"' )
920                    {
921                        isEx = false;
922                    }
923
924                    if( isEx )
925                    {
926                        // 拡張版リテラル文字列(エスケープシーケンス可能)
927                        if(!RemoveStringQuotes(term+2)){
928                            compiler.errorMessenger.Output(43,NULL,cp);
929                            goto error;
930                        }
931                        i3=FormatString_EscapeSequence(term+2);
932                        term+=2;
933                    }
934                    else
935                    {
936                        // 通常文字列
937                        if(!RemoveStringQuotes(term)){
938                            compiler.errorMessenger.Output(43,NULL,cp);
939                            goto error;
940                        }
941                        i3=lstrlen(term);
942                    }
943
944                    if( !baseType.IsPointer() )
945                    {
946                        //要求タイプがオブジェクト、または未定のとき
947
948                        //String型オブジェクトを生成
949                        i2 = ActiveBasic::Compiler::DataTableGenerator::MakeConstStringObjectToProcessStaticBuffer( compiler.GetObjectModule().dataTable, term );
950
951                        // push value
952                        compiler.codeGenerator.op_push_V( i2, Schedule::DataTable );
953
954                        type_stack[sp]=DEF_OBJECT;
955                        index_stack[sp]=(LONG_PTR)compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr();
956                        bLiteralCalculation=0;
957
958                        sp++;
959                        break;
960                    }
961StrLiteral:
962                    type_stack[sp]=typeOfPtrChar;
963                    bLiteralCalculation=0;
964
965                    i2 = compiler.AddStringToDataTable( std::string( term, i3 ) );
966
967                    //push DataSize
968                    compiler.codeGenerator.op_push_V( i2, Schedule::DataTable );
969                }
970                else if(IsVariableTopChar(term[0])||
971                    term[0]=='*'||
972                    (term[0]=='.'&&IsVariableTopChar(term[1]))){
973                    //////////////////
974                    // 何らかの識別子
975
976                    bool isLiteral;
977                    if( TermOpe( term, baseType, resultType, isLiteral, isNeedHeapFreeStructureStack[sp] ) ){
978                        if(resultType.IsNull()){
979                            //戻り値が存在しないとき
980                            for(i2=0;;i2++){
981                                if(term[i2]=='('||term[i2]=='\0'){
982                                    term[i2]=0;
983                                    break;
984                                }
985                            }
986                            compiler.errorMessenger.Output(38,term,cp);
987
988                            goto error;
989                        }
990
991                        type_stack[sp] = resultType.GetBasicType();
992                        index_stack[sp] = resultType.GetIndex();
993
994                        if( !isLiteral ){
995                            bLiteralCalculation=0;
996                        }
997
998                        if( resultType.GetBasicType() & FLAG_CAST ){
999                            // 型名のみ
1000                            compiler.errorMessenger.OutputFatalError();
1001                        }
1002                        else{
1003                            if( resultType.IsReal() ){
1004                                //sub esp,size
1005                                //fstp ptr[esp]
1006                                compiler.codeGenerator.op_fstp_push( resultType );
1007                            }
1008                            else{
1009                                if( resultType.Is64() ){
1010                                    //push edx
1011                                    compiler.codeGenerator.op_push( REG_EDX );
1012                                }
1013                                else{
1014                                    ExtendTypeTo32( resultType.GetBasicType(), REG_EAX );
1015                                }
1016
1017                                //push eax
1018                                compiler.codeGenerator.op_push( REG_EAX );
1019                            }
1020                        }
1021
1022                        sp++;
1023                        break;
1024                    }
1025
1026
1027                    // Nothing
1028                    if( lstrcmp( term, "Nothing" ) == 0 ){
1029                        isNothing_stack[sp] = true;
1030
1031                        if( baseType.IsObject() ){
1032                            type_stack[sp] = DEF_OBJECT;
1033                            index_stack[sp] = baseType.GetIndex();
1034                        }
1035                        else{
1036                            type_stack[sp] = baseType.GetBasicType();
1037                            index_stack[sp] = baseType.GetIndex();
1038                        }
1039
1040                        bLiteralCalculation = 0;
1041
1042                        //push 0
1043                        compiler.codeGenerator.op_push_V( 0 );
1044
1045                        sp++;
1046                        break;
1047                    }
1048
1049
1050                    //////////////
1051                    // 定数の場合
1052                    //////////////
1053
1054                    i3 = compiler.GetObjectModule().meta.GetGlobalConsts().GetBasicType(
1055                        ActiveBasic::Compiler::LexicalAnalyzer::FullNameToSymbol( term )
1056                    );
1057                    if(i3){
1058                        if( compiler.GetObjectModule().meta.GetGlobalConsts().IsStringPtr( ActiveBasic::Compiler::LexicalAnalyzer::FullNameToSymbol( term ), compiler.IsUnicode() ) ){
1059                            //リテラル文字列
1060
1061                            if( baseType.IsObject() || baseType.IsNull() )
1062                            {
1063                                //要求タイプがオブジェクト、または未定のとき
1064
1065                                //String型オブジェクトを生成
1066                                NewStringObject(term);
1067
1068                                type_stack[sp]=DEF_OBJECT;
1069                                index_stack[sp]=(LONG_PTR)compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr();
1070                                bLiteralCalculation=0;
1071
1072                                sp++;
1073                                break;
1074                            }
1075
1076                            double dbl = compiler.GetObjectModule().meta.GetGlobalConsts().GetDoubleData(
1077                                ActiveBasic::Compiler::LexicalAnalyzer::FullNameToSymbol( term )
1078                            );
1079                            memcpy(&i64data,&dbl,sizeof(double));
1080
1081                            //バイト数
1082                            i3=lstrlen((char *)i64data);
1083
1084                            memcpy(term,(char *)i64data,i3);
1085                            term[i3]=0;
1086                            goto StrLiteral;
1087                        }
1088
1089                        type_stack[sp]=i3;
1090                        if(IsRealNumberType(i3)){
1091                            //実数
1092                            double dbl = compiler.GetObjectModule().meta.GetGlobalConsts().GetDoubleData(
1093                                ActiveBasic::Compiler::LexicalAnalyzer::FullNameToSymbol( term )
1094                            );
1095                            memcpy(&i64data,&dbl,sizeof(double));
1096                            goto Literal;
1097                        }
1098                        else if(IsWholeNumberType(i3)){
1099                            //整数
1100                            i64data = compiler.GetObjectModule().meta.GetGlobalConsts().GetWholeData(
1101                                ActiveBasic::Compiler::LexicalAnalyzer::FullNameToSymbol( term )
1102                            );
1103                            goto Literal;
1104                        }
1105                        else{
1106                            compiler.errorMessenger.Output(300,NULL,cp);
1107                            goto error;
1108                        }
1109                    }
1110
1111
1112                    //該当する識別子が見当たらないときはエラー扱いにする
1113                    bError=1;
1114                    compiler.errorMessenger.Output(3,term,cp);
1115                    type_stack[sp]=DEF_DOUBLE;
1116                }
1117                else{
1118                    //リテラル値
1119                    type_stack[sp]=GetLiteralValue(term,&i64data,baseType.GetBasicType());
1120Literal:
1121                    if(type_stack[sp]==DEF_INT64||
1122                        type_stack[sp]==DEF_QWORD||
1123                        type_stack[sp]==DEF_DOUBLE){
1124                        //64ビット(符号有り整数/実数)
1125
1126                        //push HILONG(dbl)
1127                        compiler.codeGenerator.op_push_V((long)*(long *)(((char *)(&i64data))+4));
1128
1129                        //push LOLONG(dbl)
1130                        compiler.codeGenerator.op_push_V(*(long *)(&i64data));
1131                    }
1132                    else if(type_stack[sp]==DEF_SINGLE){
1133                        //single実数
1134
1135                        float flt;
1136                        memcpy(&dbl,&i64data,sizeof(double));
1137                        flt=(float)dbl;
1138                        memcpy(&i3,&flt,sizeof(long));
1139
1140                        //push term
1141                        compiler.codeGenerator.op_push_V(i3);
1142                    }
1143                    else{
1144                        //その他
1145
1146                        //push term
1147                        compiler.codeGenerator.op_push_V((long)i64data);
1148
1149                        if((long)i64data==0) index_stack[sp]=LITERAL_NULL;
1150                    }
1151
1152
1153                    //リテラル値の種類
1154                    if(Is64Type(type_stack[sp])==0&&IsRealNumberType(type_stack[sp])==0){
1155                        //整数(符号有り/無し)
1156
1157                        index_stack[sp]=GetLiteralIndex(i64data);
1158                    }
1159                }
1160                sp++;
1161                break;
1162
1163            //論理演算子
1164            case CALC_XOR:
1165                //value[sp-2] xor= value[sp-1]
1166                //xor演算
1167                if(!Calc_Xor(type_stack,index_stack,&sp)) goto error;
1168                break;
1169            case CALC_OR:
1170                //value[sp-2] or= value[sp-1]
1171                //or演算
1172                if(!Calc_Or(type_stack,index_stack,&sp)) goto error;
1173                break;
1174            case CALC_AND:
1175                //value[sp-2] and= value[sp-1]
1176                //and演算
1177                if(!Calc_And(type_stack,index_stack,&sp)) goto error;
1178                break;
1179            case CALC_NOT:
1180                //value[sp-1]=Not value[sp-1]
1181                //NOT演算子
1182                if(!Calc_Not(type_stack,sp)) goto error;
1183                break;
1184
1185            //比較演算子
1186            case CALC_PE:
1187                //value[sp-2]<=value[sp-1]
1188                if(!Calc_Relation_PE(type_stack,index_stack,&sp)) goto error;
1189                break;
1190            case CALC_QE:
1191                //value[sp-2]>=value[sp-1]
1192                if(!Calc_Relation_QE(type_stack,index_stack,&sp)) goto error;
1193                break;
1194            case CALC_P:
1195                //value[sp-2]<value[sp-1]
1196                if(!Calc_Relation_P(type_stack,index_stack,&sp)) goto error;
1197                break;
1198            case CALC_Q:
1199                //value[sp-2]>value[sp-1]
1200                if(!Calc_Relation_Q(type_stack,index_stack,&sp)) goto error;
1201                break;
1202            case CALC_NOTEQUAL:
1203                //value[sp-2]<>value[sp-1]
1204                if(!Calc_Relation_NotEqual(type_stack,&sp)) goto error;
1205                break;
1206            case CALC_EQUAL:
1207                //value[sp-2]=value[sp-1]
1208                if(!Calc_Relation_Equal(type_stack,&sp)) goto error;
1209                break;
1210
1211            //ビットシフト
1212            case CALC_SHL:
1213                //value[sp-2]=value[sp-2]<<value[sp-1]
1214                if(!Calc_SHL(type_stack,&sp)) goto error;
1215                break;
1216            case CALC_SHR:
1217                //value[sp-2]=value[sp-2]>>value[sp-1]
1218                if(!Calc_SHR(type_stack,&sp)) goto error;
1219                break;
1220
1221            //算術演算
1222            case CALC_ADDITION:
1223            case CALC_SUBTRACTION:
1224            case CALC_PRODUCT:
1225                if(!CalcTwoTerm_Arithmetic(idCalc,type_stack,index_stack,&sp)) goto error;
1226                break;
1227
1228            case CALC_MOD:
1229                //value[sp-2]%=value[sp-1]
1230                //剰余演算
1231                if(!Calc_Mod(type_stack,&sp)) goto error;
1232                break;
1233            case CALC_QUOTIENT:
1234                //value[sp-2]/=value[sp-1];
1235                //除算
1236                if(!Calc_Divide(type_stack,&sp,baseType.GetBasicType())) goto error;
1237                break;
1238            case CALC_INTQUOTIENT:
1239                //value[sp-2]/=value[sp-1]
1240                //整数除算
1241                if(!Calc_IntDivide(type_stack,index_stack,&sp)) goto error;
1242                break;
1243            case CALC_MINUSMARK:
1244                //value[sp-1]=-value[sp-1]
1245                //符号反転
1246                if(!Calc_MinusMark(type_stack,sp)) goto error;
1247                index_stack[sp-1]=-1;
1248                break;
1249            case CALC_POWER:
1250                //べき乗演算(浮動小数点演算のみ)
1251                if(!Calc_Power(type_stack,&sp)) goto error;
1252                break;
1253            case CALC_AS:
1254                //キャスト
1255                if(!Calc_Cast(type_stack,index_stack,&sp)) goto error;
1256                break;
1257
1258            case CALC_BYVAL:
1259                //ポインタ型→参照型
1260                if( PTR_LEVEL( type_stack[sp-1] ) <= 0 ){
1261                    //ポインタ型ではないとき
1262                    compiler.errorMessenger.Output( 1, NULL, cp );
1263                    goto error;
1264                }
1265
1266                type_stack[sp-1] = PTR_LEVEL_DOWN( type_stack[sp-1] );
1267
1268                break;
1269
1270            default:
1271                compiler.errorMessenger.Output(300,NULL,cp);
1272                goto error;
1273        }
1274    }
1275
1276    if(bError) goto error;
1277
1278    if(sp!=1){
1279        compiler.errorMessenger.Output(1,NULL,cp);
1280        goto error;
1281    }
1282
1283    if(bLiteralCalculation){
1284        //右辺値が数値の定数式の場合
1285        compiler.errorMessenger.OutputFatalError();
1286    }
1287    else{
1288        //右辺値が数値の定数式ではないとき
1289        if(IS_LITERAL(index_stack[0])) index_stack[0]=-1;
1290    }
1291
1292    if(pbIsNeedHeapFreeStructure)
1293    {
1294        *pbIsNeedHeapFreeStructure = isNeedHeapFreeStructureStack[0];
1295    }
1296
1297    resultType.SetType( type_stack[0], index_stack[0] );
1298
1299    bool isSuccessful = true;
1300    goto finish;
1301
1302
1303error:
1304    isSuccessful = false;
1305    goto finish;
1306
1307
1308finish:
1309
1310    for(i=0;i<pnum;i++){
1311        if(values[i]) HeapDefaultFree(values[i]);
1312    }
1313
1314    // 強制終了を防ぐためのダミー(原因不明)
1315    if( lstrcmp( expression, "-1/t" ) == 0 )
1316    {
1317    }
1318
1319    return isSuccessful;
1320}
Note: See TracBrowser for help on using the repository browser.