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

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

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

File size: 14.7 KB
RevLine 
[206]1#include "stdafx.h"
2
[183]3#include <jenga/include/smoothie/Smoothie.h>
4#include <jenga/include/smoothie/LexicalAnalysis.h>
5
[193]6#include <Compiler.h>
7
[3]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]
[225]16 compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);
[3]17
18 //add esp,8
[225]19 compiler.codeGenerator.op_add_esp(8);
[3]20 }
21 else if(OldType==DEF_SINGLE){
22 //fld dword ptr[esp]
[225]23 compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);
[3]24
25 //add esp,4
[225]26 compiler.codeGenerator.op_add_esp(4);
[3]27 }
28 else if(OldType==DEF_LONG){
29 //fild dword ptr[esp]
[225]30 compiler.codeGenerator.op_fld_ptr_esp(DEF_LONG);
[3]31
32 //add esp,4
[225]33 compiler.codeGenerator.op_add_esp(4);
[3]34 }
35 else if(OldType==DEF_DWORD){
36 //pop eax
[225]37 compiler.codeGenerator.op_pop(REG_EAX);
[3]38
39 //push 0
[225]40 compiler.codeGenerator.op_push_V(0);
[3]41
42 //push eax
[225]43 compiler.codeGenerator.op_push(REG_EAX);
[3]44
45 //fild qword ptr[esp]
[225]46 compiler.codeGenerator.PutOld(
47 (char)0xDF,
48 (char)0x2C,
49 (char)0x24
50 );
[3]51
52 //add esp,8
[225]53 compiler.codeGenerator.op_add_esp(8);
[3]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]
[225]62 compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);
[3]63
64 //sub esp,4
[225]65 compiler.codeGenerator.op_sub_esp(4);
[3]66
67 //fstp qword ptr[esp]
[225]68 compiler.codeGenerator.op_fstp_basereg( DEF_DOUBLE, REG_ESP );
[3]69 }
70 else if(OldType==DEF_INT64||OldType==DEF_QWORD){
71 //64ビット整数型
72
73 //fild qword ptr[esp]
[225]74 compiler.codeGenerator.op_fld_ptr_esp(DEF_INT64);
[3]75
76 //fstp qword ptr[esp]
[225]77 compiler.codeGenerator.op_fstp_basereg( DEF_DOUBLE, REG_ESP );
[3]78 }
79 else if(IsWholeNumberType(OldType)){
80 //その他整数型
81
82 if(IsSignedType(OldType)){
83 //符号あり
84
[183]85 if(OldType==DEF_INTEGER || (Smoothie::IsUnicode()&&OldType==DEF_CHAR)){
[3]86 //pop eax
[225]87 compiler.codeGenerator.op_pop(REG_EAX);
[3]88
89 //movsx eax,ax
[225]90 compiler.codeGenerator.op_movsx_R32R16( REG_EAX );
[3]91
92 //push eax
[225]93 compiler.codeGenerator.op_push(REG_EAX);
[3]94 }
[183]95 else if(OldType==DEF_SBYTE || (Smoothie::IsUnicode()==false&&OldType==DEF_CHAR)){
[3]96 //pop eax
[225]97 compiler.codeGenerator.op_pop(REG_EAX);
[3]98
99 //movsx eax,al
[225]100 compiler.codeGenerator.op_movsx_R32R8( REG_EAX );
[3]101
102 //push eax
[225]103 compiler.codeGenerator.op_push(REG_EAX);
[3]104 }
105
106 //fild dword ptr[esp]
[225]107 compiler.codeGenerator.op_fld_ptr_esp(DEF_LONG);
[3]108
109 //sub esp,4
[225]110 compiler.codeGenerator.op_sub_esp(4);
[3]111 }
112 else{
113 //符号なし
114
115 //pop eax
[225]116 compiler.codeGenerator.op_pop(REG_EAX);
[3]117
118 //push 0
[225]119 compiler.codeGenerator.op_push_V(0);
[3]120
121 //push eax
[225]122 compiler.codeGenerator.op_push(REG_EAX);
[3]123
124 //fild qword ptr[esp]
[225]125 compiler.codeGenerator.PutOld(
126 (char)0xDF,
127 (char)0x2C,
128 (char)0x24
129 );
[3]130 }
131
132 //fstp qword ptr[esp]
[225]133 compiler.codeGenerator.op_fstp_basereg( DEF_DOUBLE, REG_ESP );
[3]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]
[225]143 compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);
[3]144
145 //add esp,4
[225]146 compiler.codeGenerator.op_add_esp(4);
[3]147
148 //fstp dword ptr[esp]
[225]149 compiler.codeGenerator.op_fstp_basereg( DEF_SINGLE, REG_ESP );
[3]150 }
151 else if(OldType==DEF_INT64||OldType==DEF_QWORD){
152 //64ビット整数型
153
154 //fild qword ptr[esp]
[225]155 compiler.codeGenerator.op_fld_ptr_esp(DEF_INT64);
[3]156
157 //add esp,4
[225]158 compiler.codeGenerator.op_add_esp(4);
[3]159
160 //fstp dword ptr[esp]
[225]161 compiler.codeGenerator.op_fstp_basereg( DEF_SINGLE, REG_ESP );
[3]162 }
163 else if(IsWholeNumberType(OldType)){
164 //その他整数型
165
166 if(IsSignedType(OldType)){
167 //符号あり
168
[183]169 if(OldType==DEF_INTEGER || (Smoothie::IsUnicode()&&OldType==DEF_CHAR)){
[3]170 //pop eax
[225]171 compiler.codeGenerator.op_pop(REG_EAX);
[3]172
173 //movsx eax,ax
[225]174 compiler.codeGenerator.op_movsx_R32R16( REG_EAX );
[3]175
176 //push eax
[225]177 compiler.codeGenerator.op_push(REG_EAX);
[3]178 }
[183]179 else if(OldType==DEF_SBYTE || (Smoothie::IsUnicode()==false&&OldType==DEF_CHAR)){
[3]180 //pop eax
[225]181 compiler.codeGenerator.op_pop(REG_EAX);
[3]182
183 //movsx eax,al
[225]184 compiler.codeGenerator.op_movsx_R32R8( REG_EAX );
[3]185
186 //push eax
[225]187 compiler.codeGenerator.op_push(REG_EAX);
[3]188 }
189
190 //fild dword ptr[esp]
[225]191 compiler.codeGenerator.op_fld_ptr_esp(DEF_LONG);
[3]192 }
193 else{
194 //符号なし
195
196 //fild dword ptr[esp]
[225]197 compiler.codeGenerator.op_fld_ptr_esp(DEF_LONG);
[3]198 }
199
200 //fstp dword ptr[esp]
[225]201 compiler.codeGenerator.op_fstp_basereg( DEF_SINGLE, REG_ESP );
[3]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]
[225]213 compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);
[3]214
215 //fistp qword ptr[esp]
[225]216 compiler.codeGenerator.op_fistp_ptr_esp( sizeof(_int64) );
[3]217 }
218 else if(OldType==DEF_SINGLE){
219 //fld dword ptr[esp]
[225]220 compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);
[3]221
222 //sub esp,4
[225]223 compiler.codeGenerator.op_sub_esp(4);
[3]224
225 //fistp qword ptr[esp]
[225]226 compiler.codeGenerator.op_fistp_ptr_esp( sizeof(_int64) );
[3]227 }
228 else if(IsWholeNumberType(OldType)){
229 //その他整数
230
231 if(IsSignedType(OldType)){
232 //符号あり
233
234 //pop eax
[225]235 compiler.codeGenerator.op_pop(REG_EAX);
[3]236
237 //cdq
[225]238 compiler.codeGenerator.op_cdq();
[3]239
240 //push edx
[225]241 compiler.codeGenerator.op_push(REG_EDX);
[3]242
243 //push eax
[225]244 compiler.codeGenerator.op_push(REG_EAX);
[3]245 }
246 else{
247 //符号なし
248
249 //pop eax
[225]250 compiler.codeGenerator.op_pop(REG_EAX);
[3]251
252 //push 0
[225]253 compiler.codeGenerator.op_push_V(0);
[3]254
255 //push eax
[225]256 compiler.codeGenerator.op_push(REG_EAX);
[3]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]
[225]267 compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);
[3]268
269 //add esp,4
[225]270 compiler.codeGenerator.op_add_esp(4);
[3]271
272 //fistp dword ptr[esp]
[225]273 compiler.codeGenerator.op_fistp_ptr_esp( sizeof(long) );
[3]274 }
275 else if(OldType==DEF_SINGLE){
276 //fld dword ptr[esp]
[225]277 compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);
[3]278
279 //fistp dword ptr[esp]
[225]280 compiler.codeGenerator.op_fistp_ptr_esp( sizeof(long) );
[3]281 }
282 else if(OldType==DEF_INT64||OldType==DEF_QWORD){
283 //pop eax
[225]284 compiler.codeGenerator.op_pop(REG_EAX);
[3]285
286 //add esp,4
[225]287 compiler.codeGenerator.op_add_esp(4);
[3]288
289 //push eax
[225]290 compiler.codeGenerator.op_push(REG_EAX);
[3]291 }
292}
293void ChangeTypeToInteger(int OldType){
294 //現在のスタックの内容をInteger型に変換する
[36]295 if(OldType==DEF_BOOLEAN||
296 OldType==DEF_BYTE||
[183]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)){
[3]299 //pop eax
[225]300 compiler.codeGenerator.op_pop(REG_EAX);
[3]301
302 //movsx eax,al
[225]303 compiler.codeGenerator.op_movsx_R32R8( REG_EAX );
[3]304
305 //push eax
[225]306 compiler.codeGenerator.op_push(REG_EAX);
[3]307 }
308 else{
309 ChangeTypeToLong(OldType);
310
311 //pop eax
[225]312 compiler.codeGenerator.op_pop(REG_EAX);
[3]313
314 //and eax,0000FFFFh
[225]315 compiler.codeGenerator.op_and_RV( REG_EAX, 0x0000FFFF );
[3]316
317 //push eax
[225]318 compiler.codeGenerator.op_push(REG_EAX);
[3]319 }
320}
321void ChangeTypeToByte(int OldType){
322 //現在のスタックの内容をbyte型に変換する
[183]323 if(OldType==DEF_BYTE||OldType==DEF_SBYTE || (Smoothie::IsUnicode()==false&&OldType==DEF_CHAR)) return;
[3]324
325 ChangeTypeToLong(OldType);
326
327 //pop eax
[225]328 compiler.codeGenerator.op_pop(REG_EAX);
[3]329
330 //and eax,000000FFh
[225]331 compiler.codeGenerator.op_and_RV( REG_EAX, 0x000000FF );
[3]332
333 //push eax
[225]334 compiler.codeGenerator.op_push(REG_EAX);
[3]335}
336
[64]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]
[225]350 compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);
[64]351
352 //add esp,8
[225]353 compiler.codeGenerator.op_add_esp(8);
[64]354 }
355 else if(type==DEF_SINGLE){
356 //fld dword ptr[esp]
[225]357 compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);
[64]358
359 //add esp,4
[225]360 compiler.codeGenerator.op_add_esp(4);
[64]361 }
362 else if( Is64Type( type ) ){
363 //pop eax
[225]364 compiler.codeGenerator.op_pop(REG_EAX);
[64]365
366 //pop edx
[225]367 compiler.codeGenerator.op_pop(REG_EDX);
[64]368 }
369 else{
370 //pop eax
[225]371 compiler.codeGenerator.op_pop(REG_EAX);
[64]372 }
373}
374
[290]375void SetVariableFromEax( const Type &varType,int CalcType,RELATIVE_VAR *pRelativeVar){
[64]376 /////////////////////////////////////////////////
377 // eaxの内容を変数にコピーするコードを抽出
378 /////////////////////////////////////////////////
379
[290]380 if( varType.IsBoolean() )
381 {
[64]382 //bool
383 SetBooleanVariable(CalcType,pRelativeVar);
384 }
[290]385 else if( varType.IsReal() )
386 {
[64]387 // Double/Single型変数へレジスタの値を代入
[290]388 SetRealVariable(varType.GetBasicType(), CalcType, pRelativeVar);
[64]389 }
[290]390 else if( varType.IsWhole() || varType.IsObject() )
391 {
392 int typeSize = varType.GetSize();
[64]393
394 //整数変数へraxの値を格納する
395 SetWholeVariable( typeSize, CalcType, pRelativeVar );
396 }
397 else{
398 SetError(300,NULL,cp);
399 }
400}
401
[129]402void OpcodeCalc( const char *Command ){
[3]403 int i,i2,i3;
404 char variable[VN_SIZE];
405
[75]406
407
408 //////////////////////////////////////
409 // インクリメント・デクリメント
410 //////////////////////////////////////
411
[3]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
[75]461 if(GetVarType(variable,Type(),0)){
[3]462 //変数リストに該当したとき
463 SetError(1,NULL,cp);
464 }
465 else{
[265]466 if( compiler.GetObjectModule().meta.GetGlobalConsts().IsExist(variable)
467 || compiler.GetObjectModule().meta.GetGlobalConstMacros().IsExist(variable) )
[206]468 {
[3]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]){
[75]508 Type varType;
509 if( GetVarType(ObjName,varType,0) && varType.IsObject() ){
[3]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;
[75]517 void *pProc;
518 idProc=GetProc(temporary,(void **)&pProc);
[331]519 if( idProc )
520 {
521 CallProc(
522 idProc,
523 pProc,
524 temporary,
525 temp2,
526 Type(), // ベースタイプはなし
527 Type()
528 );
[3]529 return;
530 }
531 }
532 }
533
[64]534
535 if( lstrcmpi( variable, "This" ) == 0 ){
536 SetError(133,NULL,cp);
537 return;
538 }
539
540
[3]541 ////////////////////////////////////////
542 // 変数のタイプ型を識別して、演算を行う
543 ////////////////////////////////////////
544
[75]545 Type varType;
[3]546
547 //型を識別
[75]548 if( !GetVarType(variable,varType,false) ){
[3]549
550 // プロパティ用のメソッドを呼び出す
[75]551 if(!CallPropertyMethod( variable, Command+i+1, Type() )){
[3]552 //エラーを表示
[75]553 GetVarType(variable,varType,true);
[3]554 }
555
556 return;
557 }
558
[75]559 RELATIVE_VAR VarRelativeVar;
560 if( varType.IsStruct() ){
[64]561 //代入コピーに備える
[3]562
563 //変数アドレスを取得
[11]564 if(!GetVarOffsetReadWrite(
[3]565 variable,
566 &VarRelativeVar,
[75]567 varType)) return;
[3]568
569 SetVarPtrToEax(&VarRelativeVar);
570
571 //push eax
[225]572 compiler.codeGenerator.op_push(REG_EAX);
[3]573 }
574
575
576 //NumOpe...(スタックに答えが格納される)
[75]577 BOOL bCalcUseHeap;
578 Type calcType;
579 if( !NumOpe(Command+i+1,varType,calcType,&bCalcUseHeap) ){
580 return;
581 }
[3]582
[179]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
[3]596 //変数アドレスを取得
[11]597 if(!GetVarOffsetReadWrite(
[3]598 variable,
599 &VarRelativeVar,
[75]600 varType)) return;
[3]601
[75]602 if(varType.GetBasicType()&FLAG_PTR){
[3]603 SetError(14,variable,cp);
604 return;
605 }
606
[75]607 if( varType.IsStruct() ){
608 //構造体インスタンスへの代入
609 SetStructVariable(varType,calcType,bCalcUseHeap);
[3]610 return;
611 }
612
613
[265]614 if( varType.IsObject() && compiler.GetObjectModule().meta.GetBlittableTypes().IsExist( calcType ) ){
[128]615 // Blittable型をオブジェクトとして扱う
[206]616 vector<const UserProc *> userProcs;
[265]617 compiler.GetObjectModule().meta.GetBlittableTypes().GetClass( calcType ).GetStaticMethods().Enum( "_Create", userProcs );
[128]618 if( userProcs.size() != 1 ){
619 SetError();
620 return;
621 }
[206]622 const UserProc *pUserProc = userProcs[0];
[3]623
[128]624 // call System.[TypeClass]._Create
[225]625 compiler.codeGenerator.op_call( pUserProc );
[128]626
627 // push eax
[225]628 compiler.codeGenerator.op_push( REG_EAX );
[128]629
630 calcType = pUserProc->ReturnType();
631 }
632
633
[3]634 /////////////////////////////////
635 // 右辺、左辺の型チェックを行う
636 /////////////////////////////////
637
[75]638 CheckDifferentType(varType,calcType,0,0);
[3]639
640
641 /////////////////////////////////////////////////
642 // スタックの内容を変数にコピーするコードを抽出
643 /////////////////////////////////////////////////
644
[64]645 //eax、edx:eax、またはst(0)にスタック上のデータを取り出す
[75]646 RestoreDefaultRegisterFromStackMemory( calcType.GetBasicType() );
[64]647
[290]648 SetVariableFromEax(varType,calcType.GetBasicType(),&VarRelativeVar);
[3]649}
Note: See TracBrowser for help on using the repository browser.