source: dev/BasicCompiler_Common/NumOpe_GetType.cpp@ 94

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

New[]を禁止した。
一部の動的型情報が生成されないバグを修正。
As演算子によるダウンキャストを許可(プログラム的なチェックはまだ走っていない)

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