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

Last change on this file since 244 was 225, checked in by dai_9181, 17 years ago

CodeGeneratorクラスのベースを実装

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
375void SetVariableFromEax(int VarType,int CalcType,RELATIVE_VAR *pRelativeVar){
376 /////////////////////////////////////////////////
377 // eaxの内容を変数にコピーするコードを抽出
378 /////////////////////////////////////////////////
379
380 if(VarType==DEF_BOOLEAN){
381 //bool
382 SetBooleanVariable(CalcType,pRelativeVar);
383 }
384 else if( IsRealNumberType( VarType ) ){
385 // Double/Single型変数へレジスタの値を代入
386 SetRealVariable(VarType, CalcType, pRelativeVar);
387 }
388 else if( IsWholeNumberType( VarType ) || VarType == DEF_OBJECT ){
389 int typeSize = GetTypeSize( VarType, -1 );
390
391 //整数変数へraxの値を格納する
392 SetWholeVariable( typeSize, CalcType, pRelativeVar );
393 }
394 else{
395 SetError(300,NULL,cp);
396 }
397}
398
[129]399void OpcodeCalc( const char *Command ){
[3]400 int i,i2,i3;
401 char variable[VN_SIZE];
402
[75]403
404
405 //////////////////////////////////////
406 // インクリメント・デクリメント
407 //////////////////////////////////////
408
[3]409 for(i=0;;i++){
410 if(Command[i]=='\"'){
411 //ダブルクォートは不正なのでエラー扱い
412 variable[i]=0;
413 SetError(3,variable,cp);
414 return;
415 }
416
417 if(Command[i]=='('){
418 i2=GetStringInPare(variable+i,Command+i);
419 i+=i2-1;
420 continue;
421 }
422 if(Command[i]=='['){
423 i2=GetStringInBracket(variable+i,Command+i);
424 i+=i2-1;
425 continue;
426 }
427 if(Command[i]=='\0'){
428
429 ///////////////////////////////////
430 // インクリメント・デクリメント
431 ///////////////////////////////////
432
433 if(i>2){
434 if(Command[i-2]=='+'&&Command[i-1]=='+'){
435 //インクリメント
436 variable[i-2]=0;
437 IncDec(CALC_ADDITION,variable,"1");
438 return;
439 }
440 else if(Command[i-2]=='-'&&Command[i-1]=='-'){
441 //デクリメント
442 variable[i-2]=0;
443 IncDec(CALC_SUBTRACTION,variable,"1");
444 return;
445 }
446 }
447
448
449 //先端部分の識別子をエラーキーワードにする
450 for(i=0;;i++){
451 if(!IsVariableChar(Command[i])){
452 variable[i]=0;
453 break;
454 }
455 variable[i]=Command[i];
456 }
457
[75]458 if(GetVarType(variable,Type(),0)){
[3]459 //変数リストに該当したとき
460 SetError(1,NULL,cp);
461 }
462 else{
[206]463 if( compiler.GetMeta().GetGlobalConsts().IsExist(variable)
464 || compiler.GetMeta().GetGlobalConstMacros().IsExist(variable) )
465 {
[3]466 //定数リストに該当したとき
467 SetError(1,NULL,cp);
468 }
469 else{
470 //変数リスト、定数リストに該当しないとき
471 SetError(3,variable,cp);
472 }
473 }
474 return;
475 }
476
477 i2=GetCalcId(Command+i,&i3);
478 if(i2){
479 variable[i]=0;
480
481 if(Command[i]=='=') break;
482
483 if(Command[i+1+i3]=='='){
484 IncDec(i2,variable,Command+i+1+i3+1);
485 return;
486 }
487 }
488
489 variable[i]=Command[i];
490 }
491
492 if(Command[i+1]=='\0'){
493 SetError(1,NULL,cp);
494 return;
495 }
496
497
498
499 ///////////////////////////////////////////////////////////////
500 // インデクサのsetアクセサ([]=演算子のオーバーロードに対応)
501 ///////////////////////////////////////////////////////////////
502
503 char ObjName[VN_SIZE],array_element[VN_SIZE];
504 GetArrayElement(variable,ObjName,array_element);
505 if(array_element[0]){
[75]506 Type varType;
507 if( GetVarType(ObjName,varType,0) && varType.IsObject() ){
[3]508 char temporary[VN_SIZE];
509 sprintf(temporary,"%s.%c%c%c",ObjName,1,ESC_OPERATOR,CALC_ARRAY_SET);
510
511 char temp2[VN_SIZE];
512 sprintf(temp2,"%s,%s",array_element,Command+i+1);
513
514 int idProc;
[75]515 void *pProc;
516 idProc=GetProc(temporary,(void **)&pProc);
[3]517 if(idProc){
[75]518 CallProc(idProc,pProc,temporary,temp2,Type());
[3]519 return;
520 }
521 }
522 }
523
[64]524
525 if( lstrcmpi( variable, "This" ) == 0 ){
526 SetError(133,NULL,cp);
527 return;
528 }
529
530
[3]531 ////////////////////////////////////////
532 // 変数のタイプ型を識別して、演算を行う
533 ////////////////////////////////////////
534
[75]535 Type varType;
[3]536
537 //型を識別
[75]538 if( !GetVarType(variable,varType,false) ){
[3]539
540 // プロパティ用のメソッドを呼び出す
[75]541 if(!CallPropertyMethod( variable, Command+i+1, Type() )){
[3]542 //エラーを表示
[75]543 GetVarType(variable,varType,true);
[3]544 }
545
546 return;
547 }
548
549 extern LONG_PTR ProcPtr_BaseIndex;
[75]550 if(varType.IsProcPtr()) ProcPtr_BaseIndex=varType.GetIndex();
[3]551 else ProcPtr_BaseIndex=-1;
552
[75]553 RELATIVE_VAR VarRelativeVar;
554 if( varType.IsStruct() ){
[64]555 //代入コピーに備える
[3]556
557 //変数アドレスを取得
[11]558 if(!GetVarOffsetReadWrite(
[3]559 variable,
560 &VarRelativeVar,
[75]561 varType)) return;
[3]562
563 SetVarPtrToEax(&VarRelativeVar);
564
565 //push eax
[225]566 compiler.codeGenerator.op_push(REG_EAX);
[3]567 }
568
569
570 //NumOpe...(スタックに答えが格納される)
[75]571 BOOL bCalcUseHeap;
572 Type calcType;
573 if( !NumOpe(Command+i+1,varType,calcType,&bCalcUseHeap) ){
574 return;
575 }
[3]576
[179]577 if( calcType.IsObject() && !calcType.Equals( varType ) ){
578 bool isUpCast = false;
579 if( varType.IsObject() ){
580 if( varType.GetClass().IsEqualsOrSubClass( &calcType.GetClass() ) ){
581 isUpCast = true;
582 }
583 }
584 if( !isUpCast ){
585 //キャスト演算子のオーバーロードに対応する
586 CallCastOperatorProc(calcType,bCalcUseHeap,varType);
587 }
588 }
589
[3]590 //変数アドレスを取得
[11]591 if(!GetVarOffsetReadWrite(
[3]592 variable,
593 &VarRelativeVar,
[75]594 varType)) return;
[3]595
[75]596 if(varType.GetBasicType()&FLAG_PTR){
[3]597 SetError(14,variable,cp);
598 return;
599 }
600
[75]601 if( varType.IsStruct() ){
602 //構造体インスタンスへの代入
603 SetStructVariable(varType,calcType,bCalcUseHeap);
[3]604 return;
605 }
606
607
[193]608 if( varType.IsObject() && compiler.GetMeta().GetBlittableTypes().IsExist( calcType ) ){
[128]609 // Blittable型をオブジェクトとして扱う
[206]610 vector<const UserProc *> userProcs;
[193]611 compiler.GetMeta().GetBlittableTypes().GetClass( calcType ).GetStaticMethods().Enum( "_Create", userProcs );
[128]612 if( userProcs.size() != 1 ){
613 SetError();
614 return;
615 }
[206]616 const UserProc *pUserProc = userProcs[0];
[3]617
[128]618 // call System.[TypeClass]._Create
[225]619 compiler.codeGenerator.op_call( pUserProc );
[128]620
621 // push eax
[225]622 compiler.codeGenerator.op_push( REG_EAX );
[128]623
624 calcType = pUserProc->ReturnType();
625 }
626
627
[3]628 /////////////////////////////////
629 // 右辺、左辺の型チェックを行う
630 /////////////////////////////////
631
[75]632 CheckDifferentType(varType,calcType,0,0);
[3]633
634
635 /////////////////////////////////////////////////
636 // スタックの内容を変数にコピーするコードを抽出
637 /////////////////////////////////////////////////
638
[64]639 //eax、edx:eax、またはst(0)にスタック上のデータを取り出す
[75]640 RestoreDefaultRegisterFromStackMemory( calcType.GetBasicType() );
[64]641
[75]642 SetVariableFromEax(varType.GetBasicType(),calcType.GetBasicType(),&VarRelativeVar);
[3]643}
Note: See TracBrowser for help on using the repository browser.