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

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

CodeGeneratorクラスのベースを実装

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(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
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 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
458 if(GetVarType(variable,Type(),0)){
459 //変数リストに該当したとき
460 SetError(1,NULL,cp);
461 }
462 else{
463 if( compiler.GetMeta().GetGlobalConsts().IsExist(variable)
464 || compiler.GetMeta().GetGlobalConstMacros().IsExist(variable) )
465 {
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]){
506 Type varType;
507 if( GetVarType(ObjName,varType,0) && varType.IsObject() ){
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;
515 void *pProc;
516 idProc=GetProc(temporary,(void **)&pProc);
517 if(idProc){
518 CallProc(idProc,pProc,temporary,temp2,Type());
519 return;
520 }
521 }
522 }
523
524
525 if( lstrcmpi( variable, "This" ) == 0 ){
526 SetError(133,NULL,cp);
527 return;
528 }
529
530
531 ////////////////////////////////////////
532 // 変数のタイプ型を識別して、演算を行う
533 ////////////////////////////////////////
534
535 Type varType;
536
537 //型を識別
538 if( !GetVarType(variable,varType,false) ){
539
540 // プロパティ用のメソッドを呼び出す
541 if(!CallPropertyMethod( variable, Command+i+1, Type() )){
542 //エラーを表示
543 GetVarType(variable,varType,true);
544 }
545
546 return;
547 }
548
549 extern LONG_PTR ProcPtr_BaseIndex;
550 if(varType.IsProcPtr()) ProcPtr_BaseIndex=varType.GetIndex();
551 else ProcPtr_BaseIndex=-1;
552
553 RELATIVE_VAR VarRelativeVar;
554 if( varType.IsStruct() ){
555 //代入コピーに備える
556
557 //変数アドレスを取得
558 if(!GetVarOffsetReadWrite(
559 variable,
560 &VarRelativeVar,
561 varType)) return;
562
563 SetVarPtrToEax(&VarRelativeVar);
564
565 //push eax
566 compiler.codeGenerator.op_push(REG_EAX);
567 }
568
569
570 //NumOpe...(スタックに答えが格納される)
571 BOOL bCalcUseHeap;
572 Type calcType;
573 if( !NumOpe(Command+i+1,varType,calcType,&bCalcUseHeap) ){
574 return;
575 }
576
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
590 //変数アドレスを取得
591 if(!GetVarOffsetReadWrite(
592 variable,
593 &VarRelativeVar,
594 varType)) return;
595
596 if(varType.GetBasicType()&FLAG_PTR){
597 SetError(14,variable,cp);
598 return;
599 }
600
601 if( varType.IsStruct() ){
602 //構造体インスタンスへの代入
603 SetStructVariable(varType,calcType,bCalcUseHeap);
604 return;
605 }
606
607
608 if( varType.IsObject() && compiler.GetMeta().GetBlittableTypes().IsExist( calcType ) ){
609 // Blittable型をオブジェクトとして扱う
610 vector<const UserProc *> userProcs;
611 compiler.GetMeta().GetBlittableTypes().GetClass( calcType ).GetStaticMethods().Enum( "_Create", userProcs );
612 if( userProcs.size() != 1 ){
613 SetError();
614 return;
615 }
616 const UserProc *pUserProc = userProcs[0];
617
618 // call System.[TypeClass]._Create
619 compiler.codeGenerator.op_call( pUserProc );
620
621 // push eax
622 compiler.codeGenerator.op_push( REG_EAX );
623
624 calcType = pUserProc->ReturnType();
625 }
626
627
628 /////////////////////////////////
629 // 右辺、左辺の型チェックを行う
630 /////////////////////////////////
631
632 CheckDifferentType(varType,calcType,0,0);
633
634
635 /////////////////////////////////////////////////
636 // スタックの内容を変数にコピーするコードを抽出
637 /////////////////////////////////////////////////
638
639 //eax、edx:eax、またはst(0)にスタック上のデータを取り出す
640 RestoreDefaultRegisterFromStackMemory( calcType.GetBasicType() );
641
642 SetVariableFromEax(varType.GetBasicType(),calcType.GetBasicType(),&VarRelativeVar);
643}
Note: See TracBrowser for help on using the repository browser.