source: dev/BasicCompiler_Common/NumOpe_GetType.cpp@ 11

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

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

File size: 13.5 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_MINUSMARK:
172 //As以外の演算子に型名が指定されていないかをチェック
173 if(type[sp-1]&FLAG_CAST){
174 SetError(48,temporary,cp);
175 return 0;
176 }
177 break;
178 }
179 return 1;
180}
181
182int GetReturnType_OperatorProc(int idCalc,TYPEINFO *pBaseTypeInfo,int *type,LONG_PTR *index_stack,int &sp){
183 //オーバーロードされたオペレータ関数の戻り値を取得
184 CClass *pobj_c;
185 pobj_c=(CClass *)index_stack[sp-2];
186
187 SUBINFO **ppsi;
188 int num;
189 ppsi=pobj_c->GetOperatorSubInfo(idCalc,num);
190 if(num==0){
191 HeapDefaultFree(ppsi);
192
193 return 0;
194 }
195
196
197 //項の数
198 BOOL bTwoTerm=1;
199 if(idCalc==CALC_AS) bTwoTerm=0;
200
201
202
203 /////////////////////////////////////////////
204 // オーバーロード解決用のパラメータを設定
205 /////////////////////////////////////////////
206
207 PARAMETER_INFO *ppi;
208 int iParmNum=0;
209
210 //_System_LocalThis
211 ppi=(PARAMETER_INFO *)HeapAlloc(hHeap,0,sizeof(PARAMETER_INFO)*3);
212 ppi[iParmNum].bArray=0;
213 ppi[iParmNum].bByVal=0;
214 ppi[iParmNum].name=0;
215 ppi[iParmNum].type=DEF_PTR_VOID;
216 ppi[iParmNum].u.index=-1;
217 ppi[iParmNum].SubScripts[0]=-1;
218 iParmNum++;
219
220 if(bTwoTerm){
221 ppi[iParmNum].bArray=0;
222 ppi[iParmNum].bByVal=0;
223 ppi[iParmNum].name=0;
224 ppi[iParmNum].type=type[sp-1];
225 ppi[iParmNum].u.index=index_stack[sp-1];
226 ppi[iParmNum].SubScripts[0]=-1;
227 iParmNum++;
228 }
229
230
231 //オーバーロードを解決
232 char temporary[255];
233 if(idCalc==CALC_EQUAL) lstrcpy(temporary,"==");
234 else GetCalcName(idCalc,temporary);
235 SUBINFO *psi;
236 psi=OverloadSolution(temporary,ppsi,num,ppi,iParmNum,pBaseTypeInfo);
237 HeapDefaultFree(ppsi);
238
239 if(!psi){
240 HeapDefaultFree(ppi);
241 return 0;
242 }
243 else{
244 //オーバーロードされていないが、パラメータ個数が一致しないとき
245 if(iParmNum!=psi->ParmNum){
246 HeapDefaultFree(ppi);
247 return 0;
248 }
249 }
250
251 HeapDefaultFree(ppi);
252
253 sp--;
254 type[sp-1]=psi->ReturnType;
255 index_stack[sp-1]=psi->u.ReturnIndex;
256
257 return 1;
258}
259
260int NumOpe_GetType(char *Command,TYPEINFO *pBaseType,LONG_PTR *plpIndex){
261 extern int cp;
262 int i,i2,i3,i4;
263 char temporary[1024],temp2[1024],temp3[1024];
264
265 if(Command[0]=='\0'){
266 SetError(1,NULL,cp);
267 return 0;
268 }
269
270 if(Command[0]==1&&Command[1]==ESC_NEW){
271 //New演算子(オブジェクト生成)
272 return DEF_PTR_OBJECT;
273 }
274
275
276 /////////////////////////////////
277 // 式要素を逆ポーランド式で取得
278 /////////////////////////////////
279
280 char *values[255];
281 long calc[255];
282 long stack[255];
283 int pnum;
284 if(!GetNumOpeElements(Command,&pnum,values,calc,stack)){
285 for(i=0;i<pnum;i++){
286 if(values[i]) HeapDefaultFree(values[i]);
287 }
288 return 0;
289 }
290
291
292
293 ////////////////////////////////
294 // 演算部分のコード生成を開始
295 ////////////////////////////////
296
297 BOOL bError;
298 bError=0;
299
300 //リテラル値のみの計算かどうかを判別するためのフラグ
301 BOOL bLiteralCalculation=1;
302
303 int sp;
304 int type[255];
305 LONG_PTR index_stack[255];
306 _int64 i64data;
307 int idCalc;
308 for(i=0,sp=0;i<pnum;i++){
309 idCalc=calc[i]%100;
310
311 if(idCalc){
312 if(type[sp-2]==DEF_OBJECT){
313 //オーバーロードされたオペレータを呼び出す
314 if(!GetReturnType_OperatorProc(idCalc,pBaseType,type,index_stack,sp)){
315 goto error;
316 }
317
318 continue;
319 }
320
321 if(!CheckCalcType(idCalc,type,sp)) goto error;
322 }
323
324 switch(idCalc){
325 //数値
326 case 0:
327 index_stack[sp]=-1;
328
329 if(values[i][0]=='\"'){
330StrLiteral:
331
332 if(pBaseType){
333 if(pBaseType->type==DEF_OBJECT){
334 if(IsStringSubsituation(pBaseType->u.pobj_Class)){
335 //要求タイプがオブジェクトであり、Stringの受け入れが可能な場合
336 extern CClass *pobj_StringClass;
337 type[sp]=DEF_OBJECT;
338 index_stack[sp]=(LONG_PTR)pobj_StringClass;
339 bLiteralCalculation=0;
340
341 sp++;
342 break;
343 }
344 }
345 }
346
347 type[sp]=DEF_PTR_BYTE;
348 bLiteralCalculation=0;
349 }
350 else if((values[i][0]=='e'||values[i][0]=='E')&&
351 (values[i][1]=='x'||values[i][1]=='X')&&
352 values[i][2]=='\"'){
353 //拡張版リテラル文字列(エスケープシーケンス可能)
354 goto StrLiteral;
355 }
356 else if(IsVariableTopChar(values[i][0])||
357 values[i][0]=='*'||
358 (values[i][0]=='.'&&IsVariableTopChar(values[i][1]))){
359 //////////////////
360 // 何らかの識別子
361
362 //////////////////////////////////////
363 // 関数(DLL、ユーザー定義、組み込み)
364 //////////////////////////////////////
365
366 i2=GetCallProcName(values[i],temporary);
367 if(values[i][i2]=='('){
368 i4=GetStringInPare_RemovePare(temp2,values[i]+i2+1);
369
370 int idProc;
371 void *pInfo;
372 idProc=GetProc(temporary,&pInfo);
373
374 if(idProc){
375 //閉じカッコ")"に続く文字がNULLでないときはエラーにする
376 if(values[i][i2+1+i4+1]!='\0') SetError(42,NULL,cp);
377
378
379 ////////////////
380 // 呼び出し
381 ////////////////
382
383 i2=GetReturnTypeOfProc(idProc,pInfo,temporary,temp2,&index_stack[sp]);
384 if(i2==-1){
385 //戻り値が存在しないとき
386 goto error;
387 }
388
389 type[sp]=i2;
390 bLiteralCalculation=0;
391
392 sp++;
393 break;
394 }
395 else if(GetConstCalcBuffer(temporary,temp2,temp3)){
396 /////////////////////////
397 // マクロ関数
398 /////////////////////////
399
400 //閉じカッコ")"に続く文字がNULLでないときはエラーにする
401 if(values[i][i2+1+i4+1]!='\0') SetError(42,NULL,cp);
402
403 //マクロ関数の場合
404 i2=NumOpe_GetType(temp3,NULL,&index_stack[sp]);
405
406 if(!IS_LITERAL(index_stack[sp])){
407 //リテラル値ではなかったとき
408 bLiteralCalculation=0;
409 }
410
411 type[sp]=i2;
412
413 sp++;
414 break;
415 }
416 }
417
418 i2=GetVarType(values[i],&index_stack[sp],0);
419 if(i2!=-1){
420 //////////
421 // 変数
422 //////////
423
424 type[sp]=i2;
425 bLiteralCalculation=0;
426 sp++;
427 break;
428 }
429
430
431 //////////////
432 // 定数の場合
433 //////////////
434
435 i3 = CDBConst::obj.GetType(values[i]);
436 if(i3){
437 type[sp]=i3;
438 if(IsRealNumberType(i3)){
439 //実数
440 goto Literal;
441 }
442 else if(IsWholeNumberType(i3)){
443 //整数
444 goto Literal;
445 }
446 else if(Is64Type(i3)){
447 //64ビット整数値
448 goto Literal;
449 }
450 else if(i3==DEF_STRING){
451 //リテラル文字列
452 goto StrLiteral;
453 }
454 else{
455 SetError(1,NULL,0);
456 goto error;
457 }
458 }
459
460
461 //////////////
462 // 型名の場合
463 //////////////
464
465 LONG_PTR lp;
466 i3=GetTypeFixed(values[i],&lp);
467 if(i3!=-1){
468 type[sp]=i3|FLAG_CAST;
469 index_stack[sp]=lp;
470 sp++;
471 break;
472 }
473
474
475
476 /////////////////////////////////
477 // プロパティ用のメソッド
478 /////////////////////////////////
479
480 //配列要素を排除
481 char VarName[VN_SIZE],ArrayElements[VN_SIZE];
482 GetArrayElement(values[i],VarName,ArrayElements);
483
484 if(GetSubHash(VarName,0)){
485 TYPEINFO RetTypeInfo;
486 GetReturnTypeOfPropertyMethod(values[i],NULL,&RetTypeInfo);
487
488 //大きな型への暗黙の変換
489 type[sp]=RetTypeInfo.type;
490
491 index_stack[sp]=RetTypeInfo.u.lpIndex;
492 bLiteralCalculation=0;
493
494 sp++;
495 break;
496 }
497
498
499
500 //該当する識別子が見当たらないときはエラー扱いにする
501 bError=1;
502 SetError(3,values[i],cp);
503 type[sp]=DEF_DOUBLE;
504 }
505 else{
506 //リテラル値
507 int base_type;
508 base_type=0;
509 if(pBaseType) base_type=pBaseType->type;
510 type[sp]=GetLiteralValue(values[i],&i64data,base_type);
511Literal:
512 if((long)i64data==0&&index_stack[sp]==-1) index_stack[sp]=LITERAL_NULL;
513 }
514
515 sp++;
516 break;
517
518 //論理演算子
519 case CALC_XOR:
520 case CALC_OR:
521 case CALC_AND:
522 sp--;
523 type[sp-1]=NeutralizationType(type[sp-1],index_stack[sp-1],type[sp],index_stack[sp]);
524 break;
525 case CALC_NOT:
526 //values[sp-1]=Not values[sp-1]
527 //NOT演算子
528 break;
529
530 //比較演算子
531 case CALC_PE: //values[sp-2] <= values[sp-1]
532 case CALC_QE: //values[sp-2] >= values[sp-1]
533 case CALC_P: //values[sp-2] < values[sp-1]
534 case CALC_Q: //values[sp-2] > values[sp-1]
535 case CALC_NOTEQUAL: //values[sp-2] <> values[sp-1]
536 case CALC_EQUAL: //values[sp-2] = values[sp-1]
537 sp--;
538 type[sp-1]=DEF_LONG;
539 break;
540
541 //ビットシフト
542 case CALC_SHL: //values[sp-2] << values[sp-1]
543 case CALC_SHR: //values[sp-2] >> values[sp-1]
544 sp--;
545 break;
546
547 //算術演算
548 case CALC_ADDITION:
549 case CALC_SUBTRACTION:
550 case CALC_PRODUCT:
551 sp--;
552 type[sp-1]=NeutralizationType(type[sp-1],index_stack[sp-1],type[sp],index_stack[sp]);
553 break;
554 case CALC_MOD:
555 //values[sp-2]%=values[sp-1]
556 //剰余演算
557 sp--;
558 type[sp-1]=NeutralizationType(type[sp-1],index_stack[sp-1],type[sp],index_stack[sp]);
559 break;
560 case CALC_QUOTIENT:
561 //values[sp-2]/=values[sp-1];
562 //除算
563 sp--;
564 type[sp-1]=NeutralizationType(type[sp-1],index_stack[sp-1],type[sp],index_stack[sp]);
565 break;
566 case CALC_INTQUOTIENT:
567 //values[sp-2]/=values[sp-1]
568 //整数除算
569 sp--;
570 type[sp-1]=NeutralizationType(type[sp-1],index_stack[sp-1],type[sp],index_stack[sp]);
571 break;
572 case CALC_MINUSMARK:
573 //values[sp-1]=-values[sp-1]
574 //符号反転
575 break;
576 case CALC_POWER:
577 //べき乗演算(浮動小数点演算のみ)
578 sp--;
579 //未完成
580 break;
581 case CALC_AS:
582 //キャスト
583 type[sp-2]=type[sp-1]&(~FLAG_CAST);
584 index_stack[sp-2]=index_stack[sp-1];
585
586 sp--;
587 break;
588 }
589 }
590
591 if(bError) goto error;
592
593 if(sp!=1){
594 SetError(1,NULL,cp);
595 goto error;
596 }
597
598 if(bLiteralCalculation){
599 //右辺値が数値の定数式の場合
600 LONG_PTR lpCalcIndex;
601 int base_type=0;
602 if(pBaseType) base_type=pBaseType->type;
603 i2=StaticCalculation(true, Command,base_type,&i64data,&lpCalcIndex);
604
605 type[0]=i2;
606 index_stack[0]=lpCalcIndex;
607 }
608 else{
609 //右辺値が数値の定数式ではないとき
610 if(IS_LITERAL(index_stack[0])) index_stack[0]=-1;
611 }
612
613 if(plpIndex) *plpIndex=index_stack[0];
614
615 int RetType;
616 RetType=type[0];
617 goto finish;
618
619
620 //////////////////
621 // エラー処理
622 //////////////////
623
624error:
625 RetType=-1;
626 goto finish;
627
628
629finish:
630 for(i=0;i<pnum;i++){
631 if(values[i]) HeapDefaultFree(values[i]);
632 }
633 return RetType;
634}
Note: See TracBrowser for help on using the repository browser.