source: dev/BasicCompiler32/NumOpe.cpp@ 77

Last change on this file since 77 was 76, checked in by dai_9181, 18 years ago

TYPEINFO→Typeへのリファクタリングを実施。32bitが未完成。

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