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

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

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

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