source: dev/BasicCompiler32/NumOpe.cpp@ 8

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

Constステートメントで定数変数を宣言できるように改良。

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