source: dev/trunk/ab5.0/abdev/BasicCompiler32/Compile_Calc.cpp@ 471

Last change on this file since 471 was 465, checked in by dai_9181, 17 years ago

Messenger/ErrorMessengerクラスを導入。SetError関数によるエラー生成を廃止した。

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