source: dev/BasicCompiler_Common/NumOpe_GetType.cpp@ 79

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

バージョンをβ17にした。
#strictをデフォルトの状態で適用するようにした(#90)。
Dimステートメントにおいて、初期値式とAsが同時に指定されていたとき、As以降も初期値式の一部として捉えるよう、変更(#91)。
GetTypeDef関数を完全廃止。

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