source: dev/BasicCompiler32/NumOpe.cpp@ 34

Last change on this file since 34 was 11, checked in by dai_9181, 18 years ago

Const変数の書き込み規制を有効化(グローバル/ローカル変数のみ)
定数オブジェクトと定数メンバは未実装。

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