source: dev/BasicCompiler64/Compile_Calc.cpp@ 135

Last change on this file since 135 was 135, checked in by dai_9181, 17 years ago

Method/Memberのリファクタリング

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