source: dev/BasicCompiler64/Compile_Calc.cpp@ 11

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

Const変数の書き込み規制を有効化(グローバル/ローカル変数のみ)
定数オブジェクトと定数メンバは未実装。

File size: 12.0 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2#include "Opcode.h"
3
4void ChangeTypeToDouble_ToFpuReg(int OldType){
5 //現在のスタックの内容を実数レジスタに保存する
6 //NumOpeの直後専用
7 if(OldType==DEF_DOUBLE){
8 //fld qword ptr[esp]
9 op_fld_ptr_esp(DEF_DOUBLE);
10
11 //add esp,8
12 op_add_esp(8);
13 }
14 else if(OldType==DEF_SINGLE){
15 //fld dword ptr[esp]
16 op_fld_ptr_esp(DEF_SINGLE);
17
18 //add esp,4
19 op_add_esp(4);
20 }
21 else if(OldType==DEF_LONG){
22 //fild dword ptr[esp]
23 op_fld_ptr_esp(DEF_LONG);
24
25 //add esp,4
26 op_add_esp(4);
27 }
28 else if(OldType==DEF_DWORD){
29 //pop eax
30 op_pop(REG_EAX);
31
32 //push 0
33 op_push_value(0);
34
35 //push eax
36 op_push(REG_EAX);
37
38 //fild qword ptr[esp]
39 OpBuffer[obp++]=(char)0xDF;
40 OpBuffer[obp++]=(char)0x2C;
41 OpBuffer[obp++]=(char)0x24;
42
43 //add esp,8
44 op_add_esp(8);
45 }
46}
47void ChangeTypeToDouble(int OldType){
48 //現在のスタックの内容をdouble型に変換する
49 //NumOpeの直後専用
50 if(OldType==DEF_DOUBLE) return;
51 else if(OldType==DEF_SINGLE){
52 //fld dword ptr[esp]
53 op_fld_ptr_esp(DEF_SINGLE);
54
55 //sub esp,4
56 op_sub_esp(4);
57
58 //fstp qword ptr[esp]
59 OpBuffer[obp++]=(char)0xDD;
60 OpBuffer[obp++]=(char)0x1C;
61 OpBuffer[obp++]=(char)0x24;
62 }
63 else if(OldType==DEF_INT64||OldType==DEF_QWORD){
64 //64ビット整数型
65
66 //fild qword ptr[esp]
67 op_fld_ptr_esp(DEF_INT64);
68
69 //fstp qword ptr[esp]
70 OpBuffer[obp++]=(char)0xDD;
71 OpBuffer[obp++]=(char)0x1C;
72 OpBuffer[obp++]=(char)0x24;
73 }
74 else if(IsWholeNumberType(OldType)){
75 //その他整数型
76
77 if(IsSignedType(OldType)){
78 //符号あり
79
80 if(OldType==DEF_INTEGER){
81 //pop eax
82 op_pop(REG_EAX);
83
84 //movsx eax,ax
85 OpBuffer[obp++]=(char)0x0F;
86 OpBuffer[obp++]=(char)0xBF;
87 OpBuffer[obp++]=(char)0xC0;
88
89 //push eax
90 op_push(REG_EAX);
91 }
92 else if(OldType==DEF_CHAR){
93 //pop eax
94 op_pop(REG_EAX);
95
96 //movsx eax,al
97 OpBuffer[obp++]=(char)0x0F;
98 OpBuffer[obp++]=(char)0xBE;
99 OpBuffer[obp++]=(char)0xC0;
100
101 //push eax
102 op_push(REG_EAX);
103 }
104
105 //fild dword ptr[esp]
106 op_fld_ptr_esp(DEF_LONG);
107
108 //sub esp,4
109 op_sub_esp(4);
110 }
111 else{
112 //符号なし
113
114 //pop eax
115 op_pop(REG_EAX);
116
117 //push 0
118 op_push_value(0);
119
120 //push eax
121 op_push(REG_EAX);
122
123 //fild qword ptr[esp]
124 OpBuffer[obp++]=(char)0xDF;
125 OpBuffer[obp++]=(char)0x2C;
126 OpBuffer[obp++]=(char)0x24;
127 }
128
129 //fstp qword ptr[esp]
130 OpBuffer[obp++]=(char)0xDD;
131 OpBuffer[obp++]=(char)0x1C;
132 OpBuffer[obp++]=(char)0x24;
133 }
134 else SetError(9,NULL,cp);
135}
136void ChangeTypeToSingle(int OldType){
137 //現在のスタックの内容をfloat型に変換する
138 //NumOpeの直後専用
139 if(OldType==DEF_SINGLE) return;
140 else if(OldType==DEF_DOUBLE){
141 //fld qword ptr[esp]
142 op_fld_ptr_esp(DEF_DOUBLE);
143
144 //add esp,4
145 op_add_esp(4);
146
147 //fstp dword ptr[esp]
148 OpBuffer[obp++]=(char)0xD9;
149 OpBuffer[obp++]=(char)0x1C;
150 OpBuffer[obp++]=(char)0x24;
151 }
152 else if(OldType==DEF_INT64||OldType==DEF_QWORD){
153 //64ビット整数型
154
155 //fild qword ptr[esp]
156 op_fld_ptr_esp(DEF_INT64);
157
158 //add esp,4
159 op_add_esp(4);
160
161 //fstp dword ptr[esp]
162 OpBuffer[obp++]=(char)0xD9;
163 OpBuffer[obp++]=(char)0x1C;
164 OpBuffer[obp++]=(char)0x24;
165 }
166 else if(IsWholeNumberType(OldType)){
167 //その他整数型
168
169 if(IsSignedType(OldType)){
170 //符号あり
171
172 if(OldType==DEF_INTEGER){
173 //pop eax
174 op_pop(REG_EAX);
175
176 //movsx eax,ax
177 OpBuffer[obp++]=(char)0x0F;
178 OpBuffer[obp++]=(char)0xBF;
179 OpBuffer[obp++]=(char)0xC0;
180
181 //push eax
182 op_push(REG_EAX);
183 }
184 else if(OldType==DEF_CHAR){
185 //pop eax
186 op_pop(REG_EAX);
187
188 //movsx eax,al
189 OpBuffer[obp++]=(char)0x0F;
190 OpBuffer[obp++]=(char)0xBE;
191 OpBuffer[obp++]=(char)0xC0;
192
193 //push eax
194 op_push(REG_EAX);
195 }
196
197 //fild dword ptr[esp]
198 op_fld_ptr_esp(DEF_LONG);
199 }
200 else{
201 //符号なし
202
203 //fild dword ptr[esp]
204 op_fld_ptr_esp(DEF_LONG);
205 }
206
207 //fstp dword ptr[esp]
208 OpBuffer[obp++]=(char)0xD9;
209 OpBuffer[obp++]=(char)0x1C;
210 OpBuffer[obp++]=(char)0x24;
211 }
212 else SetError(9,NULL,cp);
213}
214void ChangeTypeToInt64(int OldType){
215 //現在のスタックの内容をInt64型に変換する
216 //NumOpeの直後専用
217 if(Is64Type(OldType)) return;
218
219 else if(OldType==DEF_DOUBLE){
220 //fld qword ptr[esp]
221 op_fld_ptr_esp(DEF_DOUBLE);
222
223 //fistp qword ptr[esp]
224 OpBuffer[obp++]=(char)0xDF;
225 OpBuffer[obp++]=(char)0x3C;
226 OpBuffer[obp++]=(char)0x24;
227 }
228 else if(OldType==DEF_SINGLE){
229 //fld dword ptr[esp]
230 op_fld_ptr_esp(DEF_SINGLE);
231
232 //sub esp,4
233 op_sub_esp(4);
234
235 //fistp qword ptr[esp]
236 OpBuffer[obp++]=(char)0xDF;
237 OpBuffer[obp++]=(char)0x3C;
238 OpBuffer[obp++]=(char)0x24;
239 }
240 else if(IsWholeNumberType(OldType)){
241 //その他整数
242
243 if(IsSignedType(OldType)){
244 //符号あり
245
246 //pop eax
247 op_pop(REG_EAX);
248
249 //cdq
250 OpBuffer[obp++]=(char)0x99;
251
252 //push edx
253 op_push(REG_EDX);
254
255 //push eax
256 op_push(REG_EAX);
257 }
258 else{
259 //符号なし
260
261 //pop eax
262 op_pop(REG_EAX);
263
264 //push 0
265 op_push_value(0);
266
267 //push eax
268 op_push(REG_EAX);
269 }
270 }
271 else SetError(9,NULL,cp);
272}
273void ChangeTypeToLong(int OldType){
274 //現在のスタックの内容をLong型に変換する
275 //NumOpeの直後専用
276 if(OldType==DEF_DOUBLE){
277 //fld qword ptr[esp]
278 op_fld_ptr_esp(DEF_DOUBLE);
279
280 //add esp,4
281 op_add_esp(4);
282
283 //fistp dword ptr[esp]
284 OpBuffer[obp++]=(char)0xDB;
285 OpBuffer[obp++]=(char)0x1C;
286 OpBuffer[obp++]=(char)0x24;
287 }
288 else if(OldType==DEF_SINGLE){
289 //fld dword ptr[esp]
290 op_fld_ptr_esp(DEF_SINGLE);
291
292 //fistp dword ptr[esp]
293 OpBuffer[obp++]=(char)0xDB;
294 OpBuffer[obp++]=(char)0x1C;
295 OpBuffer[obp++]=(char)0x24;
296 }
297 else if(OldType==DEF_INT64||OldType==DEF_QWORD){
298 //pop eax
299 op_pop(REG_EAX);
300
301 //add esp,4
302 op_add_esp(4);
303
304 //push eax
305 op_push(REG_EAX);
306 }
307}
308void ChangeTypeToInteger(int OldType){
309 //現在のスタックの内容をInteger型に変換する
310 if(OldType==DEF_BYTE||OldType==DEF_CHAR||
311 OldType==DEF_WORD||OldType==DEF_INTEGER) return;
312
313 ChangeTypeToLong(OldType);
314
315 //pop eax
316 op_pop(REG_EAX);
317
318 //and eax,0000FFFFh
319 OpBuffer[obp++]=(char)0x25;
320 *((long *)(OpBuffer+obp))=0x0000FFFF;
321 obp+=sizeof(long);
322
323 //push eax
324 op_push(REG_EAX);
325}
326void ChangeTypeToByte(int OldType){
327 //現在のスタックの内容をbyte型に変換する
328 if(OldType==DEF_BYTE||OldType==DEF_CHAR) return;
329
330 ChangeTypeToLong(OldType);
331
332 //pop eax
333 op_pop(REG_EAX);
334
335 //and eax,000000FFh
336 OpBuffer[obp++]=(char)0x25;
337 *((long *)(OpBuffer+obp))=0x000000FF;
338 obp+=sizeof(long);
339
340 //push eax
341 op_push(REG_EAX);
342}
343
344void SetVariableFromRax(int VarType,int CalcType,RELATIVE_VAR *pRelativeVar){
345 /////////////////////////////////////////////////
346 // raxの内容を変数にコピーするコードを抽出
347 /////////////////////////////////////////////////
348
349 if(VarType==DEF_CHAR||VarType==DEF_BYTE){
350 //8ビット変数へalレジスタの内容を格納する
351 SetWholeVariable(sizeof(char),CalcType,pRelativeVar);
352 }
353 else if(VarType==DEF_INTEGER||VarType==DEF_WORD){
354 //16ビット変数へaxレジスタの内容を格納する
355 SetWholeVariable(sizeof(short),CalcType,pRelativeVar);
356 }
357 else if(VarType==DEF_LONG||VarType==DEF_DWORD){
358 //32ビット変数へeaxレジスタの内容を格納する
359 SetWholeVariable(sizeof(long),CalcType,pRelativeVar);
360 }
361 else if(VarType==DEF_INT64||VarType==DEF_QWORD||IsPtrType(VarType)){
362 //64ビット変数へraxレジスタの内容を格納する
363 SetWholeVariable(sizeof(_int64),CalcType,pRelativeVar);
364 }
365 else if(VarType==DEF_DOUBLE){
366 //Double型変数へスタックの内容を格納する
367 SetDoubleVariable(CalcType,pRelativeVar);
368 }
369 else if(VarType==DEF_SINGLE){
370 //Single型変数へスタックの内容を格納する
371 SetSingleVariable(CalcType,pRelativeVar);
372 }
373}
374void OpcodeCalc(char *Command){
375 int i,i2,i3;
376 char variable[VN_SIZE];
377
378
379
380 //////////////////////////////////////
381 // インクリメント・デクリメント
382 //////////////////////////////////////
383
384 for(i=0;;i++){
385 if(Command[i]=='\"'){
386 //ダブルクォートは不正なのでエラー扱い
387 variable[i]=0;
388 SetError(3,variable,cp);
389 return;
390 }
391
392 if(Command[i]=='('){
393 i2=GetStringInPare(variable+i,Command+i);
394 i+=i2-1;
395 continue;
396 }
397 if(Command[i]=='['){
398 i2=GetStringInBracket(variable+i,Command+i);
399 i+=i2-1;
400 continue;
401 }
402 if(Command[i]=='\0'){
403
404 ///////////////////////////////////
405 // インクリメント・デクリメント
406 ///////////////////////////////////
407
408 if(i>2){
409 if(Command[i-2]=='+'&&Command[i-1]=='+'){
410 //インクリメント
411 variable[i-2]=0;
412 IncDec(CALC_ADDITION,variable,"1");
413 return;
414 }
415 else if(Command[i-2]=='-'&&Command[i-1]=='-'){
416 //デクリメント
417 variable[i-2]=0;
418 IncDec(CALC_SUBTRACTION,variable,"1");
419 return;
420 }
421 }
422
423
424 //先端部分の識別子をエラーキーワードにする
425 for(i=0;;i++){
426 if(!IsVariableChar(Command[i])){
427 variable[i]=0;
428 break;
429 }
430 variable[i]=Command[i];
431 }
432
433 LONG_PTR lp;
434 if(GetVarType(variable,&lp,0)!=-1){
435 //変数リストに該当したとき
436 SetError(1,NULL,cp);
437 }
438 else{
439 if(GetConstHash(variable)){
440 //定数リストに該当したとき
441 SetError(1,NULL,cp);
442 }
443 else{
444 //変数リスト、定数リストに該当しないとき
445 SetError(3,variable,cp);
446 }
447 }
448 return;
449 }
450
451 i2=GetCalcId(Command+i,&i3);
452 if(i2){
453 variable[i]=0;
454
455 if(Command[i]=='=') break;
456
457 if(Command[i+1+i3]=='='){
458 IncDec(i2,variable,Command+i+1+i3+1);
459 return;
460 }
461 }
462
463 variable[i]=Command[i];
464 }
465
466 if(Command[i+1]=='\0'){
467 SetError(1,NULL,cp);
468 return;
469 }
470
471
472
473 ///////////////////////////////////////////////////////////////
474 // インデクサのsetアクセサ([]=演算子のオーバーロードに対応)
475 ///////////////////////////////////////////////////////////////
476
477 char ObjName[VN_SIZE],array_element[VN_SIZE];
478 CClass *pobj_c;
479 GetArrayElement(variable,ObjName,array_element);
480 if(array_element[0]){
481 i2=GetVarType(ObjName,(LONG_PTR *)&pobj_c,0);
482 if(i2==DEF_OBJECT){
483 char temporary[VN_SIZE];
484 sprintf(temporary,"%s.%c%c%c",ObjName,1,ESC_OPERATOR,CALC_ARRAY_SET);
485
486 char temp2[VN_SIZE];
487 sprintf(temp2,"%s,%s",array_element,Command+i+1);
488
489 int idProc;
490 void *pInfo;
491 idProc=GetProc(temporary,&pInfo);
492 if(idProc){
493 CallProc(idProc,pInfo,temporary,temp2,NULL);
494 return;
495 }
496 }
497 }
498
499
500
501 ////////////////////////////////////////
502 // 変数のタイプ型を識別して、演算を行う
503 ////////////////////////////////////////
504
505 int VarType,CalcType;
506 LONG_PTR lpVarIndex,lpCalcIndex;
507 BOOL bCalcUseHeap;
508
509 //型を識別
510 VarType=GetVarType(variable,&lpVarIndex,0);
511 if(VarType==-1){
512
513 // プロパティ用のメソッドを呼び出す
514 if(!CallPropertyMethod(variable,Command+i+1,NULL)){
515 //エラーを表示
516 GetVarType(variable,&lpVarIndex,1);
517 }
518
519 return;
520 }
521
522 extern LONG_PTR ProcPtr_BaseIndex;
523 if(VarType==DEF_PTR_PROC) ProcPtr_BaseIndex=lpVarIndex;
524 else ProcPtr_BaseIndex=-1;
525
526 //NumOpe...(rax、またはxmm0に答えが格納される)
527 int reg=REG_RAX;
528 CalcType=NumOpe(&reg,Command+i+1,VarType,lpVarIndex,&lpCalcIndex,&bCalcUseHeap);
529
530 //結果を格納しているレジスタをブロッキング
531 pobj_BlockReg->lock(reg);
532
533 if(VarType==-1||CalcType==-1) return;
534
535 //変数アドレスを取得
536 RELATIVE_VAR VarRelativeVar;
537 if(!GetVarOffsetReadWrite(
538 variable,
539 &VarType,
540 &VarRelativeVar,
541 &lpVarIndex)) return;
542
543 //レジスタのブロッキングを解除
544 pobj_BlockReg->clear();
545
546 if(VarType&FLAG_PTR){
547 SetError(14,variable,cp);
548 return;
549 }
550
551 if(VarType==DEF_OBJECT){
552 //オブジェクトインスタンスへの代入
553 SetObjectVariableFromRax(lpVarIndex,CalcType,lpCalcIndex,&VarRelativeVar,bCalcUseHeap);
554 return;
555 }
556
557 if(CalcType==DEF_OBJECT){
558 //キャスト演算子のオーバーロードに対応する
559 CallCastOperatorProc(REG_RAX,CalcType,lpCalcIndex,bCalcUseHeap,VarType,lpVarIndex);
560 }
561
562
563 /////////////////////////////////
564 // 右辺、左辺の型チェックを行う
565 /////////////////////////////////
566
567 CheckDifferentType(VarType,lpVarIndex,CalcType,lpCalcIndex,0,0);
568
569
570 /////////////////////////////////////////////////
571 // rax(実数はxmm0)の内容を変数にコピー
572 /////////////////////////////////////////////////
573 SetVariableFromRax(VarType,CalcType,&VarRelativeVar);
574}
Note: See TracBrowser for help on using the repository browser.