source: dev/BasicCompiler32/NumOpe.cpp@ 51

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

ppobj_Member及びppobj_StaticMemberを廃止し、vectorに統一した(methods及びstaticMethods)。

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