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

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