source: dev/BasicCompiler32/NumOpe.cpp@ 35

Last change on this file since 35 was 35, checked in by dai_9181, 17 years ago
File size: 17.1 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 TYPEINFO BaseTypeInfo = {BaseType,lpBaseIndex};
223 if(IsStringSubsituation(pobj_Class)
224 || IsStringObjectType(&BaseTypeInfo)){
225 //要求タイプがオブジェクトであり、Stringの受け入れが可能な場合
226
227 //String型オブジェクトを生成
228 NewStringObject(term);
229
230 extern CClass *pobj_StringClass;
231 type[sp]=DEF_OBJECT;
232 index_stack[sp]=(LONG_PTR)pobj_StringClass;
233 bUseHeap[sp]=1;
234 bLiteralCalculation=0;
235
236 sp++;
237 break;
238 }
239 }
240
241
242 type[sp]=DEF_PTR_BYTE;
243 index_stack[sp]=LITERAL_STRING;
244 bLiteralCalculation=0;
245
246 i2=AddDataTable(term,i3);
247
248 //push DataSize
249 OpBuffer[obp++]=(char)0x68;
250 *((long *)(OpBuffer+obp))=i2;
251 pobj_DataTableSchedule->add();
252 obp+=sizeof(long);
253 }
254 else if((term[0]=='e'||term[0]=='E')&&
255 (term[1]=='x'||term[1]=='X')&&
256 term[2]=='\"'){
257 //拡張版リテラル文字列(エスケープシーケンス可能)
258 if(!RemoveStringQuotes(term+2)){
259 SetError(43,NULL,cp);
260 goto error;
261 }
262 i3=FormatString_EscapeSequence(term+2);
263 term+=2;
264
265 goto StrLiteral;
266 }
267 else if(IsVariableTopChar(term[0])||
268 term[0]=='*'||
269 (term[0]=='.'&&IsVariableTopChar(term[1]))){
270 //////////////////
271 // 何らかの識別子
272
273 //////////////////////////////////////
274 // 関数(DLL、ユーザー定義、組み込み)
275 //////////////////////////////////////
276
277 i2=GetCallProcName(term,temporary);
278 if(term[i2]=='('){
279 i4=GetStringInPare_RemovePare(temp2,term+i2+1);
280
281 int idProc;
282 void *pInfo;
283 idProc=GetProc(temporary,&pInfo);
284
285 if(idProc){
286 //閉じカッコ")"に続く文字がNULLでないときはエラーにする
287 if(term[i2+1+i4+1]!='\0') SetError(42,NULL,cp);
288
289 ////////////////
290 // 呼び出し
291 ////////////////
292
293 i2=CallProc(idProc,pInfo,temporary,temp2,&index_stack[sp]);
294 if(i2==-1){
295 //戻り値が存在しないとき
296 for(i2=2;;i2++){
297 if(term[i2]=='('||term[i2]=='\0'){
298 term[i2]=0;
299 break;
300 }
301 }
302 SetError(38,term,cp);
303
304 goto error;
305 }
306
307
308 /////////////////////
309 // 戻り値の処理
310 /////////////////////
311
312 //大きな型への暗黙の変換
313 type[sp]=AutoBigCast(BaseType,i2);
314 bLiteralCalculation=0;
315
316 //スタックへプッシュ
317 PushReturnValue(i2);
318
319 if(Is64Type(type[sp])&&IsWholeNumberType(i2)&&GetTypeSize(i2,-1)<=sizeof(long)){
320 //必要に応じて64ビット拡張
321 ExtendStackTo64(i2);
322 }
323
324 if(i2==DEF_OBJECT){
325 //Object型が戻ったときはヒープ領域にインスタンスが格納されている
326 //※後にfreeする必要あり
327 bUseHeap[sp]=1;
328 }
329
330 sp++;
331 break;
332 }
333 else if(GetConstCalcBuffer(temporary,temp2,temp3)){
334 /////////////////////////
335 // マクロ関数
336 /////////////////////////
337
338 //閉じカッコ")"に続く文字がNULLでないときはエラーにする
339 if(term[i2+1+i4+1]!='\0') SetError(42,NULL,cp);
340
341 //マクロ関数の場合
342 type[sp]=NumOpe(temp3,0,0,&index_stack[sp]);
343
344 if(!IS_LITERAL(index_stack[sp])){
345 //リテラル値ではなかったとき
346 bLiteralCalculation=0;
347 }
348
349 sp++;
350 break;
351 }
352 }
353
354
355
356 char variable[VN_SIZE],array_element[VN_SIZE];
357 CClass *pobj_c;
358 GetArrayElement(term,variable,array_element);
359 if(array_element[0]){
360 i2=GetVarType(variable,(LONG_PTR *)&pobj_c,0);
361 if(i2==DEF_OBJECT){
362 TYPEINFO RetTypeInfo;
363 CallArrayOperatorProc(pobj_c,variable,array_element,RetTypeInfo);
364 type[sp]=RetTypeInfo.type;
365 index_stack[sp]=RetTypeInfo.u.lpIndex;
366 bLiteralCalculation=0;
367
368 //push eax
369 op_push(REG_EAX);
370
371 sp++;
372 break;
373 }
374 }
375
376
377
378 RELATIVE_VAR RelativeVar;
379 if(GetVarOffset(
380 false, //エラー表示あり
381 false, //読み込み専用
382 term,&i2,&RelativeVar,&index_stack[sp])){
383 //////////
384 // 変数
385 //////////
386
387 //大きな型への暗黙の変換
388 type[sp]=AutoBigCast(BaseType,i2);
389 bLiteralCalculation=0;
390
391 if(i2&FLAG_PTR){
392 //配列ポインタ
393 type[sp]=GetPtrType(i2^FLAG_PTR,index_stack[sp]);
394
395 SetVarPtrToEax(&RelativeVar);
396
397 //push eax
398 op_push(REG_EAX);
399 }
400 else if(i2==DEF_DOUBLE||
401 i2==DEF_INT64||
402 i2==DEF_QWORD){
403 //64ビット型
404 PushDoubleVariable(&RelativeVar);
405 }
406 else if(i2==DEF_LONG||i2==DEF_DWORD||i2==DEF_SINGLE||
407 IsPtrType(i2)){
408 //32ビット型
409 PushLongVariable(&RelativeVar);
410 }
411 else if(i2==DEF_INTEGER){
412 PushIntegerVariable(&RelativeVar);
413 }
414 else if(i2==DEF_WORD){
415 PushWordVariable(&RelativeVar);
416 }
417 else if(i2==DEF_CHAR){
418 PushCharVariable(&RelativeVar);
419 }
420 else if(i2==DEF_BYTE){
421 PushByteVariable(&RelativeVar);
422 }
423 else if(i2==DEF_OBJECT){
424 //オブジェクト ポインタをeaxへ格納
425 SetVarPtrToEax(&RelativeVar);
426
427 //push eax
428 op_push(REG_EAX);
429 }
430
431 if(Is64Type(type[sp])&&IsWholeNumberType(i2)&&GetTypeSize(i2,-1)<=sizeof(long)){
432 //必要に応じて64ビット拡張
433 ExtendStackTo64(i2);
434 }
435
436 sp++;
437 break;
438 }
439
440
441 //////////////
442 // 定数の場合
443 //////////////
444
445 i3 = CDBConst::obj.GetType(term);
446 if(i3){
447 type[sp]=i3;
448 if(IsRealNumberType(i3)){
449 //実数
450 double dbl = CDBConst::obj.GetDoubleData(term);
451 memcpy(&i64data,&dbl,sizeof(double));
452 goto Literal;
453 }
454 else if(IsWholeNumberType(i3)){
455 //整数
456 i64data = CDBConst::obj.GetWholeData(term);
457 goto Literal;
458 }
459 /*else if(i3==DEF_STRING){
460 //リテラル文字列
461
462 //バイト数
463 i3=(int)dbl;
464
465 memcpy(term,temporary,i3);
466 goto StrLiteral;
467 }*/
468 else{
469 SetError(300,NULL,cp);
470 goto error;
471 }
472 }
473
474
475 //////////////
476 // 型名の場合
477 //////////////
478
479 LONG_PTR lp;
480 i3=GetTypeFixed(term,&lp);
481 if(i3!=-1){
482 type[sp]=i3|FLAG_CAST;
483 index_stack[sp]=lp;
484 sp++;
485 break;
486 }
487
488
489
490 /////////////////////////////////
491 // プロパティ用のメソッド
492 /////////////////////////////////
493
494 //配列要素を排除
495 char VarName[VN_SIZE],ArrayElements[VN_SIZE];
496 GetArrayElement(term,VarName,ArrayElements);
497
498 if(GetSubHash(VarName,0)){
499 TYPEINFO RetTypeInfo;
500 CallPropertyMethod(term,NULL,&RetTypeInfo);
501
502 //大きな型への暗黙の変換
503 type[sp]=AutoBigCast(BaseType,RetTypeInfo.type);
504
505 index_stack[sp]=RetTypeInfo.u.lpIndex;
506 bLiteralCalculation=0;
507
508 //スタックへプッシュ
509 PushReturnValue(RetTypeInfo.type);
510
511 if(type[sp]==DEF_OBJECT){
512 //Object型が戻ったときはヒープ領域にインスタンスが格納されている
513 //※後にfreeする必要あり
514 bUseHeap[sp]=1;
515 }
516
517 sp++;
518 break;
519 }
520
521
522
523 //該当する識別子が見当たらないときはエラー扱いにする
524 bError=1;
525 SetError(3,term,cp);
526 type[sp]=DEF_DOUBLE;
527 }
528 else{
529 //リテラル値
530 type[sp]=GetLiteralValue(term,&i64data,BaseType);
531Literal:
532 if(type[sp]==DEF_INT64||
533 type[sp]==DEF_QWORD||
534 type[sp]==DEF_DOUBLE){
535 //64ビット(符号有り整数/実数)
536
537 //push HILONG(dbl)
538 op_push_value((long)*(long *)(((char *)(&i64data))+4));
539
540 //push LOLONG(dbl)
541 op_push_value(*(long *)(&i64data));
542 }
543 else if(type[sp]==DEF_SINGLE){
544 //single実数
545
546 float flt;
547 memcpy(&dbl,&i64data,sizeof(double));
548 flt=(float)dbl;
549 memcpy(&i3,&flt,sizeof(long));
550
551 //push term
552 op_push_value(i3);
553 }
554 else{
555 //その他
556
557 //push term
558 op_push_value((long)i64data);
559
560 if((long)i64data==0) index_stack[sp]=LITERAL_NULL;
561 }
562
563
564 //リテラル値の種類
565 if(Is64Type(type[sp])==0&&IsRealNumberType(type[sp])==0){
566 //整数(符号有り/無し)
567
568 index_stack[sp]=GetLiteralIndex(i64data);
569 }
570 }
571 sp++;
572 break;
573
574 //論理演算子
575 case CALC_XOR:
576 //value[sp-2] xor= value[sp-1]
577 //xor演算
578 if(!Calc_Xor(type,index_stack,&sp)) goto error;
579 break;
580 case CALC_OR:
581 //value[sp-2] or= value[sp-1]
582 //or演算
583 if(!Calc_Or(type,index_stack,&sp)) goto error;
584 break;
585 case CALC_AND:
586 //value[sp-2] and= value[sp-1]
587 //and演算
588 if(!Calc_And(type,index_stack,&sp)) goto error;
589 break;
590 case CALC_NOT:
591 //value[sp-1]=Not value[sp-1]
592 //NOT演算子
593 if(!Calc_Not(type,sp)) goto error;
594 break;
595
596 //比較演算子
597 case CALC_PE:
598 //value[sp-2]<=value[sp-1]
599 if(!Calc_Relation_PE(type,index_stack,&sp)) goto error;
600 break;
601 case CALC_QE:
602 //value[sp-2]>=value[sp-1]
603 if(!Calc_Relation_QE(type,index_stack,&sp)) goto error;
604 break;
605 case CALC_P:
606 //value[sp-2]<value[sp-1]
607 if(!Calc_Relation_P(type,index_stack,&sp)) goto error;
608 break;
609 case CALC_Q:
610 //value[sp-2]>value[sp-1]
611 if(!Calc_Relation_Q(type,index_stack,&sp)) goto error;
612 break;
613 case CALC_NOTEQUAL:
614 //value[sp-2]<>value[sp-1]
615 if(!Calc_Relation_NotEqual(type,&sp)) goto error;
616 break;
617 case CALC_EQUAL:
618 //value[sp-2]=value[sp-1]
619 if(!Calc_Relation_Equal(type,&sp)) goto error;
620 break;
621
622 //ビットシフト
623 case CALC_SHL:
624 //value[sp-2]=value[sp-2]<<value[sp-1]
625 if(!Calc_SHL(type,&sp)) goto error;
626 break;
627 case CALC_SHR:
628 //value[sp-2]=value[sp-2]>>value[sp-1]
629 if(!Calc_SHR(type,&sp)) goto error;
630 break;
631
632 //算術演算
633 case CALC_ADDITION:
634 case CALC_SUBTRACTION:
635 case CALC_PRODUCT:
636 if(!CalcTwoTerm_Arithmetic(idCalc,type,index_stack,&sp)) goto error;
637 break;
638
639 case CALC_MOD:
640 //value[sp-2]%=value[sp-1]
641 //剰余演算
642 if(!Calc_Mod(type,&sp)) goto error;
643 break;
644 case CALC_QUOTIENT:
645 //value[sp-2]/=value[sp-1];
646 //除算
647 if(!Calc_Divide(type,&sp,BaseType)) goto error;
648 break;
649 case CALC_INTQUOTIENT:
650 //value[sp-2]/=value[sp-1]
651 //整数除算
652 if(!Calc_IntDivide(type,index_stack,&sp)) goto error;
653 break;
654 case CALC_MINUSMARK:
655 //value[sp-1]=-value[sp-1]
656 //符号反転
657 if(!Calc_MinusMark(type,sp)) goto error;
658 index_stack[sp-1]=-1;
659 break;
660 case CALC_POWER:
661 //べき乗演算(浮動小数点演算のみ)
662 if(!Calc_Power(type,&sp)) goto error;
663 break;
664 case CALC_AS:
665 //キャスト
666 if(!Calc_Cast(type,index_stack,&sp)) goto error;
667 break;
668
669 default:
670 SetError(300,NULL,cp);
671 break;
672 }
673 }
674
675 if(bError) goto error;
676
677 if(sp!=1){
678 SetError(1,NULL,cp);
679 goto error;
680 }
681
682 if(bLiteralCalculation){
683 //右辺値が数値の定数式の場合
684 LONG_PTR lpClassIndex;
685 i2=StaticCalculation(true, Command,BaseType,&i64data,&lpClassIndex);
686
687 obp=BeforeObp;
688 pobj_SubAddrSchedule->num=Before_ProcAddrScheduleNum;
689 pobj_DataTableSchedule->num=Before_DataTableScheduleNum;
690 pobj_Reloc->copy(pobj_BackReloc);
691
692 if(i2==DEF_INT64||
693 i2==DEF_QWORD||
694 i2==DEF_DOUBLE){
695 //64ビット(符号有り整数/実数)
696
697 //push HILONG(i64data)
698 op_push_value((long)*(long *)(((char *)(&i64data))+4));
699
700 //push LOLONG(i64data)
701 op_push_value(*(long *)(&i64data));
702 }
703 else if(i2==DEF_SINGLE){
704 //single実数
705
706 memcpy(&dbl,&i64data,sizeof(_int64));
707
708 float flt;
709 flt=(float)dbl;
710 memcpy(&i3,&flt,sizeof(long));
711
712 //push flt
713 op_push_value(i3);
714 }
715 else{
716 //整数(符号有り/無し)
717
718 i3=(long)i64data;
719
720 if(i2==DEF_CHAR||i2==DEF_BYTE) i3=i3&0x000000FF;
721 if(i2==DEF_INTEGER||i2==DEF_WORD) i3=i3&0x0000FFFF;
722
723 //push term
724 op_push_value(i3);
725 }
726
727 type[0]=i2;
728 index_stack[0]=lpClassIndex;
729 }
730 else{
731 //右辺値が数値の定数式ではないとき
732 if(IS_LITERAL(index_stack[0])) index_stack[0]=-1;
733 }
734
735 if(plpIndex) *plpIndex=index_stack[0];
736 if(pbUseHeap) *pbUseHeap=bUseHeap[0];
737
738 int RetType;
739 RetType=type[0];
740 goto finish;
741
742
743error:
744 RetType=-1;
745 goto finish;
746
747
748finish:
749
750 for(i=0;i<pnum;i++){
751 if(values[i]) HeapDefaultFree(values[i]);
752 }
753
754 //再配置スケジュールバックアップ情報を解放
755 delete pobj_BackReloc;
756
757 return RetType;
758}
Note: See TracBrowser for help on using the repository browser.