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

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

不正なByValに対するエラーメッセージが正確に表示されなくなるバグを修正

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