source: dev/trunk/abdev/BasicCompiler32/Compile_Calc.cpp@ 220

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

コード全体のリファクタリングを実施

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