source: dev/BasicCompiler32/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.4 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}
214
215void ChangeTypeToInt64(int OldType){
216 //現在のスタックの内容をInt64型に変換する
217 //NumOpeの直後専用
218 if(Is64Type(OldType)) return;
219
220 else if(OldType==DEF_DOUBLE){
221 //fld qword ptr[esp]
222 op_fld_ptr_esp(DEF_DOUBLE);
223
224 //fistp qword ptr[esp]
225 fpu_cast();
226 OpBuffer[obp++]=(char)0xDF;
227 OpBuffer[obp++]=(char)0x3C;
228 OpBuffer[obp++]=(char)0x24;
229 fpu_cast_end();
230 }
231 else if(OldType==DEF_SINGLE){
232 //fld dword ptr[esp]
233 op_fld_ptr_esp(DEF_SINGLE);
234
235 //sub esp,4
236 op_sub_esp(4);
237
238 //fistp qword ptr[esp]
239 fpu_cast();
240 OpBuffer[obp++]=(char)0xDF;
241 OpBuffer[obp++]=(char)0x3C;
242 OpBuffer[obp++]=(char)0x24;
243 fpu_cast_end();
244 }
245 else if(IsWholeNumberType(OldType)){
246 //その他整数
247
248 if(IsSignedType(OldType)){
249 //符号あり
250
251 //pop eax
252 op_pop(REG_EAX);
253
254 //cdq
255 op_cdq();
256
257 //push edx
258 op_push(REG_EDX);
259
260 //push eax
261 op_push(REG_EAX);
262 }
263 else{
264 //符号なし
265
266 //pop eax
267 op_pop(REG_EAX);
268
269 //push 0
270 op_push_value(0);
271
272 //push eax
273 op_push(REG_EAX);
274 }
275 }
276 else SetError(9,NULL,cp);
277}
278void ChangeTypeToLong(int OldType){
279 //現在のスタックの内容をLong型に変換する
280 //NumOpeの直後専用
281 if(OldType==DEF_DOUBLE){
282
283 //fld qword ptr[esp]
284 op_fld_ptr_esp(DEF_DOUBLE);
285
286 //add esp,4
287 op_add_esp(4);
288
289 //fistp dword ptr[esp]
290 fpu_cast();
291 OpBuffer[obp++]=(char)0xDB;
292 OpBuffer[obp++]=(char)0x1C;
293 OpBuffer[obp++]=(char)0x24;
294 fpu_cast_end();
295 }
296 else if(OldType==DEF_SINGLE){
297 //fld dword ptr[esp]
298 op_fld_ptr_esp(DEF_SINGLE);
299
300 //fistp dword ptr[esp]
301 fpu_cast();
302 OpBuffer[obp++]=(char)0xDB;
303 OpBuffer[obp++]=(char)0x1C;
304 OpBuffer[obp++]=(char)0x24;
305 fpu_cast_end();
306 }
307 else if(OldType==DEF_INT64||OldType==DEF_QWORD){
308 //pop eax
309 op_pop(REG_EAX);
310
311 //add esp,4
312 op_add_esp(4);
313
314 //push eax
315 op_push(REG_EAX);
316 }
317}
318void ChangeTypeToInteger(int OldType){
319 //現在のスタックの内容をInteger型に変換する
320 if(OldType==DEF_BYTE||
321 OldType==DEF_WORD||OldType==DEF_INTEGER) return;
322 else if(OldType==DEF_CHAR){
323 //pop eax
324 op_pop(REG_EAX);
325
326 //movsx eax,al
327 OpBuffer[obp++]=(char)0x0F;
328 OpBuffer[obp++]=(char)0xBE;
329 OpBuffer[obp++]=(char)0xC0;
330
331 //push eax
332 op_push(REG_EAX);
333 }
334 else{
335 ChangeTypeToLong(OldType);
336
337 //pop eax
338 op_pop(REG_EAX);
339
340 //and eax,0000FFFFh
341 OpBuffer[obp++]=(char)0x25;
342 *((long *)(OpBuffer+obp))=0x0000FFFF;
343 obp+=sizeof(long);
344
345 //push eax
346 op_push(REG_EAX);
347 }
348}
349void ChangeTypeToByte(int OldType){
350 //現在のスタックの内容をbyte型に変換する
351 if(OldType==DEF_BYTE||OldType==DEF_CHAR) return;
352
353 ChangeTypeToLong(OldType);
354
355 //pop eax
356 op_pop(REG_EAX);
357
358 //and eax,000000FFh
359 OpBuffer[obp++]=(char)0x25;
360 *((long *)(OpBuffer+obp))=0x000000FF;
361 obp+=sizeof(long);
362
363 //push eax
364 op_push(REG_EAX);
365}
366
367void OpcodeCalc(char *Command){
368 int i,i2,i3;
369 char variable[VN_SIZE];
370
371 for(i=0;;i++){
372 if(Command[i]=='\"'){
373 //ダブルクォートは不正なのでエラー扱い
374 variable[i]=0;
375 SetError(3,variable,cp);
376 return;
377 }
378
379 if(Command[i]=='('){
380 i2=GetStringInPare(variable+i,Command+i);
381 i+=i2-1;
382 continue;
383 }
384 if(Command[i]=='['){
385 i2=GetStringInBracket(variable+i,Command+i);
386 i+=i2-1;
387 continue;
388 }
389 if(Command[i]=='\0'){
390
391 ///////////////////////////////////
392 // インクリメント・デクリメント
393 ///////////////////////////////////
394
395 if(i>2){
396 if(Command[i-2]=='+'&&Command[i-1]=='+'){
397 //インクリメント
398 variable[i-2]=0;
399 IncDec(CALC_ADDITION,variable,"1");
400 return;
401 }
402 else if(Command[i-2]=='-'&&Command[i-1]=='-'){
403 //デクリメント
404 variable[i-2]=0;
405 IncDec(CALC_SUBTRACTION,variable,"1");
406 return;
407 }
408 }
409
410
411 //先端部分の識別子をエラーキーワードにする
412 for(i=0;;i++){
413 if(!IsVariableChar(Command[i])){
414 variable[i]=0;
415 break;
416 }
417 variable[i]=Command[i];
418 }
419
420 LONG_PTR lp;
421 if(GetVarType(variable,&lp,0)!=-1){
422 //変数リストに該当したとき
423 SetError(1,NULL,cp);
424 }
425 else{
426 if(GetConstHash(variable)){
427 //定数リストに該当したとき
428 SetError(1,NULL,cp);
429 }
430 else{
431 //変数リスト、定数リストに該当しないとき
432 SetError(3,variable,cp);
433 }
434 }
435 return;
436 }
437
438 i2=GetCalcId(Command+i,&i3);
439 if(i2){
440 variable[i]=0;
441
442 if(Command[i]=='=') break;
443
444 if(Command[i+1+i3]=='='){
445 IncDec(i2,variable,Command+i+1+i3+1);
446 return;
447 }
448 }
449
450 variable[i]=Command[i];
451 }
452
453 if(Command[i+1]=='\0'){
454 SetError(1,NULL,cp);
455 return;
456 }
457
458
459
460 ///////////////////////////////////////////////////////////////
461 // インデクサのsetアクセサ([]=演算子のオーバーロードに対応)
462 ///////////////////////////////////////////////////////////////
463
464 char ObjName[VN_SIZE],array_element[VN_SIZE];
465 CClass *pobj_c;
466 GetArrayElement(variable,ObjName,array_element);
467 if(array_element[0]){
468 i2=GetVarType(ObjName,(LONG_PTR *)&pobj_c,0);
469 if(i2==DEF_OBJECT){
470 char temporary[VN_SIZE];
471 sprintf(temporary,"%s.%c%c%c",ObjName,1,ESC_OPERATOR,CALC_ARRAY_SET);
472
473 char temp2[VN_SIZE];
474 sprintf(temp2,"%s,%s",array_element,Command+i+1);
475
476 int idProc;
477 void *pInfo;
478 idProc=GetProc(temporary,&pInfo);
479 if(idProc){
480 CallProc(idProc,pInfo,temporary,temp2,NULL);
481 return;
482 }
483 }
484 }
485
486
487
488 ////////////////////////////////////////
489 // 変数のタイプ型を識別して、演算を行う
490 ////////////////////////////////////////
491
492 int VarType,CalcType;
493 LONG_PTR lpVarIndex,lpCalcIndex;
494 RELATIVE_VAR VarRelativeVar;
495 BOOL bCalcUseHeap;
496
497 //型を識別
498 VarType=GetVarType(variable,&lpVarIndex,0);
499 if(VarType==-1){
500
501 // プロパティ用のメソッドを呼び出す
502 if(!CallPropertyMethod(variable,Command+i+1,NULL)){
503 //エラーを表示
504 GetVarType(variable,&lpVarIndex,1);
505 }
506
507 return;
508 }
509
510 extern LONG_PTR ProcPtr_BaseIndex;
511 if(VarType==DEF_PTR_PROC) ProcPtr_BaseIndex=lpVarIndex;
512 else ProcPtr_BaseIndex=-1;
513
514 if(VarType==DEF_OBJECT){
515 //代入演算のオーバーロード オペレータに備える
516
517 //変数アドレスを取得
518 if(!GetVarOffsetReadWrite(
519 variable,
520 &VarType,
521 &VarRelativeVar,
522 &lpVarIndex)) return;
523
524 SetVarPtrToEax(&VarRelativeVar);
525
526 //push eax
527 op_push(REG_EAX);
528 }
529
530
531 //NumOpe...(スタックに答えが格納される)
532 CalcType=NumOpe(Command+i+1,VarType,lpVarIndex,&lpCalcIndex,&bCalcUseHeap);
533 if(VarType==-1||CalcType==-1) return;
534
535 //変数アドレスを取得
536 if(!GetVarOffsetReadWrite(
537 variable,
538 &VarType,
539 &VarRelativeVar,
540 &lpVarIndex)) return;
541
542 if(VarType&FLAG_PTR){
543 SetError(14,variable,cp);
544 return;
545 }
546
547 if(VarType==DEF_OBJECT){
548 //オブジェクトインスタンスへの代入
549 SetObjectVariable(lpVarIndex,CalcType,lpCalcIndex,bCalcUseHeap);
550 return;
551 }
552
553 if(CalcType==DEF_OBJECT){
554 //キャスト演算子のオーバーロードに対応する
555 CallCastOperatorProc(CalcType,lpCalcIndex,bCalcUseHeap,VarType,lpVarIndex);
556 }
557
558
559
560 /////////////////////////////////
561 // 右辺、左辺の型チェックを行う
562 /////////////////////////////////
563
564 CheckDifferentType(VarType,lpVarIndex,CalcType,lpCalcIndex,0,0);
565
566
567 /////////////////////////////////////////////////
568 // スタックの内容を変数にコピーするコードを抽出
569 /////////////////////////////////////////////////
570
571 if(VarType==DEF_CHAR||VarType==DEF_BYTE){
572 //8ビット整数型変数へスタックの内容を格納する
573 Set8Variable(CalcType,VarRelativeVar.dwKind,VarRelativeVar.offset,VarRelativeVar.bOffsetOffset);
574 }
575 else if(VarType==DEF_INTEGER||VarType==DEF_WORD){
576 //16ビット整数型変数へスタックの内容を格納する
577 Set16Variable(CalcType,VarRelativeVar.dwKind,VarRelativeVar.offset,VarRelativeVar.bOffsetOffset);
578 }
579 else if(VarType==DEF_LONG||VarType==DEF_DWORD||IsPtrType(VarType)){
580 //32ビット整数型変数へスタックの内容を格納する
581 if(VarType==DEF_LONG)
582 SetLongVariable(CalcType,VarRelativeVar.dwKind,VarRelativeVar.offset,VarRelativeVar.bOffsetOffset);
583 else
584 SetDWordVariable(CalcType,VarRelativeVar.dwKind,VarRelativeVar.offset,VarRelativeVar.bOffsetOffset);
585 }
586 else if(VarType==DEF_INT64||VarType==DEF_QWORD){
587 //64ビット整数型変数へスタックの内容を格納する
588 SetInt64Variable(CalcType,&VarRelativeVar);
589 }
590 else if(VarType==DEF_DOUBLE){
591 //Double型変数へスタックの内容を格納する
592 SetDoubleVariable(CalcType,VarRelativeVar.dwKind,VarRelativeVar.offset,VarRelativeVar.bOffsetOffset);
593 }
594 else if(VarType==DEF_SINGLE){
595 //Single型変数へスタックの内容を格納する
596 SetSingleVariable(CalcType,VarRelativeVar.dwKind,VarRelativeVar.offset,VarRelativeVar.bOffsetOffset);
597 }
598}
Note: See TracBrowser for help on using the repository browser.