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

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