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

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

AddressOfの左辺値を加味した処理を簡潔にした

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