source: dev/trunk/ab5.0/abdev/BasicCompiler64/Compile_Calc.cpp @ 463

Last change on this file since 463 was 463, checked in by dai_9181, 16 years ago

[461]を64bit版にマージ。

File size: 6.4 KB
Line 
1#include "stdafx.h"
2
3#include <Compiler.h>
4
5#include "../BasicCompiler_Common/common.h"
6#include "Opcode.h"
7
8void SetVariableFromRax( const Type &varType, int CalcType,RELATIVE_VAR *pRelativeVar){
9    /////////////////////////////////////////////////
10    // raxの内容を変数にコピーするコードを抽出
11    /////////////////////////////////////////////////
12
13    if( varType.IsBoolean() )
14    {
15        //bool
16        SetBooleanVariable(CalcType,pRelativeVar);
17    }
18    else if( varType.IsReal() )
19    {
20        // Double/Single型変数へレジスタの値を代入
21        SetRealVariable(varType.GetBasicType(), CalcType, pRelativeVar);
22    }
23    else if( varType.IsWhole() || varType.IsObject() )
24    {
25        //整数変数へraxの値を格納する
26        SetWholeVariable( varType.GetSize(), CalcType, pRelativeVar );
27    }
28    else{
29        SetError(300,NULL,cp);
30    }
31}
32void OpcodeCalc(const char *Command){
33    int i,i2,i3;
34    char variable[VN_SIZE];
35
36
37    //////////////////////////////////////
38    // インクリメント・デクリメント
39    //////////////////////////////////////
40
41    for(i=0;;i++){
42        if(Command[i]=='\"'){
43            //ダブルクォートは不正なのでエラー扱い
44            variable[i]=0;
45            SetError(3,variable,cp);
46            return;
47        }
48
49        if(Command[i]=='('){
50            i2=GetStringInPare(variable+i,Command+i);
51            i+=i2-1;
52            continue;
53        }
54        if(Command[i]=='['){
55            i2=GetStringInBracket(variable+i,Command+i);
56            i+=i2-1;
57            continue;
58        }
59        if(Command[i]=='\0'){
60
61            ///////////////////////////////////
62            // インクリメント・デクリメント
63            ///////////////////////////////////
64
65            if(i>2){
66                if(Command[i-2]=='+'&&Command[i-1]=='+'){
67                    //インクリメント
68                    variable[i-2]=0;
69                    IncDec(CALC_ADDITION,variable,"1");
70                    return;
71                }
72                else if(Command[i-2]=='-'&&Command[i-1]=='-'){
73                    //デクリメント
74                    variable[i-2]=0;
75                    IncDec(CALC_SUBTRACTION,variable,"1");
76                    return;
77                }
78            }
79
80
81            //先端部分の識別子をエラーキーワードにする
82            for(i=0;;i++){
83                if(!IsVariableChar(Command[i])){
84                    variable[i]=0;
85                    break;
86                }
87                variable[i]=Command[i];
88            }
89
90            if(GetVarType(variable,Type(),0)){
91                //変数リストに該当したとき
92                SetError(1,NULL,cp);
93            }
94            else{
95                if( compiler.GetObjectModule().meta.GetGlobalConsts().IsExist(variable)
96                    || compiler.GetObjectModule().meta.GetGlobalConstMacros().IsExist(variable) )
97                {
98                    //定数リストに該当したとき
99                    SetError(1,NULL,cp);
100                }
101                else{
102                    //変数リスト、定数リストに該当しないとき
103                    SetError(3,variable,cp);
104                }
105            }
106            return;
107        }
108
109        i2=GetCalcId(Command+i,&i3);
110        if(i2){
111            variable[i]=0;
112
113            if(Command[i]=='=') break;
114
115            if(Command[i+1+i3]=='='){
116                IncDec(i2,variable,Command+i+1+i3+1);
117                return;
118            }
119        }
120
121        variable[i]=Command[i];
122    }
123
124    if(Command[i+1]=='\0'){
125        SetError(1,NULL,cp);
126        return;
127    }
128
129
130
131    ///////////////////////////////////////////////////////////////
132    // インデクサのsetアクセサ([]=演算子のオーバーロードに対応)
133    ///////////////////////////////////////////////////////////////
134
135    char ObjName[VN_SIZE],array_element[VN_SIZE];
136    GetArrayElement(variable,ObjName,array_element);
137    if(array_element[0]){
138        Type varType;
139        if( GetVarType(ObjName,varType,0) && varType.IsObject() ){
140            char temporary[VN_SIZE];
141            sprintf(temporary,"%s.%c%c%c",ObjName,1,ESC_OPERATOR,CALC_ARRAY_SET);
142
143            char temp2[VN_SIZE];
144            sprintf(temp2,"%s,%s",array_element,Command+i+1);
145
146            int idProc;
147            void *pProc;
148            idProc=GetProc(temporary,(void **)&pProc);
149            if( idProc )
150            {
151                CallProc(
152                    idProc,
153                    pProc,
154                    temporary,
155                    temp2,
156                    Type(),         // ベースタイプはなし
157                    Type()
158                );
159                return;
160            }
161        }
162    }
163
164
165    if( lstrcmpi( variable, "This" ) == 0 ){
166        SetError(133,NULL,cp);
167        return;
168    }
169
170
171    ////////////////////////////////////////
172    // 変数のタイプ型を識別して、演算を行う
173    ////////////////////////////////////////
174
175    Type varType;
176
177    //型を識別
178    if( !GetTermTypeOnlyVariable(variable,varType) ){
179
180        // プロパティ用のメソッドを呼び出す
181        if(!CallPropertyMethod( variable, Command+i+1, Type() )){
182            //エラーを表示
183            GetVarType(variable,varType,true);
184        }
185
186        return;
187    }
188
189    //NumOpe...(rax、またはxmm0に答えが格納される)
190    int reg=REG_RAX;
191    Type calcType;
192    bool isNeedHeapFreeStructure;
193    if( !NumOpe(&reg,Command+i+1,varType,calcType,&isNeedHeapFreeStructure) ){
194        return;
195    }
196
197    if(reg!=REG_RAX&&calcType.IsWhole()||
198        varType.IsNull()||calcType.IsNull()){
199        SetError(300,NULL,cp);
200    }
201
202    //結果を格納しているレジスタをブロッキング
203    pobj_BlockReg->lock(reg);
204
205    //変数アドレスを取得
206    RELATIVE_VAR VarRelativeVar;
207    if( !TermOpeOnlyVariable( variable, varType, VarRelativeVar, true ) )
208    {
209        SetError();
210        return;
211    }
212
213    //レジスタのブロッキングを解除
214    pobj_BlockReg->clear();
215
216    if(varType.GetBasicType()&FLAG_PTR){
217        SetError(14,variable,cp);
218        return;
219    }
220
221    if( varType.IsStruct() ){
222        //構造体インスタンスへの代入
223        SetStructVariableFromRax(varType,calcType,&VarRelativeVar,isNeedHeapFreeStructure);
224        return;
225    }
226
227    if( calcType.IsObject() && !calcType.Equals( varType ) ){
228        bool isUpCast = false;
229        if( varType.IsObject() ){
230            if( varType.GetClass().IsEqualsOrSubClass( &calcType.GetClass() ) ){
231                isUpCast = true;
232            }
233        }
234        if( !isUpCast ){
235            //キャスト演算子のオーバーロードに対応する
236            CallCastOperatorProc(REG_RAX,calcType,isNeedHeapFreeStructure,varType);
237        }
238    }
239
240    if( varType.IsObject() && compiler.GetObjectModule().meta.GetBlittableTypes().IsExist( calcType ) ){
241        // Blittable型をオブジェクトとして扱う
242        vector<const UserProc *> userProcs;
243        compiler.GetObjectModule().meta.GetBlittableTypes().GetClass( calcType ).GetStaticMethods().Enum( "_Create", userProcs );
244        if( userProcs.size() != 1 ){
245            SetError();
246            return;
247        }
248        const UserProc *pUserProc = userProcs[0];
249
250        // mov rcx, rax
251        compiler.codeGenerator.op_mov_RR( REG_RCX, REG_RAX );
252
253        // call System.[TypeClass]._Create
254        compiler.codeGenerator.op_call( pUserProc );
255
256        calcType = pUserProc->ReturnType();
257    }
258
259    /////////////////////////////////
260    // 右辺、左辺の型チェックを行う
261    /////////////////////////////////
262
263    CheckDifferentType(varType,calcType,0,0);
264
265
266    /////////////////////////////////////////////////
267    // rax(実数はxmm0)の内容を変数にコピー
268    /////////////////////////////////////////////////
269    SetVariableFromRax(varType,calcType.GetBasicType(),&VarRelativeVar);
270
271
272    // コード生成過程で発生した構造体の一時メモリを破棄する
273    compiler.codeGenerator.op_FreeTempStructure();
274}
Note: See TracBrowser for help on using the repository browser.