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

Last change on this file since 701 was 701, checked in by dai_9181, 15 years ago
  • [700]の一部を差し戻し。
    • 差し戻し内容
      • strlenSSE2へのdefineを差し戻し。
      • _TermOpeを差し戻し。

!!!注意
コミット時は、下記の事項を守ること。

  • ライブラリのリビルドが正常に行えることを確認すること。
  • 最低限のテストケース(現状ではSimpleTestCase)がリリース版で正常に動作することを確認すること。
  • コンパイラ・デバッガ関連のコード修正時は、上記2点について、x86/x64の双方にて確認すること。
  • 「まとめてコミット」はなるべく避けること。何のためのコミットなのかをログと対にして確認できるようにすること。
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( 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                    if( compiler.IsUnicode() )
966                    {
967                        i2 = compiler.GetObjectModule().dataTable.AddWString( Jenga::Common::ToWString( std::string( term, i3 ) ) );
968                    }
969                    else
970                    {
971                        i2 = compiler.GetObjectModule().dataTable.AddString( std::string( term, i3 ) );
972                    }
973
974                    //push DataSize
975                    compiler.codeGenerator.op_push_V( i2, Schedule::DataTable );
976                }
977                else if(IsVariableTopChar(term[0])||
978                    term[0]=='*'||
979                    (term[0]=='.'&&IsVariableTopChar(term[1]))){
980                    //////////////////
981                    // 何らかの識別子
982
983                    bool isLiteral;
984                    if( TermOpe( term, baseType, resultType, isLiteral, isNeedHeapFreeStructureStack[sp] ) ){
985                        if(resultType.IsNull()){
986                            //戻り値が存在しないとき
987                            for(i2=0;;i2++){
988                                if(term[i2]=='('||term[i2]=='\0'){
989                                    term[i2]=0;
990                                    break;
991                                }
992                            }
993                            compiler.errorMessenger.Output(38,term,cp);
994
995                            goto error;
996                        }
997
998                        type_stack[sp] = resultType.GetBasicType();
999                        index_stack[sp] = resultType.GetIndex();
1000
1001                        if( !isLiteral ){
1002                            bLiteralCalculation=0;
1003                        }
1004
1005                        if( resultType.GetBasicType() & FLAG_CAST ){
1006                            // 型名のみ
1007                            compiler.errorMessenger.OutputFatalError();
1008                        }
1009                        else{
1010                            if( resultType.IsReal() ){
1011                                //sub esp,size
1012                                //fstp ptr[esp]
1013                                compiler.codeGenerator.op_fstp_push( resultType );
1014                            }
1015                            else{
1016                                if( resultType.Is64() ){
1017                                    //push edx
1018                                    compiler.codeGenerator.op_push( REG_EDX );
1019                                }
1020                                else{
1021                                    ExtendTypeTo32( resultType.GetBasicType(), REG_EAX );
1022                                }
1023
1024                                //push eax
1025                                compiler.codeGenerator.op_push( REG_EAX );
1026                            }
1027                        }
1028
1029                        sp++;
1030                        break;
1031                    }
1032
1033
1034                    // Nothing
1035                    if( lstrcmp( term, "Nothing" ) == 0 ){
1036                        isNothing_stack[sp] = true;
1037
1038                        if( baseType.IsObject() ){
1039                            type_stack[sp] = DEF_OBJECT;
1040                            index_stack[sp] = baseType.GetIndex();
1041                        }
1042                        else{
1043                            type_stack[sp] = baseType.GetBasicType();
1044                            index_stack[sp] = baseType.GetIndex();
1045                        }
1046
1047                        bLiteralCalculation = 0;
1048
1049                        //push 0
1050                        compiler.codeGenerator.op_push_V( 0 );
1051
1052                        sp++;
1053                        break;
1054                    }
1055
1056
1057                    //////////////
1058                    // 定数の場合
1059                    //////////////
1060
1061                    i3 = compiler.GetObjectModule().meta.GetGlobalConsts().GetBasicType(
1062                        ActiveBasic::Compiler::LexicalAnalyzer::FullNameToSymbol( term )
1063                    );
1064                    if(i3){
1065                        if( compiler.GetObjectModule().meta.GetGlobalConsts().IsStringPtr( ActiveBasic::Compiler::LexicalAnalyzer::FullNameToSymbol( term ), compiler.IsUnicode() ) ){
1066                            //リテラル文字列
1067
1068                            if( baseType.IsObject() || baseType.IsNull() )
1069                            {
1070                                //要求タイプがオブジェクト、または未定のとき
1071
1072                                //String型オブジェクトを生成
1073                                NewStringObject(term);
1074
1075                                type_stack[sp]=DEF_OBJECT;
1076                                index_stack[sp]=(LONG_PTR)compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr();
1077                                bLiteralCalculation=0;
1078
1079                                sp++;
1080                                break;
1081                            }
1082
1083                            double dbl = compiler.GetObjectModule().meta.GetGlobalConsts().GetDoubleData(
1084                                ActiveBasic::Compiler::LexicalAnalyzer::FullNameToSymbol( term )
1085                            );
1086                            memcpy(&i64data,&dbl,sizeof(double));
1087
1088                            //バイト数
1089                            i3=lstrlen((char *)i64data);
1090
1091                            memcpy(term,(char *)i64data,i3);
1092                            term[i3]=0;
1093                            goto StrLiteral;
1094                        }
1095
1096                        type_stack[sp]=i3;
1097                        if(IsRealNumberType(i3)){
1098                            //実数
1099                            double dbl = compiler.GetObjectModule().meta.GetGlobalConsts().GetDoubleData(
1100                                ActiveBasic::Compiler::LexicalAnalyzer::FullNameToSymbol( term )
1101                            );
1102                            memcpy(&i64data,&dbl,sizeof(double));
1103                            goto Literal;
1104                        }
1105                        else if(IsWholeNumberType(i3)){
1106                            //整数
1107                            i64data = compiler.GetObjectModule().meta.GetGlobalConsts().GetWholeData(
1108                                ActiveBasic::Compiler::LexicalAnalyzer::FullNameToSymbol( term )
1109                            );
1110                            goto Literal;
1111                        }
1112                        else{
1113                            compiler.errorMessenger.Output(300,NULL,cp);
1114                            goto error;
1115                        }
1116                    }
1117
1118
1119                    //該当する識別子が見当たらないときはエラー扱いにする
1120                    bError=1;
1121                    compiler.errorMessenger.Output(3,term,cp);
1122                    type_stack[sp]=DEF_DOUBLE;
1123                }
1124                else{
1125                    //リテラル値
1126                    type_stack[sp]=GetLiteralValue(term,&i64data,baseType.GetBasicType());
1127Literal:
1128                    if(type_stack[sp]==DEF_INT64||
1129                        type_stack[sp]==DEF_QWORD||
1130                        type_stack[sp]==DEF_DOUBLE){
1131                        //64ビット(符号有り整数/実数)
1132
1133                        //push HILONG(dbl)
1134                        compiler.codeGenerator.op_push_V((long)*(long *)(((char *)(&i64data))+4));
1135
1136                        //push LOLONG(dbl)
1137                        compiler.codeGenerator.op_push_V(*(long *)(&i64data));
1138                    }
1139                    else if(type_stack[sp]==DEF_SINGLE){
1140                        //single実数
1141
1142                        float flt;
1143                        memcpy(&dbl,&i64data,sizeof(double));
1144                        flt=(float)dbl;
1145                        memcpy(&i3,&flt,sizeof(long));
1146
1147                        //push term
1148                        compiler.codeGenerator.op_push_V(i3);
1149                    }
1150                    else{
1151                        //その他
1152
1153                        //push term
1154                        compiler.codeGenerator.op_push_V((long)i64data);
1155
1156                        if((long)i64data==0) index_stack[sp]=LITERAL_NULL;
1157                    }
1158
1159
1160                    //リテラル値の種類
1161                    if(Is64Type(type_stack[sp])==0&&IsRealNumberType(type_stack[sp])==0){
1162                        //整数(符号有り/無し)
1163
1164                        index_stack[sp]=GetLiteralIndex(i64data);
1165                    }
1166                }
1167                sp++;
1168                break;
1169
1170            //論理演算子
1171            case CALC_XOR:
1172                //value[sp-2] xor= value[sp-1]
1173                //xor演算
1174                if(!Calc_Xor(type_stack,index_stack,&sp)) goto error;
1175                break;
1176            case CALC_OR:
1177                //value[sp-2] or= value[sp-1]
1178                //or演算
1179                if(!Calc_Or(type_stack,index_stack,&sp)) goto error;
1180                break;
1181            case CALC_AND:
1182                //value[sp-2] and= value[sp-1]
1183                //and演算
1184                if(!Calc_And(type_stack,index_stack,&sp)) goto error;
1185                break;
1186            case CALC_NOT:
1187                //value[sp-1]=Not value[sp-1]
1188                //NOT演算子
1189                if(!Calc_Not(type_stack,sp)) goto error;
1190                break;
1191
1192            //比較演算子
1193            case CALC_PE:
1194                //value[sp-2]<=value[sp-1]
1195                if(!Calc_Relation_PE(type_stack,index_stack,&sp)) goto error;
1196                break;
1197            case CALC_QE:
1198                //value[sp-2]>=value[sp-1]
1199                if(!Calc_Relation_QE(type_stack,index_stack,&sp)) goto error;
1200                break;
1201            case CALC_P:
1202                //value[sp-2]<value[sp-1]
1203                if(!Calc_Relation_P(type_stack,index_stack,&sp)) goto error;
1204                break;
1205            case CALC_Q:
1206                //value[sp-2]>value[sp-1]
1207                if(!Calc_Relation_Q(type_stack,index_stack,&sp)) goto error;
1208                break;
1209            case CALC_NOTEQUAL:
1210                //value[sp-2]<>value[sp-1]
1211                if(!Calc_Relation_NotEqual(type_stack,&sp)) goto error;
1212                break;
1213            case CALC_EQUAL:
1214                //value[sp-2]=value[sp-1]
1215                if(!Calc_Relation_Equal(type_stack,&sp)) goto error;
1216                break;
1217
1218            //ビットシフト
1219            case CALC_SHL:
1220                //value[sp-2]=value[sp-2]<<value[sp-1]
1221                if(!Calc_SHL(type_stack,&sp)) goto error;
1222                break;
1223            case CALC_SHR:
1224                //value[sp-2]=value[sp-2]>>value[sp-1]
1225                if(!Calc_SHR(type_stack,&sp)) goto error;
1226                break;
1227
1228            //算術演算
1229            case CALC_ADDITION:
1230            case CALC_SUBTRACTION:
1231            case CALC_PRODUCT:
1232                if(!CalcTwoTerm_Arithmetic(idCalc,type_stack,index_stack,&sp)) goto error;
1233                break;
1234
1235            case CALC_MOD:
1236                //value[sp-2]%=value[sp-1]
1237                //剰余演算
1238                if(!Calc_Mod(type_stack,&sp)) goto error;
1239                break;
1240            case CALC_QUOTIENT:
1241                //value[sp-2]/=value[sp-1];
1242                //除算
1243                if(!Calc_Divide(type_stack,&sp,baseType.GetBasicType())) goto error;
1244                break;
1245            case CALC_INTQUOTIENT:
1246                //value[sp-2]/=value[sp-1]
1247                //整数除算
1248                if(!Calc_IntDivide(type_stack,index_stack,&sp)) goto error;
1249                break;
1250            case CALC_MINUSMARK:
1251                //value[sp-1]=-value[sp-1]
1252                //符号反転
1253                if(!Calc_MinusMark(type_stack,sp)) goto error;
1254                index_stack[sp-1]=-1;
1255                break;
1256            case CALC_POWER:
1257                //べき乗演算(浮動小数点演算のみ)
1258                if(!Calc_Power(type_stack,&sp)) goto error;
1259                break;
1260            case CALC_AS:
1261                //キャスト
1262                if(!Calc_Cast(type_stack,index_stack,&sp)) goto error;
1263                break;
1264
1265            case CALC_BYVAL:
1266                //ポインタ型→参照型
1267                if( PTR_LEVEL( type_stack[sp-1] ) <= 0 ){
1268                    //ポインタ型ではないとき
1269                    compiler.errorMessenger.Output( 1, NULL, cp );
1270                    goto error;
1271                }
1272
1273                type_stack[sp-1] = PTR_LEVEL_DOWN( type_stack[sp-1] );
1274
1275                break;
1276
1277            default:
1278                compiler.errorMessenger.Output(300,NULL,cp);
1279                goto error;
1280        }
1281    }
1282
1283    if(bError) goto error;
1284
1285    if(sp!=1){
1286        compiler.errorMessenger.Output(1,NULL,cp);
1287        goto error;
1288    }
1289
1290    if(bLiteralCalculation){
1291        //右辺値が数値の定数式の場合
1292        compiler.errorMessenger.OutputFatalError();
1293    }
1294    else{
1295        //右辺値が数値の定数式ではないとき
1296        if(IS_LITERAL(index_stack[0])) index_stack[0]=-1;
1297    }
1298
1299    if(pbIsNeedHeapFreeStructure)
1300    {
1301        *pbIsNeedHeapFreeStructure = isNeedHeapFreeStructureStack[0];
1302    }
1303
1304    resultType.SetType( type_stack[0], index_stack[0] );
1305
1306    bool isSuccessful = true;
1307    goto finish;
1308
1309
1310error:
1311    isSuccessful = false;
1312    goto finish;
1313
1314
1315finish:
1316
1317    for(i=0;i<pnum;i++){
1318        if(values[i]) HeapDefaultFree(values[i]);
1319    }
1320
1321    // 強制終了を防ぐためのダミー(原因不明)
1322    if( lstrcmp( expression, "-1/t" ) == 0 )
1323    {
1324    }
1325
1326    return isSuccessful;
1327}
Note: See TracBrowser for help on using the repository browser.