source: dev/BasicCompiler32/Compile_Calc.cpp@ 49

Last change on this file since 49 was 46, checked in by dai_9181, 18 years ago

VarPtrの戻り値の型をVoidPtrではなく、ポインタレベルを増加した型にした。
関連関数のパラメータにconstを適用。

File size: 15.8 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_BOOLEAN||
321 OldType==DEF_BYTE||
322 OldType==DEF_WORD||OldType==DEF_INTEGER) return;
323 else if(OldType==DEF_CHAR){
324 //pop eax
325 op_pop(REG_EAX);
326
327 //movsx eax,al
328 OpBuffer[obp++]=(char)0x0F;
329 OpBuffer[obp++]=(char)0xBE;
330 OpBuffer[obp++]=(char)0xC0;
331
332 //push eax
333 op_push(REG_EAX);
334 }
335 else{
336 ChangeTypeToLong(OldType);
337
338 //pop eax
339 op_pop(REG_EAX);
340
341 //and eax,0000FFFFh
342 OpBuffer[obp++]=(char)0x25;
343 *((long *)(OpBuffer+obp))=0x0000FFFF;
344 obp+=sizeof(long);
345
346 //push eax
347 op_push(REG_EAX);
348 }
349}
350void ChangeTypeToByte(int OldType){
351 //現在のスタックの内容をbyte型に変換する
352 if(OldType==DEF_BYTE||OldType==DEF_CHAR) return;
353
354 ChangeTypeToLong(OldType);
355
356 //pop eax
357 op_pop(REG_EAX);
358
359 //and eax,000000FFh
360 OpBuffer[obp++]=(char)0x25;
361 *((long *)(OpBuffer+obp))=0x000000FF;
362 obp+=sizeof(long);
363
364 //push eax
365 op_push(REG_EAX);
366}
367
368void OpcodeCalc(char *Command){
369 int i,i2,i3;
370 char variable[VN_SIZE];
371
372 for(i=0;;i++){
373 if(Command[i]=='\"'){
374 //ダブルクォートは不正なのでエラー扱い
375 variable[i]=0;
376 SetError(3,variable,cp);
377 return;
378 }
379
380 if(Command[i]=='('){
381 i2=GetStringInPare(variable+i,Command+i);
382 i+=i2-1;
383 continue;
384 }
385 if(Command[i]=='['){
386 i2=GetStringInBracket(variable+i,Command+i);
387 i+=i2-1;
388 continue;
389 }
390 if(Command[i]=='\0'){
391
392 ///////////////////////////////////
393 // インクリメント・デクリメント
394 ///////////////////////////////////
395
396 if(i>2){
397 if(Command[i-2]=='+'&&Command[i-1]=='+'){
398 //インクリメント
399 variable[i-2]=0;
400 IncDec(CALC_ADDITION,variable,"1");
401 return;
402 }
403 else if(Command[i-2]=='-'&&Command[i-1]=='-'){
404 //デクリメント
405 variable[i-2]=0;
406 IncDec(CALC_SUBTRACTION,variable,"1");
407 return;
408 }
409 }
410
411
412 //先端部分の識別子をエラーキーワードにする
413 for(i=0;;i++){
414 if(!IsVariableChar(Command[i])){
415 variable[i]=0;
416 break;
417 }
418 variable[i]=Command[i];
419 }
420
421 LONG_PTR lp;
422 if(GetVarType(variable,&lp,0)!=-1){
423 //変数リストに該当したとき
424 SetError(1,NULL,cp);
425 }
426 else{
427 if(GetConstHash(variable)){
428 //定数リストに該当したとき
429 SetError(1,NULL,cp);
430 }
431 else{
432 //変数リスト、定数リストに該当しないとき
433 SetError(3,variable,cp);
434 }
435 }
436 return;
437 }
438
439 i2=GetCalcId(Command+i,&i3);
440 if(i2){
441 variable[i]=0;
442
443 if(Command[i]=='=') break;
444
445 if(Command[i+1+i3]=='='){
446 IncDec(i2,variable,Command+i+1+i3+1);
447 return;
448 }
449 }
450
451 variable[i]=Command[i];
452 }
453
454 if(Command[i+1]=='\0'){
455 SetError(1,NULL,cp);
456 return;
457 }
458
459
460
461 ///////////////////////////////////////////////////////////////
462 // インデクサのsetアクセサ([]=演算子のオーバーロードに対応)
463 ///////////////////////////////////////////////////////////////
464
465 char ObjName[VN_SIZE],array_element[VN_SIZE];
466 CClass *pobj_c;
467 GetArrayElement(variable,ObjName,array_element);
468 if(array_element[0]){
469 i2=GetVarType(ObjName,(LONG_PTR *)&pobj_c,0);
470 if(i2==DEF_OBJECT){
471 char temporary[VN_SIZE];
472 sprintf(temporary,"%s.%c%c%c",ObjName,1,ESC_OPERATOR,CALC_ARRAY_SET);
473
474 char temp2[VN_SIZE];
475 sprintf(temp2,"%s,%s",array_element,Command+i+1);
476
477 int idProc;
478 void *pInfo;
479 idProc=GetProc(temporary,&pInfo);
480 if(idProc){
481 CallProc(idProc,pInfo,temporary,temp2,NULL);
482 return;
483 }
484 }
485 }
486
487 ////////////////////////////////////////
488 // 変数のタイプ型を識別して、演算を行う
489 ////////////////////////////////////////
490
491 int VarType,CalcType;
492 LONG_PTR lpVarIndex,lpCalcIndex;
493 RELATIVE_VAR VarRelativeVar;
494 BOOL bCalcUseHeap;
495
496 //型を識別
497 VarType=GetVarType(variable,&lpVarIndex,0);
498 if(VarType==-1){
499
500 // プロパティ用のメソッドを呼び出す
501 if(!CallPropertyMethod(variable,Command+i+1,NULL)){
502 //エラーを表示
503 GetVarType(variable,&lpVarIndex,1);
504 }
505
506 return;
507 }
508
509 extern LONG_PTR ProcPtr_BaseIndex;
510 if(VarType==DEF_PTR_PROC) ProcPtr_BaseIndex=lpVarIndex;
511 else ProcPtr_BaseIndex=-1;
512
513 if(VarType==DEF_OBJECT){
514 //代入演算のオーバーロード オペレータに備える
515
516 //変数アドレスを取得
517 if(!GetVarOffsetReadWrite(
518 variable,
519 &VarType,
520 &VarRelativeVar,
521 &lpVarIndex)) return;
522
523 SetVarPtrToEax(&VarRelativeVar);
524
525 //push eax
526 op_push(REG_EAX);
527 }
528
529
530 //NumOpe...(スタックに答えが格納される)
531 CalcType=NumOpe(Command+i+1,VarType,lpVarIndex,&lpCalcIndex,&bCalcUseHeap);
532 if(VarType==-1||CalcType==-1) return;
533
534 //変数アドレスを取得
535 if(!GetVarOffsetReadWrite(
536 variable,
537 &VarType,
538 &VarRelativeVar,
539 &lpVarIndex)) return;
540
541 if(VarType&FLAG_PTR){
542 SetError(14,variable,cp);
543 return;
544 }
545
546 if(VarType==DEF_OBJECT){
547 //オブジェクトインスタンスへの代入
548 SetObjectVariable(lpVarIndex,CalcType,lpCalcIndex,bCalcUseHeap);
549 return;
550 }
551
552 if(CalcType==DEF_OBJECT){
553 //キャスト演算子のオーバーロードに対応する
554 CallCastOperatorProc(CalcType,lpCalcIndex,bCalcUseHeap,VarType,lpVarIndex);
555 }
556
557
558
559 /////////////////////////////////
560 // 右辺、左辺の型チェックを行う
561 /////////////////////////////////
562
563 CheckDifferentType(VarType,lpVarIndex,CalcType,lpCalcIndex,0,0);
564
565
566 /////////////////////////////////////////////////
567 // スタックの内容を変数にコピーするコードを抽出
568 /////////////////////////////////////////////////
569
570 if(VarType==DEF_BOOLEAN){
571 //bool
572 SetBooleanVariable(CalcType,&VarRelativeVar);
573 }
574 else if(VarType==DEF_CHAR||VarType==DEF_BYTE){
575 //8ビット整数型変数へスタックの内容を格納する
576 Set8Variable(CalcType,VarRelativeVar.dwKind,VarRelativeVar.offset,VarRelativeVar.bOffsetOffset);
577 }
578 else if(VarType==DEF_INTEGER||VarType==DEF_WORD){
579 //16ビット整数型変数へスタックの内容を格納する
580 Set16Variable(CalcType,VarRelativeVar.dwKind,VarRelativeVar.offset,VarRelativeVar.bOffsetOffset);
581 }
582 else if(VarType==DEF_LONG||VarType==DEF_DWORD||IsPtrType(VarType)){
583 //32ビット整数型変数へスタックの内容を格納する
584 if(VarType==DEF_LONG)
585 SetLongVariable(CalcType,VarRelativeVar.dwKind,VarRelativeVar.offset,VarRelativeVar.bOffsetOffset);
586 else
587 SetDWordVariable(CalcType,VarRelativeVar.dwKind,VarRelativeVar.offset,VarRelativeVar.bOffsetOffset);
588 }
589 else if(VarType==DEF_INT64||VarType==DEF_QWORD){
590 //64ビット整数型変数へスタックの内容を格納する
591 SetInt64Variable(CalcType,&VarRelativeVar);
592 }
593 else if(VarType==DEF_DOUBLE){
594 //Double型変数へスタックの内容を格納する
595 SetDoubleVariable(CalcType,VarRelativeVar.dwKind,VarRelativeVar.offset,VarRelativeVar.bOffsetOffset);
596 }
597 else if(VarType==DEF_SINGLE){
598 //Single型変数へスタックの内容を格納する
599 SetSingleVariable(CalcType,VarRelativeVar.dwKind,VarRelativeVar.offset,VarRelativeVar.bOffsetOffset);
600 }
601}
602
603void SetRefVariable( const char *varname, const char *expression ){
604 ////////////////////////////////////////
605 // 変数のタイプ型を識別して、演算を行う
606 ////////////////////////////////////////
607
608 int VarType,CalcType;
609 LONG_PTR lpVarIndex,lpCalcIndex;
610 RELATIVE_VAR VarRelativeVar;
611 BOOL bCalcUseHeap;
612
613 //型を識別
614 VarType=GetVarType(varname,&lpVarIndex,0);
615 if(VarType==-1){
616 SetError(300,NULL,cp);
617 return;
618 }
619
620 extern LONG_PTR ProcPtr_BaseIndex;
621 if(VarType==DEF_PTR_PROC) ProcPtr_BaseIndex=lpVarIndex;
622 else ProcPtr_BaseIndex=-1;
623
624 if(VarType==DEF_OBJECT){
625 //代入演算のオーバーロード オペレータに備える
626
627 //変数アドレスを取得
628 if(!GetVarOffsetReadWrite(
629 varname,
630 &VarType,
631 &VarRelativeVar,
632 &lpVarIndex)) return;
633
634 SetVarPtrToEax(&VarRelativeVar);
635
636 //push eax
637 op_push(REG_EAX);
638 }
639
640
641 //NumOpe...(スタックに答えが格納される)
642 CalcType=NumOpe(expression,VarType,lpVarIndex,&lpCalcIndex,&bCalcUseHeap);
643 if(VarType==-1||CalcType==-1) return;
644
645 //変数アドレスを取得
646 if(!GetVarOffsetReadWrite(
647 varname,
648 &VarType,
649 &VarRelativeVar,
650 &lpVarIndex)) return;
651
652 if(VarType&FLAG_PTR){
653 SetError(14,varname,cp);
654 return;
655 }
656
657
658 if( VarType == DEF_OBJECT && VarRelativeVar.dwKind == VAR_REFLOCAL ){
659 // 参照型オブジェクトへの代入(初期化)はポインタ変数と同様の処理に値する
660 PTR_LEVEL_UP( VarType );
661
662 VarRelativeVar.dwKind = VAR_LOCAL;
663
664 if( CalcType == DEF_OBJECT ){
665 //右辺値が実体オブジェクトのときは、参照をコピー
666 PTR_LEVEL_UP( CalcType );
667 }
668 }
669 else{
670 SetError(300,NULL,cp);
671 }
672
673
674 /////////////////////////////////
675 // 右辺、左辺の型チェックを行う
676 /////////////////////////////////
677
678 CheckDifferentType(VarType,lpVarIndex,CalcType,lpCalcIndex,0,0);
679
680
681 /////////////////////////////////////////////////
682 // スタックの内容を変数にコピーするコードを抽出
683 /////////////////////////////////////////////////
684
685 if(VarType==DEF_BOOLEAN){
686 //bool
687 SetBooleanVariable(CalcType,&VarRelativeVar);
688 }
689 else if(VarType==DEF_CHAR||VarType==DEF_BYTE){
690 //8ビット整数型変数へスタックの内容を格納する
691 Set8Variable(CalcType,VarRelativeVar.dwKind,VarRelativeVar.offset,VarRelativeVar.bOffsetOffset);
692 }
693 else if(VarType==DEF_INTEGER||VarType==DEF_WORD){
694 //16ビット整数型変数へスタックの内容を格納する
695 Set16Variable(CalcType,VarRelativeVar.dwKind,VarRelativeVar.offset,VarRelativeVar.bOffsetOffset);
696 }
697 else if(VarType==DEF_LONG||VarType==DEF_DWORD||IsPtrType(VarType)){
698 //32ビット整数型変数へスタックの内容を格納する
699 if(VarType==DEF_LONG)
700 SetLongVariable(CalcType,VarRelativeVar.dwKind,VarRelativeVar.offset,VarRelativeVar.bOffsetOffset);
701 else
702 SetDWordVariable(CalcType,VarRelativeVar.dwKind,VarRelativeVar.offset,VarRelativeVar.bOffsetOffset);
703 }
704 else if(VarType==DEF_INT64||VarType==DEF_QWORD){
705 //64ビット整数型変数へスタックの内容を格納する
706 SetInt64Variable(CalcType,&VarRelativeVar);
707 }
708 else if(VarType==DEF_DOUBLE){
709 //Double型変数へスタックの内容を格納する
710 SetDoubleVariable(CalcType,VarRelativeVar.dwKind,VarRelativeVar.offset,VarRelativeVar.bOffsetOffset);
711 }
712 else if(VarType==DEF_SINGLE){
713 //Single型変数へスタックの内容を格納する
714 SetSingleVariable(CalcType,VarRelativeVar.dwKind,VarRelativeVar.offset,VarRelativeVar.bOffsetOffset);
715 }
716}
Note: See TracBrowser for help on using the repository browser.