source: dev/BasicCompiler_Common/NumOpe_GetType.cpp@ 73

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

Parameterクラスを適用。32bit側は動くようになったので、64bitのほうを調整する。

File size: 16.2 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_SBYTE;
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->params.size()){
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 Operator_New_GetType(const char *Parameter,LONG_PTR *plpIndex,const TYPEINFO &baseTypeInfo ){
258 char TypeName[VN_SIZE],CreateParameter[VN_SIZE],objectSizeStr[VN_SIZE];
259 int i,i2;
260
261 i=0;
262
263 if(Parameter[0]=='['){
264 i=GetStringInBracket(objectSizeStr,Parameter);
265
266 SlideString(objectSizeStr+1,-1);
267 objectSizeStr[i-2]=0;
268 }
269 else objectSizeStr[0]=0;
270
271 for(i2=0;;i++,i2++){
272 if(Parameter[i]=='('){
273 TypeName[i2]=0;
274
275 //コンストラクタに渡すパラメータを取得
276 i2=GetStringInPare(CreateParameter,Parameter+i);
277 RemoveStringPare(CreateParameter);
278 i+=i2;
279 if(Parameter[i]!='\0'){
280 SetError(42,NULL,cp);
281 return 0;
282 }
283 break;
284 }
285 TypeName[i2]=Parameter[i];
286 if(Parameter[i]=='\0'){
287 CreateParameter[0]=0;
288 break;
289 }
290 }
291
292 int type;
293 type=GetTypeFixed(TypeName,plpIndex);
294
295 if( baseTypeInfo.type == DEF_OBJECT ){
296 return DEF_OBJECT;
297 }
298 return DEF_PTR_OBJECT;
299}
300
301int NumOpe_GetType_Old( const char *Command,TYPEINFO *pBaseType,LONG_PTR *plpIndex){
302 extern int cp;
303 int i,i2,i3,i4;
304 char temporary[1024],temp2[1024],temp3[1024];
305
306 if(Command[0]=='\0'){
307 SetError(1,NULL,cp);
308 return 0;
309 }
310
311 if(Command[0]==1&& Command[1]==ESC_NEW ){
312 //New演算子(オブジェクト生成)
313 return Operator_New_GetType(Command+2,plpIndex, *pBaseType );
314 }
315
316
317 /////////////////////////////////
318 // 式要素を逆ポーランド式で取得
319 /////////////////////////////////
320
321 char *values[255];
322 long calc[255];
323 long stack[255];
324 int pnum;
325 if(!GetNumOpeElements(Command,&pnum,values,calc,stack)){
326 for(i=0;i<pnum;i++){
327 if(values[i]) HeapDefaultFree(values[i]);
328 }
329 return 0;
330 }
331
332
333
334 ////////////////////////////////
335 // 演算部分のコード生成を開始
336 ////////////////////////////////
337
338 BOOL bError;
339 bError=0;
340
341 //リテラル値のみの計算かどうかを判別するためのフラグ
342 BOOL bLiteralCalculation=1;
343
344 int sp;
345 int type[255];
346 LONG_PTR index_stack[255];
347 _int64 i64data;
348 int idCalc;
349 for(i=0,sp=0;i<pnum;i++){
350 idCalc=calc[i]%100;
351
352 if(idCalc){
353 if(type[sp-2]==DEF_OBJECT){
354 //オーバーロードされたオペレータを呼び出す
355 if(!GetReturnType_OperatorProc(idCalc,pBaseType,type,index_stack,sp)){
356 goto error;
357 }
358
359 continue;
360 }
361
362 if(!CheckCalcType(idCalc,type,sp)) goto error;
363 }
364
365 switch(idCalc){
366 //数値
367 case 0:
368 index_stack[sp]=-1;
369
370 char *term;
371 term = values[i];
372
373 if(term[0]=='\"'){
374StrLiteral:
375
376 if(pBaseType){
377 if(pBaseType->type==DEF_OBJECT){
378 if(IsStringObjectType(*pBaseType)){
379 //要求タイプがオブジェクトであり、Stringの受け入れが可能な場合
380 extern CClass *pobj_StringClass;
381 type[sp]=DEF_OBJECT;
382 index_stack[sp]=(LONG_PTR)pobj_StringClass;
383 bLiteralCalculation=0;
384
385 sp++;
386 break;
387 }
388 }
389 }
390
391 type[sp]=typeOfPtrChar;
392 bLiteralCalculation=0;
393 }
394 else if((term[0]=='e'||term[0]=='E')&&
395 (term[1]=='x'||term[1]=='X')&&
396 term[2]=='\"'){
397 //拡張版リテラル文字列(エスケープシーケンス可能)
398 goto StrLiteral;
399 }
400 else if(IsVariableTopChar(term[0])||
401 term[0]=='*'||
402 (term[0]=='.'&&IsVariableTopChar(term[1]))){
403 //////////////////
404 // 何らかの識別子
405
406 //////////////////////////////////////
407 // 関数(DLL、ユーザー定義、組み込み)
408 //////////////////////////////////////
409
410 i2=GetCallProcName(term,temporary);
411 if(term[i2]=='('){
412 i4=GetStringInPare_RemovePare(temp2,term+i2+1);
413
414 int idProc;
415 void *pInfo;
416 idProc=GetProc(temporary,&pInfo);
417
418 if(idProc){
419 //閉じカッコ")"に続く文字がNULLでないとき
420 if(term[i2+1+i4+1]!='\0'){
421 if( term[i2+1+i4+1] == '.'
422 || term[i2+1+i4+1] == 1 && term[i2+1+i4+2] == ESC_PSMEM ){
423 goto NonProc;
424 }
425 else{
426 SetError(42,NULL,cp);
427 }
428 }
429
430
431 ////////////////
432 // 呼び出し
433 ////////////////
434
435 i2=GetReturnTypeOfProc(idProc,pInfo,temporary,temp2,&index_stack[sp]);
436 if(i2==-1){
437 //戻り値が存在しないとき
438 goto error;
439 }
440
441 type[sp]=i2;
442 bLiteralCalculation=0;
443
444 sp++;
445 break;
446 }
447 else if(GetConstCalcBuffer(temporary,temp2,temp3)){
448 /////////////////////////
449 // マクロ関数
450 /////////////////////////
451
452 //閉じカッコ")"に続く文字がNULLでないときはエラーにする
453 if(term[i2+1+i4+1]!='\0') SetError(42,NULL,cp);
454
455 //マクロ関数の場合
456 i2=NumOpe_GetType_Old(temp3,NULL,&index_stack[sp]);
457
458 if(!IS_LITERAL(index_stack[sp])){
459 //リテラル値ではなかったとき
460 bLiteralCalculation=0;
461 }
462
463 type[sp]=i2;
464
465 sp++;
466 break;
467 }
468 }
469NonProc:
470
471 //インデクサ(getアクセサ)
472 char VarName[VN_SIZE],ArrayElements[VN_SIZE];
473 GetArrayElement(term,VarName,ArrayElements);
474 if(ArrayElements[0]){
475 CClass *pobj_c;
476 i2=GetVarType(VarName,(LONG_PTR *)&pobj_c,0);
477 if(i2==DEF_OBJECT){
478 TYPEINFO RetTypeInfo;
479 if( !GetReturnTypeOfIndexerGetterProc(pobj_c,RetTypeInfo) ){
480 SetError(1,NULL,cp);
481 goto error;
482 }
483 type[sp]=RetTypeInfo.type;
484 index_stack[sp]=RetTypeInfo.u.lpIndex;
485 bLiteralCalculation=0;
486
487 sp++;
488 break;
489 }
490 }
491
492
493 // Nothing
494 if( lstrcmp( term, "Nothing" ) == 0 ){
495 type[sp] = DEF_OBJECT;
496 if( pBaseType && pBaseType->type == DEF_OBJECT ){
497 index_stack[sp] = pBaseType->u.lpIndex;
498 }
499 else{
500 index_stack[sp] = (LONG_PTR)pobj_DBClass->GetObjectClass();
501 }
502 bLiteralCalculation = 0;
503 sp++;
504 break;
505 }
506
507
508 i2=GetVarType(term,&index_stack[sp],0);
509 if(i2!=-1){
510 //////////
511 // 変数
512 //////////
513
514 if(i2&FLAG_PTR){
515 //配列ポインタ
516 type[sp]=GetPtrType(i2^FLAG_PTR,index_stack[sp]);
517 }
518 else{
519 type[sp]=i2;
520 }
521
522 bLiteralCalculation=0;
523 sp++;
524 break;
525 }
526
527
528 //////////////
529 // 定数の場合
530 //////////////
531
532 i3 = CDBConst::obj.GetType(term);
533 if(i3){
534 type[sp]=i3;
535 if(IsRealNumberType(i3)){
536 //実数
537 goto Literal;
538 }
539 else if(IsWholeNumberType(i3)){
540 //整数
541 goto Literal;
542 }
543 else if(Is64Type(i3)){
544 //64ビット整数値
545 goto Literal;
546 }
547 else if(i3==DEF_STRING){
548 //リテラル文字列
549 goto StrLiteral;
550 }
551 else{
552 SetError(1,NULL,0);
553 goto error;
554 }
555 }
556
557
558 //////////////
559 // 型名の場合
560 //////////////
561
562 LONG_PTR lp;
563 i3=GetTypeFixed(term,&lp);
564 if(i3!=-1){
565 type[sp]=i3|FLAG_CAST;
566 index_stack[sp]=lp;
567 sp++;
568 break;
569 }
570
571
572
573 /////////////////////////////////
574 // プロパティ用のメソッド
575 /////////////////////////////////
576
577 //配列要素を排除
578 GetArrayElement(term,VarName,ArrayElements);
579
580 if(GetSubHash(VarName,0)){
581 TYPEINFO RetTypeInfo;
582 GetReturnTypeOfPropertyMethod(term,NULL,&RetTypeInfo);
583
584 //大きな型への暗黙の変換
585 type[sp]=RetTypeInfo.type;
586
587 index_stack[sp]=RetTypeInfo.u.lpIndex;
588 bLiteralCalculation=0;
589
590 sp++;
591 break;
592 }
593
594
595
596 //該当する識別子が見当たらないときはエラー扱いにする
597 bError=1;
598 SetError(3,term,cp);
599 type[sp]=DEF_DOUBLE;
600 }
601 else{
602 //リテラル値
603 int base_type;
604 base_type=0;
605 if(pBaseType) base_type=pBaseType->type;
606 type[sp]=GetLiteralValue(term,&i64data,base_type);
607Literal:
608 if((long)i64data==0&&index_stack[sp]==-1) index_stack[sp]=LITERAL_NULL;
609 }
610
611 sp++;
612 break;
613
614 //論理演算子
615 case CALC_XOR:
616 case CALC_OR:
617 case CALC_AND:
618 sp--;
619 type[sp-1]=NeutralizationType(type[sp-1],index_stack[sp-1],type[sp],index_stack[sp]);
620 break;
621 case CALC_NOT:
622 //values[sp-1]=Not values[sp-1]
623 //NOT演算子
624 break;
625
626 //比較演算子
627 case CALC_PE: //values[sp-2] <= values[sp-1]
628 case CALC_QE: //values[sp-2] >= values[sp-1]
629 case CALC_P: //values[sp-2] < values[sp-1]
630 case CALC_Q: //values[sp-2] > values[sp-1]
631 case CALC_NOTEQUAL: //values[sp-2] <> values[sp-1]
632 case CALC_EQUAL: //values[sp-2] = values[sp-1]
633 sp--;
634 type[sp-1]=DEF_LONG;
635 break;
636
637 //ビットシフト
638 case CALC_SHL: //values[sp-2] << values[sp-1]
639 case CALC_SHR: //values[sp-2] >> values[sp-1]
640 sp--;
641 break;
642
643 //算術演算
644 case CALC_ADDITION:
645 case CALC_SUBTRACTION:
646 case CALC_PRODUCT:
647 sp--;
648 type[sp-1]=NeutralizationType(type[sp-1],index_stack[sp-1],type[sp],index_stack[sp]);
649 break;
650 case CALC_MOD:
651 //values[sp-2]%=values[sp-1]
652 //剰余演算
653 sp--;
654 type[sp-1]=NeutralizationType(type[sp-1],index_stack[sp-1],type[sp],index_stack[sp]);
655 break;
656 case CALC_QUOTIENT:
657 //values[sp-2]/=values[sp-1];
658 //除算
659 sp--;
660 type[sp-1]=NeutralizationType(type[sp-1],index_stack[sp-1],type[sp],index_stack[sp]);
661 break;
662 case CALC_INTQUOTIENT:
663 //values[sp-2]/=values[sp-1]
664 //整数除算
665 sp--;
666 type[sp-1]=NeutralizationType(type[sp-1],index_stack[sp-1],type[sp],index_stack[sp]);
667 break;
668 case CALC_MINUSMARK:
669 //values[sp-1]=-values[sp-1]
670 //符号反転
671 break;
672 case CALC_POWER:
673 //べき乗演算(浮動小数点演算のみ)
674 sp--;
675 //未完成
676 break;
677 case CALC_AS:
678 //キャスト
679 type[sp-2]=type[sp-1]&(~FLAG_CAST);
680 index_stack[sp-2]=index_stack[sp-1];
681
682 sp--;
683 break;
684
685 case CALC_BYVAL:
686 //ポインタ型→参照型
687 if( PTR_LEVEL( type[sp-1] ) <= 0 ){
688 //ポインタ型ではないとき
689 SetError( 3, NULL, cp );
690 goto error;
691 }
692
693 type[sp-1] = PTR_LEVEL_DOWN( type[sp-1] );
694 break;
695 }
696 }
697
698 if(bError) goto error;
699
700 if(sp!=1){
701 SetError(1,NULL,cp);
702 goto error;
703 }
704
705 if(bLiteralCalculation){
706 //右辺値が数値の定数式の場合
707 LONG_PTR lpCalcIndex;
708 int base_type=0;
709 if(pBaseType) base_type=pBaseType->type;
710 i2=StaticCalculation(true, Command,base_type,&i64data,&lpCalcIndex);
711
712 type[0]=i2;
713 index_stack[0]=lpCalcIndex;
714 }
715 else{
716 //右辺値が数値の定数式ではないとき
717 if(IS_LITERAL(index_stack[0])) index_stack[0]=-1;
718 }
719
720 if(plpIndex) *plpIndex=index_stack[0];
721
722 int RetType;
723 RetType=type[0];
724 goto finish;
725
726
727 //////////////////
728 // エラー処理
729 //////////////////
730
731error:
732 RetType=-1;
733 goto finish;
734
735
736finish:
737 for(i=0;i<pnum;i++){
738 if(values[i]) HeapDefaultFree(values[i]);
739 }
740 return RetType;
741}
742
743bool NumOpe_GetType( const char *expression, const Type &baseType, Type &resultType ){
744 TYPEINFO baseTypeInfo = {
745 baseType.GetBasicType(),
746 baseType.GetIndex()
747 };
748 LONG_PTR lpIndex;
749 int basicType = NumOpe_GetType_Old( expression,
750 baseType.IsNull() ? NULL:&baseTypeInfo,
751 &lpIndex );
752
753 resultType.SetBasicType( basicType );
754 resultType.SetIndex( lpIndex );
755
756 return ( basicType != -1 );
757}
Note: See TracBrowser for help on using the repository browser.