source: dev/BasicCompiler_Common/NumOpe_GetType.cpp@ 50

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

オーバーロード解決用の関数保持リストを "SUBINFO " ではなく、"vector<SUBINFO *>" に変更した。

File size: 14.4 KB
Line 
1#include "common.h"
2
3
4int MakeWholeType(int size,int bSigned){
5 switch(size){
6 case 1:
7 if(bSigned) return DEF_CHAR;
8 else return DEF_BYTE;
9 break;
10 case 2:
11 if(bSigned) return DEF_INTEGER;
12 else return DEF_WORD;
13 break;
14 case 4:
15 if(bSigned) return DEF_LONG;
16 else return DEF_DWORD;
17 break;
18 case 8:
19 if(bSigned) return DEF_INT64;
20 else return DEF_QWORD;
21 break;
22 }
23 return 0;
24}
25
26int AutoBigCast(int BaseType,int CalcType){
27 int type;
28 type=CalcType;
29
30 if(!BaseType){
31 //ベースタイプが未定のとき
32 return type;
33 }
34
35 if(!IsWholeNumberType(type)){
36 //整数型ではないときは暗黙の変換は必要なし
37 return type;
38 }
39
40 if(BaseType==DEF_OBJECT){
41 //ベースタイプがオブジェクトのときは暗黙の変換は必要なし
42 return type;
43 }
44
45 int BaseTypeSize;
46 BaseTypeSize=GetTypeSize(BaseType,-1);
47
48 if(IsRealNumberType(BaseType)){
49 if(GetTypeSize(CalcType,-1)<4)
50 type=MakeWholeType(4,IsSignedType(CalcType));
51 }
52 else if(BaseTypeSize>GetTypeSize(CalcType,-1)){
53 //要求される型のほうがサイズが大きいとき
54 type=MakeWholeType(BaseTypeSize,IsSignedType(CalcType));
55 }
56
57 if(!type){
58 extern int cp;
59 SetError(300,NULL,cp);
60 }
61
62 return type;
63}
64
65BOOL CheckCalcType(int idCalc,int *type,int sp){
66 //演算子の右辺、左辺の型をチェック
67 extern int cp;
68
69 //演算子名を取得
70 char temporary[255];
71 GetCalcName(idCalc,temporary);
72
73 switch(idCalc){
74
75 /////////////////////////////////////
76 // 実数に対する論理演算はエラー
77 /////////////////////////////////////
78
79 case CALC_XOR:
80 case CALC_OR:
81 case CALC_AND:
82 if(IsRealNumberType(type[sp-2])||IsRealNumberType(type[sp-1])){
83 //いずれかの項が実数のとき
84 SetError(45,temporary,cp);
85 return 0;
86 }
87
88 //As以外の演算子に型名が指定されていないかをチェック
89 if((type[sp-2]&FLAG_CAST)||(type[sp-1]&FLAG_CAST)){
90 SetError(48,temporary,cp);
91 return 0;
92 }
93 break;
94
95 case CALC_NOT:
96 if(IsRealNumberType(type[sp-1])){
97 //実数のとき
98 SetError(45,temporary,cp);
99 return 0;
100 }
101
102 //As以外の演算子に型名が指定されていないかをチェック
103 if(type[sp-1]&FLAG_CAST){
104 SetError(48,temporary,cp);
105 return 0;
106 }
107 break;
108
109
110
111 /////////////////////////////////////
112 // 比較演算はチェック項目なし
113 /////////////////////////////////////
114
115 case CALC_PE:
116 case CALC_QE:
117 case CALC_NOTEQUAL:
118 case CALC_EQUAL:
119 case CALC_P:
120 case CALC_Q:
121 //As以外の演算子に型名が指定されていないかをチェック
122 if((type[sp-2]&FLAG_CAST)||(type[sp-1]&FLAG_CAST)){
123 SetError(48,temporary,cp);
124 return 0;
125 }
126 break;
127
128
129
130 /////////////////////////////////////
131 // 算術演算をチェック
132 /////////////////////////////////////
133
134 case CALC_ADDITION:
135 case CALC_SUBTRACTION:
136 case CALC_PRODUCT:
137 case CALC_QUOTIENT:
138 case CALC_POWER:
139 //As以外の演算子に型名が指定されていないかをチェック
140 if((type[sp-2]&FLAG_CAST)||(type[sp-1]&FLAG_CAST)){
141 SetError(48,temporary,cp);
142 return 0;
143 }
144 break;
145
146 case CALC_SHL:
147 case CALC_SHR:
148 case CALC_MOD:
149 case CALC_INTQUOTIENT:
150 if(IsRealNumberType(type[sp-2])||IsRealNumberType(type[sp-1])){
151 //いずれかの項が実数のとき
152 SetError(45,temporary,cp);
153 return 0;
154 }
155
156 //As以外の演算子に型名が指定されていないかをチェック
157 if((type[sp-2]&FLAG_CAST)||(type[sp-1]&FLAG_CAST)){
158 SetError(48,temporary,cp);
159 return 0;
160 }
161 break;
162
163 case CALC_AS:
164 if((type[sp-1]&FLAG_CAST)==0){
165 //型名が指定されていないときはエラー
166 SetError(47,NULL,cp);
167 return 0;
168 }
169 break;
170
171 case CALC_BYVAL:
172 if(type[sp-1]&FLAG_CAST){
173 //型名が指定されていないときはエラー
174 SetError(47,NULL,cp);
175 return 0;
176 }
177 break;
178
179 case CALC_MINUSMARK:
180 //As以外の演算子に型名が指定されていないかをチェック
181 if(type[sp-1]&FLAG_CAST){
182 SetError(48,temporary,cp);
183 return 0;
184 }
185 break;
186 }
187 return 1;
188}
189
190int GetReturnType_OperatorProc(int idCalc,TYPEINFO *pBaseTypeInfo,int *type,LONG_PTR *index_stack,int &sp){
191 //オーバーロードされたオペレータ関数の戻り値を取得
192 CClass *pobj_c;
193 pobj_c=(CClass *)index_stack[sp-2];
194
195 std::vector<SUBINFO *> subs;
196 pobj_c->EnumMethod( idCalc, subs );
197 if( subs.size() == 0 ){
198 return 0;
199 }
200
201
202 //項の数
203 BOOL bTwoTerm=1;
204 if(idCalc==CALC_AS) bTwoTerm=0;
205
206
207
208 /////////////////////////////////////////////
209 // オーバーロード解決用のパラメータを設定
210 /////////////////////////////////////////////
211
212
213 //_System_LocalThis
214 PARAMETER_INFO *ppi = (PARAMETER_INFO *)HeapAlloc(hHeap,0,sizeof(PARAMETER_INFO)*3);
215 int iParmNum=0;
216
217 if(bTwoTerm){
218 ppi[iParmNum].bArray=0;
219 ppi[iParmNum].bByVal=0;
220 ppi[iParmNum].name=0;
221 ppi[iParmNum].type=type[sp-1];
222 ppi[iParmNum].u.index=index_stack[sp-1];
223 ppi[iParmNum].SubScripts[0]=-1;
224 iParmNum++;
225 }
226
227
228 //オーバーロードを解決
229 char temporary[255];
230 if(idCalc==CALC_EQUAL) lstrcpy(temporary,"==");
231 else GetCalcName(idCalc,temporary);
232 SUBINFO *psi;
233 psi=OverloadSolution(temporary,subs,ppi,iParmNum,pBaseTypeInfo);
234
235
236 if(!psi){
237 HeapDefaultFree(ppi);
238 return 0;
239 }
240 else{
241 //オーバーロードされていないが、パラメータ個数が一致しないとき
242 if(iParmNum!=psi->ParmNum){
243 HeapDefaultFree(ppi);
244 return 0;
245 }
246 }
247
248 HeapDefaultFree(ppi);
249
250 sp--;
251 type[sp-1]=psi->ReturnType;
252 index_stack[sp-1]=psi->u.ReturnIndex;
253
254 return 1;
255}
256
257int NumOpe_GetType(char *Command,TYPEINFO *pBaseType,LONG_PTR *plpIndex){
258 extern int cp;
259 int i,i2,i3,i4;
260 char temporary[1024],temp2[1024],temp3[1024];
261
262 if(Command[0]=='\0'){
263 SetError(1,NULL,cp);
264 return 0;
265 }
266
267 if(Command[0]==1&&Command[1]==ESC_NEW){
268 //New演算子(オブジェクト生成)
269 return DEF_PTR_OBJECT;
270 }
271
272
273 /////////////////////////////////
274 // 式要素を逆ポーランド式で取得
275 /////////////////////////////////
276
277 char *values[255];
278 long calc[255];
279 long stack[255];
280 int pnum;
281 if(!GetNumOpeElements(Command,&pnum,values,calc,stack)){
282 for(i=0;i<pnum;i++){
283 if(values[i]) HeapDefaultFree(values[i]);
284 }
285 return 0;
286 }
287
288
289
290 ////////////////////////////////
291 // 演算部分のコード生成を開始
292 ////////////////////////////////
293
294 BOOL bError;
295 bError=0;
296
297 //リテラル値のみの計算かどうかを判別するためのフラグ
298 BOOL bLiteralCalculation=1;
299
300 int sp;
301 int type[255];
302 LONG_PTR index_stack[255];
303 _int64 i64data;
304 int idCalc;
305 for(i=0,sp=0;i<pnum;i++){
306 idCalc=calc[i]%100;
307
308 if(idCalc){
309 if(type[sp-2]==DEF_OBJECT){
310 //オーバーロードされたオペレータを呼び出す
311 if(!GetReturnType_OperatorProc(idCalc,pBaseType,type,index_stack,sp)){
312 goto error;
313 }
314
315 continue;
316 }
317
318 if(!CheckCalcType(idCalc,type,sp)) goto error;
319 }
320
321 switch(idCalc){
322 //数値
323 case 0:
324 index_stack[sp]=-1;
325
326 char *term;
327 term = values[i];
328
329 if(term[0]=='\"'){
330StrLiteral:
331
332 if(pBaseType){
333 if(pBaseType->type==DEF_OBJECT){
334 if(IsStringSubsituation(pBaseType->u.pobj_Class)
335 || IsStringObjectType(pBaseType)){
336 //要求タイプがオブジェクトであり、Stringの受け入れが可能な場合
337 extern CClass *pobj_StringClass;
338 type[sp]=DEF_OBJECT;
339 index_stack[sp]=(LONG_PTR)pobj_StringClass;
340 bLiteralCalculation=0;
341
342 sp++;
343 break;
344 }
345 }
346 }
347
348 type[sp]=DEF_PTR_BYTE;
349 bLiteralCalculation=0;
350 }
351 else if((term[0]=='e'||term[0]=='E')&&
352 (term[1]=='x'||term[1]=='X')&&
353 term[2]=='\"'){
354 //拡張版リテラル文字列(エスケープシーケンス可能)
355 goto StrLiteral;
356 }
357 else if(IsVariableTopChar(term[0])||
358 term[0]=='*'||
359 (term[0]=='.'&&IsVariableTopChar(term[1]))){
360 //////////////////
361 // 何らかの識別子
362
363 //////////////////////////////////////
364 // 関数(DLL、ユーザー定義、組み込み)
365 //////////////////////////////////////
366
367 i2=GetCallProcName(term,temporary);
368 if(term[i2]=='('){
369 i4=GetStringInPare_RemovePare(temp2,term+i2+1);
370
371 int idProc;
372 void *pInfo;
373 idProc=GetProc(temporary,&pInfo);
374
375 if(idProc){
376 //閉じカッコ")"に続く文字がNULLでないとき
377 if(term[i2+1+i4+1]!='\0'){
378 if( term[i2+1+i4+1] == '.'
379 || term[i2+1+i4+1] == 1 && term[i2+1+i4+2] == ESC_PSMEM ){
380 goto NonProc;
381 }
382 else{
383 SetError(42,NULL,cp);
384 }
385 }
386
387
388 ////////////////
389 // 呼び出し
390 ////////////////
391
392 i2=GetReturnTypeOfProc(idProc,pInfo,temporary,temp2,&index_stack[sp]);
393 if(i2==-1){
394 //戻り値が存在しないとき
395 goto error;
396 }
397
398 type[sp]=i2;
399 bLiteralCalculation=0;
400
401 sp++;
402 break;
403 }
404 else if(GetConstCalcBuffer(temporary,temp2,temp3)){
405 /////////////////////////
406 // マクロ関数
407 /////////////////////////
408
409 //閉じカッコ")"に続く文字がNULLでないときはエラーにする
410 if(term[i2+1+i4+1]!='\0') SetError(42,NULL,cp);
411
412 //マクロ関数の場合
413 i2=NumOpe_GetType(temp3,NULL,&index_stack[sp]);
414
415 if(!IS_LITERAL(index_stack[sp])){
416 //リテラル値ではなかったとき
417 bLiteralCalculation=0;
418 }
419
420 type[sp]=i2;
421
422 sp++;
423 break;
424 }
425 }
426NonProc:
427
428 //インデクサ(getアクセサ)
429 char VarName[VN_SIZE],ArrayElements[VN_SIZE];
430 GetArrayElement(term,VarName,ArrayElements);
431 if(ArrayElements[0]){
432 CClass *pobj_c;
433 i2=GetVarType(VarName,(LONG_PTR *)&pobj_c,0);
434 if(i2==DEF_OBJECT){
435 TYPEINFO RetTypeInfo;
436 if( !GetReturnTypeOfIndexerGetterProc(pobj_c,RetTypeInfo) ){
437 SetError(1,NULL,cp);
438 goto error;
439 }
440 type[sp]=RetTypeInfo.type;
441 index_stack[sp]=RetTypeInfo.u.lpIndex;
442 bLiteralCalculation=0;
443
444 sp++;
445 break;
446 }
447 }
448
449
450 i2=GetVarType(term,&index_stack[sp],0);
451 if(i2!=-1){
452 //////////
453 // 変数
454 //////////
455
456 type[sp]=i2;
457 bLiteralCalculation=0;
458 sp++;
459 break;
460 }
461
462
463 //////////////
464 // 定数の場合
465 //////////////
466
467 i3 = CDBConst::obj.GetType(term);
468 if(i3){
469 type[sp]=i3;
470 if(IsRealNumberType(i3)){
471 //実数
472 goto Literal;
473 }
474 else if(IsWholeNumberType(i3)){
475 //整数
476 goto Literal;
477 }
478 else if(Is64Type(i3)){
479 //64ビット整数値
480 goto Literal;
481 }
482 else if(i3==DEF_STRING){
483 //リテラル文字列
484 goto StrLiteral;
485 }
486 else{
487 SetError(1,NULL,0);
488 goto error;
489 }
490 }
491
492
493 //////////////
494 // 型名の場合
495 //////////////
496
497 LONG_PTR lp;
498 i3=GetTypeFixed(term,&lp);
499 if(i3!=-1){
500 type[sp]=i3|FLAG_CAST;
501 index_stack[sp]=lp;
502 sp++;
503 break;
504 }
505
506
507
508 /////////////////////////////////
509 // プロパティ用のメソッド
510 /////////////////////////////////
511
512 //配列要素を排除
513 GetArrayElement(term,VarName,ArrayElements);
514
515 if(GetSubHash(VarName,0)){
516 TYPEINFO RetTypeInfo;
517 GetReturnTypeOfPropertyMethod(term,NULL,&RetTypeInfo);
518
519 //大きな型への暗黙の変換
520 type[sp]=RetTypeInfo.type;
521
522 index_stack[sp]=RetTypeInfo.u.lpIndex;
523 bLiteralCalculation=0;
524
525 sp++;
526 break;
527 }
528
529
530
531 //該当する識別子が見当たらないときはエラー扱いにする
532 bError=1;
533 SetError(3,term,cp);
534 type[sp]=DEF_DOUBLE;
535 }
536 else{
537 //リテラル値
538 int base_type;
539 base_type=0;
540 if(pBaseType) base_type=pBaseType->type;
541 type[sp]=GetLiteralValue(term,&i64data,base_type);
542Literal:
543 if((long)i64data==0&&index_stack[sp]==-1) index_stack[sp]=LITERAL_NULL;
544 }
545
546 sp++;
547 break;
548
549 //論理演算子
550 case CALC_XOR:
551 case CALC_OR:
552 case CALC_AND:
553 sp--;
554 type[sp-1]=NeutralizationType(type[sp-1],index_stack[sp-1],type[sp],index_stack[sp]);
555 break;
556 case CALC_NOT:
557 //values[sp-1]=Not values[sp-1]
558 //NOT演算子
559 break;
560
561 //比較演算子
562 case CALC_PE: //values[sp-2] <= values[sp-1]
563 case CALC_QE: //values[sp-2] >= values[sp-1]
564 case CALC_P: //values[sp-2] < values[sp-1]
565 case CALC_Q: //values[sp-2] > values[sp-1]
566 case CALC_NOTEQUAL: //values[sp-2] <> values[sp-1]
567 case CALC_EQUAL: //values[sp-2] = values[sp-1]
568 sp--;
569 type[sp-1]=DEF_LONG;
570 break;
571
572 //ビットシフト
573 case CALC_SHL: //values[sp-2] << values[sp-1]
574 case CALC_SHR: //values[sp-2] >> values[sp-1]
575 sp--;
576 break;
577
578 //算術演算
579 case CALC_ADDITION:
580 case CALC_SUBTRACTION:
581 case CALC_PRODUCT:
582 sp--;
583 type[sp-1]=NeutralizationType(type[sp-1],index_stack[sp-1],type[sp],index_stack[sp]);
584 break;
585 case CALC_MOD:
586 //values[sp-2]%=values[sp-1]
587 //剰余演算
588 sp--;
589 type[sp-1]=NeutralizationType(type[sp-1],index_stack[sp-1],type[sp],index_stack[sp]);
590 break;
591 case CALC_QUOTIENT:
592 //values[sp-2]/=values[sp-1];
593 //除算
594 sp--;
595 type[sp-1]=NeutralizationType(type[sp-1],index_stack[sp-1],type[sp],index_stack[sp]);
596 break;
597 case CALC_INTQUOTIENT:
598 //values[sp-2]/=values[sp-1]
599 //整数除算
600 sp--;
601 type[sp-1]=NeutralizationType(type[sp-1],index_stack[sp-1],type[sp],index_stack[sp]);
602 break;
603 case CALC_MINUSMARK:
604 //values[sp-1]=-values[sp-1]
605 //符号反転
606 break;
607 case CALC_POWER:
608 //べき乗演算(浮動小数点演算のみ)
609 sp--;
610 //未完成
611 break;
612 case CALC_AS:
613 //キャスト
614 type[sp-2]=type[sp-1]&(~FLAG_CAST);
615 index_stack[sp-2]=index_stack[sp-1];
616
617 sp--;
618 break;
619
620 case CALC_BYVAL:
621 //ポインタ型→参照型
622 if( PTR_LEVEL( type[sp-1] ) <= 0 ){
623 //ポインタ型ではないとき
624 SetError( 3, NULL, cp );
625 goto error;
626 }
627
628 type[sp-1] = PTR_LEVEL_DOWN( type[sp-1] );
629 break;
630 }
631 }
632
633 if(bError) goto error;
634
635 if(sp!=1){
636 SetError(1,NULL,cp);
637 goto error;
638 }
639
640 if(bLiteralCalculation){
641 //右辺値が数値の定数式の場合
642 LONG_PTR lpCalcIndex;
643 int base_type=0;
644 if(pBaseType) base_type=pBaseType->type;
645 i2=StaticCalculation(true, Command,base_type,&i64data,&lpCalcIndex);
646
647 type[0]=i2;
648 index_stack[0]=lpCalcIndex;
649 }
650 else{
651 //右辺値が数値の定数式ではないとき
652 if(IS_LITERAL(index_stack[0])) index_stack[0]=-1;
653 }
654
655 if(plpIndex) *plpIndex=index_stack[0];
656
657 int RetType;
658 RetType=type[0];
659 goto finish;
660
661
662 //////////////////
663 // エラー処理
664 //////////////////
665
666error:
667 RetType=-1;
668 goto finish;
669
670
671finish:
672 for(i=0;i<pnum;i++){
673 if(values[i]) HeapDefaultFree(values[i]);
674 }
675 return RetType;
676}
Note: See TracBrowser for help on using the repository browser.