source: dev/BasicCompiler32/NumOpe.cpp@ 3

Last change on this file since 3 was 3, checked in by dai_9181, 17 years ago
File size: 17.0 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2#include "Opcode.h"
3
4void PushReturnValue(int type){
5 //関数の戻り値をスタックへプッシュする
6 //※この処理内では、esi、ediは使用不可
7
8 if(type==DEF_OBJECT){
9 //push eax
10 op_push(REG_EAX);
11 }
12 else if(type==DEF_DOUBLE){
13 //sub esp,8
14 op_sub_esp(8);
15
16 //fstp qword ptr[esp]
17 OpBuffer[obp++]=(char)0xDD;
18 OpBuffer[obp++]=(char)0x1C;
19 OpBuffer[obp++]=(char)0x24;
20 }
21 else if(type==DEF_SINGLE){
22 //sub esp,4
23 op_sub_esp(4);
24
25 //fstp dword ptr[esp]
26 OpBuffer[obp++]=(char)0xD9;
27 OpBuffer[obp++]=(char)0x1C;
28 OpBuffer[obp++]=(char)0x24;
29 }
30 else if(type==DEF_INT64||type==DEF_QWORD){
31 //push edx
32 op_push(REG_EDX);
33
34 //push eax
35 op_push(REG_EAX);
36 }
37 else if(type==DEF_LONG){
38 //push eax
39 op_push(REG_EAX);
40 }
41 else if(type==DEF_INTEGER){
42 //movsx ebx,ax
43 OpBuffer[obp++]=(char)0x0F;
44 OpBuffer[obp++]=(char)0xBF;
45 OpBuffer[obp++]=(char)0xD8;
46
47 //push ebx
48 op_push(REG_EBX);
49 }
50 else if(type==DEF_CHAR){
51 //movsx ebx,al
52 OpBuffer[obp++]=(char)0x0F;
53 OpBuffer[obp++]=(char)0xBE;
54 OpBuffer[obp++]=(char)0xD8;
55
56 //push ebx
57 op_push(REG_EBX);
58 }
59 else if(type==DEF_DWORD||type==DEF_WORD||type==DEF_BYTE||
60 IsPtrType(type)){
61 //push eax
62 op_push(REG_EAX);
63 }
64 else if(type==DEF_PTR_BYTE){
65 //push eax
66 op_push(REG_EAX);
67 }
68}
69
70void NewStringObject(LPSTR lpszText){
71 ///////////////////////////////////////////////////////
72 // lpszTextを元にStringオブジェクトを生成し、
73 // オブジェクトポインタをスタックに格納する
74 ///////////////////////////////////////////////////////
75
76 extern CClass *pobj_StringClass;
77 int object_size;
78 object_size=GetSizeOfClass(pobj_StringClass);
79
80 //push object_size
81 op_push_value(object_size);
82
83 //call calloc
84 extern SUBINFO *pSub_calloc;
85 op_call(pSub_calloc);
86
87 //push eax
88 op_push(REG_EAX);
89
90 //push eax
91 op_push(REG_EAX);
92
93 {
94 //push eax
95 op_push(REG_EAX);
96
97 //call constructor
98 op_call(pobj_StringClass->ppobj_Method[pobj_StringClass->ConstructorMemberSubIndex]->psi);
99 }
100
101 int i2;
102 i2=AddDataTable(lpszText,lstrlen(lpszText));
103
104 //push lpszPtr
105 OpBuffer[obp++]=(char)0x68;
106 *((long *)(OpBuffer+obp))=i2;
107 pobj_DataTableSchedule->add();
108 obp+=sizeof(long);
109
110
111 SetObjectVariable((LONG_PTR)pobj_StringClass,DEF_PTR_BYTE,-1,0);
112}
113
114
115int NumOpe(char *Command,int BaseType,LONG_PTR lpBaseIndex,LONG_PTR *plpIndex,BOOL *pbUseHeap){
116 extern HANDLE hHeap;
117 int i,i2,i3,i4;
118 char temporary[8192],temp2[1024],temp3[1024];
119
120 if(Command[0]=='\0'){
121 SetError(1,NULL,cp);
122 return -1;
123 }
124
125 if(Command[0]==1&&Command[1]==ESC_NEW){
126 //New演算子(オブジェクト生成)
127 return Operator_New(Command+2,plpIndex);
128 }
129
130
131 /////////////////////////////////
132 // 式要素を逆ポーランド式で取得
133 /////////////////////////////////
134
135 char *values[255];
136 long calc[255];
137 long stack[255];
138 int pnum;
139 if(!GetNumOpeElements(Command,&pnum,values,calc,stack)){
140 for(i=0;i<pnum;i++){
141 if(values[i]) HeapDefaultFree(values[i]);
142 }
143 return 0;
144 }
145
146
147 BOOL bError;
148 bError=0;
149
150 //リテラル値のみの計算かどうかを判別するためのフラグ
151 BOOL bLiteralCalculation=1;
152
153 //リテラル演算の場合を考慮した演算前のバッファ位置
154 int BeforeObp;
155 BeforeObp=obp;
156
157 //リテラル演算の場合を考慮した演算前のプロシージャスケジュール位置
158 //※64ビットの掛け算、除算などで特殊関数が呼ばれるため
159 int Before_ProcAddrScheduleNum;
160 Before_ProcAddrScheduleNum=pobj_SubAddrSchedule->num;
161
162 //リテラル演算の場合を考慮した演算前のデータテーブルスケジュール位置
163 int Before_DataTableScheduleNum;
164 Before_DataTableScheduleNum=pobj_DataTableSchedule->num;
165
166 //リテラル演算の場合を考慮した演算前の再配置スケジュール
167 CReloc *pobj_BackReloc;
168 pobj_BackReloc=new CReloc();
169 pobj_BackReloc->copy(pobj_Reloc);
170
171 double dbl;
172 int sp;
173 int type[255];
174 LONG_PTR index_stack[255];
175 BOOL bUseHeap[255];
176 _int64 i64data;
177 for(i=0,sp=0;i<pnum;i++){
178 int idCalc;
179 idCalc=calc[i]%100;
180
181 if(idCalc){
182 if(type[sp-2]==DEF_OBJECT){
183 //オーバーロードされたオペレータを呼び出す
184 TYPEINFO BaseTypeInfo={BaseType,lpBaseIndex};
185 i2=CallOperatorProc(idCalc,&BaseTypeInfo,type,index_stack,bUseHeap,sp);
186 if(i2==0){
187 if(idCalc==CALC_EQUAL) lstrcpy(temp2,"==");
188 else GetCalcName(idCalc,temp2);
189 sprintf(temporary,"Operator %s",temp2);
190 SetError(27,temporary,cp);
191 goto error;
192 }
193 else if(i2==-1) goto error;
194
195 continue;
196 }
197
198 if(!CheckCalcType(idCalc,type,sp)) goto error;
199 }
200
201 switch(idCalc){
202 //数値
203 case 0:
204 index_stack[sp]=-1;
205 bUseHeap[sp]=0;
206
207 char *term;
208 term=values[i];
209
210 if(term[0]=='\"'){
211 //リテラル文字列
212 if(!RemoveStringQuotes(term)){
213 SetError(43,NULL,cp);
214 goto error;
215 }
216 i3=lstrlen(term);
217StrLiteral:
218
219 if(BaseType==DEF_OBJECT){
220 CClass *pobj_Class;
221 pobj_Class=(CClass *)lpBaseIndex;
222 if(IsStringSubsituation(pobj_Class)){
223 //要求タイプがオブジェクトであり、Stringの受け入れが可能な場合
224
225 //String型オブジェクトを生成
226 NewStringObject(term);
227
228 extern CClass *pobj_StringClass;
229 type[sp]=DEF_OBJECT;
230 index_stack[sp]=(LONG_PTR)pobj_StringClass;
231 bUseHeap[sp]=1;
232 bLiteralCalculation=0;
233
234 sp++;
235 break;
236 }
237 }
238
239
240 type[sp]=DEF_PTR_BYTE;
241 index_stack[sp]=LITERAL_STRING;
242 bLiteralCalculation=0;
243
244 i2=AddDataTable(term,i3);
245
246 //push DataSize
247 OpBuffer[obp++]=(char)0x68;
248 *((long *)(OpBuffer+obp))=i2;
249 pobj_DataTableSchedule->add();
250 obp+=sizeof(long);
251 }
252 else if((term[0]=='e'||term[0]=='E')&&
253 (term[1]=='x'||term[1]=='X')&&
254 term[2]=='\"'){
255 //拡張版リテラル文字列(エスケープシーケンス可能)
256 if(!RemoveStringQuotes(term+2)){
257 SetError(43,NULL,cp);
258 goto error;
259 }
260 i3=FormatString_EscapeSequence(term+2);
261 term+=2;
262
263 goto StrLiteral;
264 }
265 else if(IsVariableTopChar(term[0])||
266 term[0]=='*'||
267 (term[0]=='.'&&IsVariableTopChar(term[1]))){
268 //////////////////
269 // 何らかの識別子
270
271 //////////////////////////////////////
272 // 関数(DLL、ユーザー定義、組み込み)
273 //////////////////////////////////////
274
275 i2=GetCallProcName(term,temporary);
276 if(term[i2]=='('){
277 i4=GetStringInPare_RemovePare(temp2,term+i2+1);
278
279 int idProc;
280 void *pInfo;
281 idProc=GetProc(temporary,&pInfo);
282
283 if(idProc){
284 //閉じカッコ")"に続く文字がNULLでないときはエラーにする
285 if(term[i2+1+i4+1]!='\0') SetError(42,NULL,cp);
286
287 ////////////////
288 // 呼び出し
289 ////////////////
290
291 i2=CallProc(idProc,pInfo,temporary,temp2,&index_stack[sp]);
292 if(i2==-1){
293 //戻り値が存在しないとき
294 for(i2=2;;i2++){
295 if(term[i2]=='('||term[i2]=='\0'){
296 term[i2]=0;
297 break;
298 }
299 }
300 SetError(38,term,cp);
301
302 goto error;
303 }
304
305
306 /////////////////////
307 // 戻り値の処理
308 /////////////////////
309
310 //大きな型への暗黙の変換
311 type[sp]=AutoBigCast(BaseType,i2);
312 bLiteralCalculation=0;
313
314 //スタックへプッシュ
315 PushReturnValue(i2);
316
317 if(Is64Type(type[sp])&&IsWholeNumberType(i2)&&GetTypeSize(i2,-1)<=sizeof(long)){
318 //必要に応じて64ビット拡張
319 ExtendStackTo64(i2);
320 }
321
322 if(i2==DEF_OBJECT){
323 //Object型が戻ったときはヒープ領域にインスタンスが格納されている
324 //※後にfreeする必要あり
325 bUseHeap[sp]=1;
326 }
327
328 sp++;
329 break;
330 }
331 else if(GetConstCalcBuffer(temporary,temp2,temp3)){
332 /////////////////////////
333 // マクロ関数
334 /////////////////////////
335
336 //閉じカッコ")"に続く文字がNULLでないときはエラーにする
337 if(term[i2+1+i4+1]!='\0') SetError(42,NULL,cp);
338
339 //マクロ関数の場合
340 type[sp]=NumOpe(temp3,0,0,&index_stack[sp]);
341
342 if(!IS_LITERAL(index_stack[sp])){
343 //リテラル値ではなかったとき
344 bLiteralCalculation=0;
345 }
346
347 sp++;
348 break;
349 }
350 }
351
352
353
354 char variable[VN_SIZE],array_element[VN_SIZE];
355 CClass *pobj_c;
356 GetArrayElement(term,variable,array_element);
357 if(array_element[0]){
358 i2=GetVarType(variable,(LONG_PTR *)&pobj_c,0);
359 if(i2==DEF_OBJECT){
360 TYPEINFO RetTypeInfo;
361 CallArrayOperatorProc(pobj_c,variable,array_element,RetTypeInfo);
362 type[sp]=RetTypeInfo.type;
363 index_stack[sp]=RetTypeInfo.u.lpIndex;
364 bLiteralCalculation=0;
365
366 //push eax
367 op_push(REG_EAX);
368
369 sp++;
370 break;
371 }
372 }
373
374
375
376 RELATIVE_VAR RelativeVar;
377 if(GetVarOffset(0,term,&i2,&RelativeVar,&index_stack[sp])){
378 //////////
379 // 変数
380 //////////
381
382 //大きな型への暗黙の変換
383 type[sp]=AutoBigCast(BaseType,i2);
384 bLiteralCalculation=0;
385
386 if(i2&FLAG_PTR){
387 //配列ポインタ
388 type[sp]=GetPtrType(i2^FLAG_PTR,index_stack[sp]);
389
390 SetVarPtrToEax(&RelativeVar);
391
392 //push eax
393 op_push(REG_EAX);
394 }
395 else if(i2==DEF_DOUBLE||
396 i2==DEF_INT64||
397 i2==DEF_QWORD){
398 //64ビット型
399 PushDoubleVariable(&RelativeVar);
400 }
401 else if(i2==DEF_LONG||i2==DEF_DWORD||i2==DEF_SINGLE||
402 IsPtrType(i2)){
403 //32ビット型
404 PushLongVariable(&RelativeVar);
405 }
406 else if(i2==DEF_INTEGER){
407 PushIntegerVariable(&RelativeVar);
408 }
409 else if(i2==DEF_WORD){
410 PushWordVariable(&RelativeVar);
411 }
412 else if(i2==DEF_CHAR){
413 PushCharVariable(&RelativeVar);
414 }
415 else if(i2==DEF_BYTE){
416 PushByteVariable(&RelativeVar);
417 }
418 else if(i2==DEF_OBJECT){
419 //オブジェクト ポインタをeaxへ格納
420 SetVarPtrToEax(&RelativeVar);
421
422 //push eax
423 op_push(REG_EAX);
424 }
425
426 if(Is64Type(type[sp])&&IsWholeNumberType(i2)&&GetTypeSize(i2,-1)<=sizeof(long)){
427 //必要に応じて64ビット拡張
428 ExtendStackTo64(i2);
429 }
430
431 sp++;
432 break;
433 }
434
435
436 //////////////
437 // 定数の場合
438 //////////////
439
440 i3=GetConstValue(term,&dbl,temporary,&index_stack[sp]);
441 if(i3!=-1){
442 type[sp]=i3;
443 if(IsRealNumberType(i3)){
444 //実数
445 memcpy(&i64data,&dbl,sizeof(double));
446 goto Literal;
447 }
448 else if(IsWholeNumberType(i3)){
449 //整数
450 i64data=(_int64)dbl;
451 goto Literal;
452 }
453 else if(Is64Type(i3)){
454 //64ビット整数値
455 memcpy(&i64data,&dbl,sizeof(_int64));
456 goto Literal;
457 }
458 else if(i3==DEF_STRING){
459 //リテラル文字列
460
461 //バイト数
462 i3=(int)dbl;
463
464 memcpy(term,temporary,i3);
465 goto StrLiteral;
466 }
467 else{
468 SetError(300,NULL,cp);
469 goto error;
470 }
471 }
472
473
474 //////////////
475 // 型名の場合
476 //////////////
477
478 LONG_PTR lp;
479 i3=GetTypeFixed(term,&lp);
480 if(i3!=-1){
481 type[sp]=i3|FLAG_CAST;
482 index_stack[sp]=lp;
483 sp++;
484 break;
485 }
486
487
488
489 /////////////////////////////////
490 // プロパティ用のメソッド
491 /////////////////////////////////
492
493 //配列要素を排除
494 char VarName[VN_SIZE],ArrayElements[VN_SIZE];
495 GetArrayElement(term,VarName,ArrayElements);
496
497 if(GetSubHash(VarName,0)){
498 TYPEINFO RetTypeInfo;
499 CallPropertyMethod(term,NULL,&RetTypeInfo);
500
501 //大きな型への暗黙の変換
502 type[sp]=AutoBigCast(BaseType,RetTypeInfo.type);
503
504 index_stack[sp]=RetTypeInfo.u.lpIndex;
505 bLiteralCalculation=0;
506
507 //スタックへプッシュ
508 PushReturnValue(RetTypeInfo.type);
509
510 if(type[sp]==DEF_OBJECT){
511 //Object型が戻ったときはヒープ領域にインスタンスが格納されている
512 //※後にfreeする必要あり
513 bUseHeap[sp]=1;
514 }
515
516 sp++;
517 break;
518 }
519
520
521
522 //該当する識別子が見当たらないときはエラー扱いにする
523 bError=1;
524 SetError(3,term,cp);
525 type[sp]=DEF_DOUBLE;
526 }
527 else{
528 //リテラル値
529 type[sp]=GetLiteralValue(term,&i64data,BaseType);
530Literal:
531 if(type[sp]==DEF_INT64||
532 type[sp]==DEF_QWORD||
533 type[sp]==DEF_DOUBLE){
534 //64ビット(符号有り整数/実数)
535
536 //push HILONG(dbl)
537 op_push_value((long)*(long *)(((char *)(&i64data))+4));
538
539 //push LOLONG(dbl)
540 op_push_value(*(long *)(&i64data));
541 }
542 else if(type[sp]==DEF_SINGLE){
543 //single実数
544
545 float flt;
546 memcpy(&dbl,&i64data,sizeof(double));
547 flt=(float)dbl;
548 memcpy(&i3,&flt,sizeof(long));
549
550 //push term
551 op_push_value(i3);
552 }
553 else{
554 //その他
555
556 //push term
557 op_push_value((long)i64data);
558
559 if((long)i64data==0) index_stack[sp]=LITERAL_NULL;
560 }
561
562
563 //リテラル値の種類
564 if(Is64Type(type[sp])==0&&IsRealNumberType(type[sp])==0){
565 //整数(符号有り/無し)
566
567 index_stack[sp]=GetLiteralIndex(i64data);
568 }
569 }
570 sp++;
571 break;
572
573 //論理演算子
574 case CALC_XOR:
575 //value[sp-2] xor= value[sp-1]
576 //xor演算
577 if(!Calc_Xor(type,index_stack,&sp)) goto error;
578 break;
579 case CALC_OR:
580 //value[sp-2] or= value[sp-1]
581 //or演算
582 if(!Calc_Or(type,index_stack,&sp)) goto error;
583 break;
584 case CALC_AND:
585 //value[sp-2] and= value[sp-1]
586 //and演算
587 if(!Calc_And(type,index_stack,&sp)) goto error;
588 break;
589 case CALC_NOT:
590 //value[sp-1]=Not value[sp-1]
591 //NOT演算子
592 if(!Calc_Not(type,sp)) goto error;
593 break;
594
595 //比較演算子
596 case CALC_PE:
597 //value[sp-2]<=value[sp-1]
598 if(!Calc_Relation_PE(type,index_stack,&sp)) goto error;
599 break;
600 case CALC_QE:
601 //value[sp-2]>=value[sp-1]
602 if(!Calc_Relation_QE(type,index_stack,&sp)) goto error;
603 break;
604 case CALC_P:
605 //value[sp-2]<value[sp-1]
606 if(!Calc_Relation_P(type,index_stack,&sp)) goto error;
607 break;
608 case CALC_Q:
609 //value[sp-2]>value[sp-1]
610 if(!Calc_Relation_Q(type,index_stack,&sp)) goto error;
611 break;
612 case CALC_NOTEQUAL:
613 //value[sp-2]<>value[sp-1]
614 if(!Calc_Relation_NotEqual(type,&sp)) goto error;
615 break;
616 case CALC_EQUAL:
617 //value[sp-2]=value[sp-1]
618 if(!Calc_Relation_Equal(type,&sp)) goto error;
619 break;
620
621 //ビットシフト
622 case CALC_SHL:
623 //value[sp-2]=value[sp-2]<<value[sp-1]
624 if(!Calc_SHL(type,&sp)) goto error;
625 break;
626 case CALC_SHR:
627 //value[sp-2]=value[sp-2]>>value[sp-1]
628 if(!Calc_SHR(type,&sp)) goto error;
629 break;
630
631 //算術演算
632 case CALC_ADDITION:
633 case CALC_SUBTRACTION:
634 case CALC_PRODUCT:
635 if(!CalcTwoTerm_Arithmetic(idCalc,type,index_stack,&sp)) goto error;
636 break;
637
638 case CALC_MOD:
639 //value[sp-2]%=value[sp-1]
640 //剰余演算
641 if(!Calc_Mod(type,&sp)) goto error;
642 break;
643 case CALC_QUOTIENT:
644 //value[sp-2]/=value[sp-1];
645 //除算
646 if(!Calc_Divide(type,&sp,BaseType)) goto error;
647 break;
648 case CALC_INTQUOTIENT:
649 //value[sp-2]/=value[sp-1]
650 //整数除算
651 if(!Calc_IntDivide(type,index_stack,&sp)) goto error;
652 break;
653 case CALC_MINUSMARK:
654 //value[sp-1]=-value[sp-1]
655 //符号反転
656 if(!Calc_MinusMark(type,sp)) goto error;
657 index_stack[sp-1]=-1;
658 break;
659 case CALC_POWER:
660 //べき乗演算(浮動小数点演算のみ)
661 if(!Calc_Power(type,&sp)) goto error;
662 break;
663 case CALC_AS:
664 //キャスト
665 if(!Calc_Cast(type,index_stack,&sp)) goto error;
666 break;
667
668 default:
669 SetError(300,NULL,cp);
670 break;
671 }
672 }
673
674 if(bError) goto error;
675
676 if(sp!=1){
677 SetError(1,NULL,cp);
678 goto error;
679 }
680
681 if(bLiteralCalculation){
682 //右辺値が数値の定数式の場合
683 LONG_PTR lpClassIndex;
684 i2=StaticCalculation(true, Command,BaseType,&i64data,&lpClassIndex);
685
686 obp=BeforeObp;
687 pobj_SubAddrSchedule->num=Before_ProcAddrScheduleNum;
688 pobj_DataTableSchedule->num=Before_DataTableScheduleNum;
689 pobj_Reloc->copy(pobj_BackReloc);
690
691 if(i2==DEF_INT64||
692 i2==DEF_QWORD||
693 i2==DEF_DOUBLE){
694 //64ビット(符号有り整数/実数)
695
696 //push HILONG(i64data)
697 op_push_value((long)*(long *)(((char *)(&i64data))+4));
698
699 //push LOLONG(i64data)
700 op_push_value(*(long *)(&i64data));
701 }
702 else if(i2==DEF_SINGLE){
703 //single実数
704
705 memcpy(&dbl,&i64data,sizeof(_int64));
706
707 float flt;
708 flt=(float)dbl;
709 memcpy(&i3,&flt,sizeof(long));
710
711 //push flt
712 op_push_value(i3);
713 }
714 else{
715 //整数(符号有り/無し)
716
717 i3=(long)i64data;
718
719 if(i2==DEF_CHAR||i2==DEF_BYTE) i3=i3&0x000000FF;
720 if(i2==DEF_INTEGER||i2==DEF_WORD) i3=i3&0x0000FFFF;
721
722 //push term
723 op_push_value(i3);
724 }
725
726 type[0]=i2;
727 index_stack[0]=lpClassIndex;
728 }
729 else{
730 //右辺値が数値の定数式ではないとき
731 if(IS_LITERAL(index_stack[0])) index_stack[0]=-1;
732 }
733
734 if(plpIndex) *plpIndex=index_stack[0];
735 if(pbUseHeap) *pbUseHeap=bUseHeap[0];
736
737 int RetType;
738 RetType=type[0];
739 goto finish;
740
741
742error:
743 RetType=-1;
744 goto finish;
745
746
747finish:
748
749 for(i=0;i<pnum;i++){
750 if(values[i]) HeapDefaultFree(values[i]);
751 }
752
753 //再配置スケジュールバックアップ情報を解放
754 delete pobj_BackReloc;
755
756 return RetType;
757}
Note: See TracBrowser for help on using the repository browser.