source: dev/trunk/abdev/BasicCompiler_Common/NumOpe_GetType.cpp@ 415

Last change on this file since 415 was 415, checked in by dai_9181, 16 years ago

代入演算時の左辺に関数呼び出しの戻り値を評価してメンバを取得するようなコードが存在するとき、エラーになってしまっていたので改修した。(32bit版のみ対応)

File size: 23.0 KB
Line 
1#include "stdafx.h"
2
3#include <jenga/include/smoothie/Smoothie.h>
4
5#include <Compiler.h>
6
7#include "common.h"
8
9
10int MakeWholeType(int size,int bSigned){
11 switch(size){
12 case 1:
13 if(bSigned) return DEF_SBYTE;
14 else return DEF_BYTE;
15 break;
16 case 2:
17 if(bSigned) return DEF_INTEGER;
18 else return DEF_WORD;
19 break;
20 case 4:
21 if(bSigned) return DEF_LONG;
22 else return DEF_DWORD;
23 break;
24 case 8:
25 if(bSigned) return DEF_INT64;
26 else return DEF_QWORD;
27 break;
28 }
29 return 0;
30}
31
32int AutoBigCast(int BaseType,int CalcType){
33 int type;
34 type=CalcType;
35
36 if(BaseType==0||BaseType==-1){
37 //ベースタイプが未定のとき
38 return type;
39 }
40
41 if(!IsWholeNumberType(type)){
42 //整数型ではないときは暗黙の変換は必要なし
43 return type;
44 }
45
46 if(BaseType==DEF_OBJECT||BaseType==DEF_STRUCT){
47 //ベースタイプがオブジェクトのときは暗黙の変換は必要なし
48 return type;
49 }
50
51 int BaseTypeSize;
52 BaseTypeSize=Type(BaseType,-1).GetSize();
53
54 if(IsRealNumberType(BaseType)){
55 if(Type(CalcType,-1).GetSize()<4)
56 type=MakeWholeType(4,IsSignedType(CalcType));
57 }
58 else if(BaseTypeSize>Type(CalcType,-1).GetSize()){
59 //要求される型のほうがサイズが大きいとき
60 type=MakeWholeType(BaseTypeSize,IsSignedType(CalcType));
61 }
62
63 if(!type){
64 extern int cp;
65 SetError(300,NULL,cp);
66 }
67
68 return type;
69}
70
71BOOL CheckCalcType(int idCalc,int *type,int sp){
72 //演算子の右辺、左辺の型をチェック
73 extern int cp;
74
75 //演算子名を取得
76 char temporary[255];
77 GetCalcName(idCalc,temporary);
78
79 switch(idCalc){
80
81 /////////////////////////////////////
82 // 実数に対する論理演算はエラー
83 /////////////////////////////////////
84
85 case CALC_XOR:
86 case CALC_OR:
87 case CALC_AND:
88 if(IsRealNumberType(type[sp-2])||IsRealNumberType(type[sp-1])){
89 //いずれかの項が実数のとき
90 SetError(45,temporary,cp);
91 return 0;
92 }
93
94 //As以外の演算子に型名が指定されていないかをチェック
95 if((type[sp-2]&FLAG_CAST)||(type[sp-1]&FLAG_CAST)){
96 SetError(48,temporary,cp);
97 return 0;
98 }
99 break;
100
101 case CALC_NOT:
102 if(IsRealNumberType(type[sp-1])){
103 //実数のとき
104 SetError(45,temporary,cp);
105 return 0;
106 }
107
108 //As以外の演算子に型名が指定されていないかをチェック
109 if(type[sp-1]&FLAG_CAST){
110 SetError(48,temporary,cp);
111 return 0;
112 }
113 break;
114
115
116
117 /////////////////////////////////////
118 // 比較演算はチェック項目なし
119 /////////////////////////////////////
120
121 case CALC_PE:
122 case CALC_QE:
123 case CALC_NOTEQUAL:
124 case CALC_EQUAL:
125 case CALC_P:
126 case CALC_Q:
127 //As以外の演算子に型名が指定されていないかをチェック
128 if((type[sp-2]&FLAG_CAST)||(type[sp-1]&FLAG_CAST)){
129 SetError(48,temporary,cp);
130 return 0;
131 }
132 break;
133
134
135
136 /////////////////////////////////////
137 // 算術演算をチェック
138 /////////////////////////////////////
139
140 case CALC_ADDITION:
141 case CALC_SUBTRACTION:
142 case CALC_PRODUCT:
143 case CALC_QUOTIENT:
144 case CALC_POWER:
145 //As以外の演算子に型名が指定されていないかをチェック
146 if((type[sp-2]&FLAG_CAST)||(type[sp-1]&FLAG_CAST)){
147 SetError(48,temporary,cp);
148 return 0;
149 }
150 break;
151
152 case CALC_SHL:
153 case CALC_SHR:
154 case CALC_MOD:
155 case CALC_INTQUOTIENT:
156 if(IsRealNumberType(type[sp-2])||IsRealNumberType(type[sp-1])){
157 //いずれかの項が実数のとき
158 SetError(45,temporary,cp);
159 return 0;
160 }
161
162 //As以外の演算子に型名が指定されていないかをチェック
163 if((type[sp-2]&FLAG_CAST)||(type[sp-1]&FLAG_CAST)){
164 SetError(48,temporary,cp);
165 return 0;
166 }
167 break;
168
169 case CALC_AS:
170 if((type[sp-1]&FLAG_CAST)==0){
171 //型名が指定されていないときはエラー
172 SetError(47,NULL,cp);
173 return 0;
174 }
175 break;
176
177 case CALC_BYVAL:
178 if(type[sp-1]&FLAG_CAST){
179 //型名が指定されていないときはエラー
180 SetError(47,NULL,cp);
181 return 0;
182 }
183 break;
184
185 case CALC_MINUSMARK:
186 //As以外の演算子に型名が指定されていないかをチェック
187 if(type[sp-1]&FLAG_CAST){
188 SetError(48,temporary,cp);
189 return 0;
190 }
191 break;
192 }
193 return 1;
194}
195
196int GetReturnType_OperatorProc(int idCalc,const Type &baseType,int *type,LONG_PTR *index_stack,int &sp){
197 //オーバーロードされたオペレータ関数の戻り値を取得
198 CClass *pobj_c;
199 pobj_c=(CClass *)index_stack[sp-2];
200
201 std::vector<const UserProc *> subs;
202 pobj_c->GetDynamicMethods().Enum( idCalc, subs );
203 if( subs.size() == 0 ){
204 return 0;
205 }
206
207
208 //項の数
209 BOOL bTwoTerm=1;
210 if(idCalc==CALC_AS) bTwoTerm=0;
211
212
213
214 /////////////////////////////////////////////
215 // オーバーロード解決用のパラメータを設定
216 /////////////////////////////////////////////
217
218
219 //_System_LocalThis
220 Parameters params;
221
222 if(bTwoTerm){
223 params.push_back( new Parameter( "", Type( type[sp-1], index_stack[sp-1] ) ) );
224 }
225
226
227 //オーバーロードを解決
228 char temporary[255];
229 if(idCalc==CALC_EQUAL) lstrcpy(temporary,"==");
230 else GetCalcName(idCalc,temporary);
231 const UserProc *pUserProc = OverloadSolution( temporary, subs, params, baseType );
232
233 if(bTwoTerm){
234 delete params[0];
235 }
236
237 if(!pUserProc){
238 return 0;
239 }
240 else{
241 //オーバーロードされていないが、パラメータ個数が一致しないとき
242 if(params.size()!=pUserProc->Params().size()){
243 return 0;
244 }
245 }
246
247 sp--;
248 type[sp-1]=pUserProc->ReturnType().GetBasicType();
249 index_stack[sp-1]=pUserProc->ReturnType().GetIndex();
250
251 return 1;
252}
253
254bool Operator_New_GetType(const char *Parameter,const Type &baseType, Type &resultType ){
255 char TypeName[VN_SIZE],objectSizeStr[VN_SIZE];
256 int i,i2;
257
258 i=0;
259
260 if(Parameter[0]=='['){
261 i=GetStringInBracket(objectSizeStr,Parameter);
262
263 SlideString(objectSizeStr+1,-1);
264 objectSizeStr[i-2]=0;
265 }
266 else objectSizeStr[0]=0;
267
268 for(i2=0;;i++,i2++){
269 if(Parameter[i]=='(' || Parameter[i]=='['){
270 TypeName[i2]=0;
271 break;
272 }
273 TypeName[i2]=Parameter[i];
274 if(Parameter[i]=='\0'){
275 break;
276 }
277 }
278
279 if( !compiler.StringToType( TypeName, resultType ) )
280 {
281 SetError(3,TypeName,cp);
282 return false;
283 }
284
285 if( !resultType.IsObject() )
286 {
287 SetError(121,NULL,cp);
288 return false;
289 }
290
291 if( baseType.IsObject() ){
292 resultType.SetBasicType( DEF_OBJECT );
293 }
294 else{
295 resultType.SetBasicType( DEF_PTR_OBJECT );
296 }
297 return true;
298}
299
300bool GetMemberTermType( const Type &leftType, const Type &baseType, Type &resultType, const char *termFull, const char *termLeft, const char *member, bool *pIsVariable )
301{
302 ////////////////////////////////
303 // インデクサ(getアクセサ)
304 ////////////////////////////////
305
306 char VarName[VN_SIZE],ArrayElements[VN_SIZE];
307 GetArrayElement(member,VarName,ArrayElements);
308 if(ArrayElements[0]){
309 Type classType;
310 GetMemberType( leftType, VarName, classType, 0, false );
311 if( classType.IsObject() ){
312 if( !GetReturnTypeOfIndexerGetterProc( classType, resultType ) ){
313 SetError(1,NULL,cp);
314 return false;
315 }
316
317 return true;
318 }
319 }
320
321
322 ///////////////////////////////////////////////////////////////////
323 // メンバを検索
324 ///////////////////////////////////////////////////////////////////
325 if( GetMemberType( leftType, member, resultType, 0, false ) ){
326 // メンバが見つかったとき
327
328 if( pIsVariable )
329 {
330 *pIsVariable = true;
331 }
332
333 return true;
334 }
335
336
337 ///////////////////////////////////////////////////////////////////
338 // 動的メソッドを検索
339 ///////////////////////////////////////////////////////////////////
340 char methodName[VN_SIZE] ,lpPtrOffset[VN_SIZE], dummy[1];
341 char parameter[VN_SIZE];
342 ReferenceKind refType;
343 lstrcpy( methodName, member );
344 GetVarFormatString(methodName,parameter,lpPtrOffset,dummy,refType);
345
346 vector<const UserProc *> userProcs;
347 leftType.GetClass().EnumDynamicMethodsOrInterfaceMethods( methodName, userProcs );
348 if(userProcs.size()){
349 //オーバーロードを解決
350 const UserProc *pUserProc = OverloadSolutionWithStrParam(termFull,userProcs,parameter,termLeft);
351
352 if( pUserProc ){
353 resultType = pUserProc->ReturnType();
354
355 // 型パラメータを解決
356 ResolveFormalGenericTypeParameter( resultType, leftType, pUserProc );
357
358 return true;
359 }
360 }
361
362 return false;
363}
364
365bool GetTermType( const char *term, const Type &baseType, Type &resultType, bool &isLiteral, bool *pIsClassName, bool *pIsVariable )
366{
367 char parameter[VN_SIZE];
368
369 // Withを解決
370 char termFull[VN_SIZE];
371 if(term[0]=='.'){
372 GetWithName(termFull);
373 lstrcat(termFull,term);
374 }
375 else lstrcpy(termFull,term);
376
377 char termLeft[VN_SIZE];
378 lstrcpy(termLeft,termFull);
379
380 // パース
381 char member[VN_SIZE];
382 ReferenceKind refType;
383 if( SplitMemberName( termFull, termLeft, member, refType ) ){
384 ///////////////////////////////////////////////////////////////////
385 // オブジェクトとメンバに分解できるとき
386 // termLeft.member
387 ///////////////////////////////////////////////////////////////////
388
389 isLiteral = false;
390
391 // オブジェクト側の型を取得
392 bool isClassName = false;
393 Type leftType;
394 if( GetTermType( termLeft, Type(), leftType, isLiteral, &isClassName ) ){
395 if( isClassName == false && compiler.GetObjectModule().meta.GetBlittableTypes().IsExist( leftType ) ){
396 // 左側のオブジェクト部分がBlittable型のとき
397
398 char temporary[VN_SIZE];
399 lstrcpy( temporary, termLeft );
400 sprintf( termLeft, "%s(%s)",
401 compiler.GetObjectModule().meta.GetBlittableTypes().Find( leftType ).GetCreateStaticMethodFullName().c_str(),
402 temporary );
403
404 if( !GetTermType( termLeft, Type(), leftType, isLiteral, &isClassName ) ){
405 goto globalArea;
406 }
407 }
408 }
409 else{
410 goto globalArea;
411 }
412
413 if( isClassName ){
414 // 静的メンバ/メソッドの場合
415 goto globalArea;
416 }
417
418 if( !leftType.HasMember() ){
419 // メンバを持たない型の場合
420 return false;
421 }
422
423 return GetMemberTermType( leftType, baseType, resultType, termFull, termLeft, member, pIsVariable );
424 }
425
426
427 //////////////////////////////////////////////
428 // クラス名かどうかをチェック(静的メンバ用)
429 //////////////////////////////////////////////
430
431 if( pIsClassName ){
432 if( compiler.GetObjectModule().meta.GetClasses().Find( termFull ) ){
433 *pIsClassName = true;
434 return true;
435 }
436 }
437
438
439 /////////////////////////////////////////////////////////////////
440 // グローバル属性
441 /////////////////////////////////////////////////////////////////
442globalArea:
443
444
445 if(lstrcmpi(termFull,"This")==0){
446 if( compiler.pCompilingClass == NULL )
447 {
448 return false;
449 }
450
451 //Thisオブジェクト
452 resultType.SetType( DEF_OBJECT, compiler.pCompilingClass );
453 isLiteral = false;
454 return true;
455 }
456
457
458 //////////////////////////////////////
459 // 関数(DLL、ユーザー定義、組み込み)
460 //////////////////////////////////////
461 char procName[VN_SIZE];
462 char temporary[8192];
463
464 int i2=GetCallProcName(termFull,procName);
465 if(termFull[i2]=='('){
466 int i4=GetStringInPare_RemovePare(parameter,termFull+i2+1);
467
468 void *pProc;
469 int idProc=GetProc(procName,(void **)&pProc);
470
471 if(idProc){
472 //閉じカッコ")"に続く文字がNULLでないとき
473 if(termFull[i2+1+i4+1]!='\0'){
474 SetError(42,NULL,cp);
475 }
476
477
478 ////////////////
479 // 呼び出し
480 ////////////////
481
482 if( !CallProc(idProc,pProc,procName,parameter, baseType, resultType, false ) ){
483 return false;
484 }
485 if( resultType.IsNull() ){
486 //戻り値が存在しないとき
487 return false;
488 }
489
490 isLiteral = false;
491
492 return true;
493 }
494 else
495 {
496 ConstMacro *pConstMacro = compiler.GetObjectModule().meta.GetGlobalConstMacros().Find( procName );
497 if( pConstMacro )
498 {
499 if( pConstMacro->GetCalcBuffer( parameter, temporary ) )
500 {
501 /////////////////////////
502 // マクロ関数
503 /////////////////////////
504
505 //閉じカッコ")"に続く文字がNULLでないときはエラーにする
506 if(termFull[i2+1+i4+1]!='\0') SetError(42,NULL,cp);
507
508 //マクロ関数の場合
509 if( !NumOpe_GetType(temporary,Type(),resultType) ){
510 return false;
511 }
512
513 if( !IS_LITERAL( resultType.GetIndex() ) ){
514 //リテラル値ではなかったとき
515 isLiteral = false;
516 }
517
518 return true;
519 }
520 }
521 }
522 }
523
524
525 ////////////////////////////////
526 // インデクサ(getアクセサ)
527 ////////////////////////////////
528
529 char VarName[VN_SIZE],ArrayElements[VN_SIZE];
530 GetArrayElement(termFull,VarName,ArrayElements);
531 if(ArrayElements[0]){
532 Type classType;
533 GetVarType(VarName,classType,false);
534 if( classType.IsObject() ){
535 if( !GetReturnTypeOfIndexerGetterProc( classType, resultType ) ){
536 SetError(1,NULL,cp);
537 return false;
538 }
539
540 isLiteral = false;
541
542 return true;
543 }
544 }
545
546
547 ////////////////////////////////
548 // 変数
549 ////////////////////////////////
550
551 if( GetVarType( termFull, resultType, false ) ){
552 if( resultType.GetBasicType() & FLAG_PTR ){
553 //配列ポインタ
554 resultType.SetBasicType( GetPtrType( resultType.GetBasicType()^FLAG_PTR ) );
555 }
556
557 isLiteral = false;
558
559 if( pIsVariable )
560 {
561 // 変数である
562 *pIsVariable = true;
563 }
564
565 return true;
566 }
567
568
569 /////////////////////////////////
570 // プロパティ用のメソッド
571 /////////////////////////////////
572
573 //配列要素を排除
574 GetArrayElement(termFull,VarName,ArrayElements);
575
576 if(GetSubHash(VarName,0)){
577 GetReturnTypeOfPropertyMethod(termFull,NULL,resultType);
578
579 isLiteral = false;
580
581 return true;
582 }
583
584
585 return false;
586}
587
588bool GetTermType( const char *term, Type &resultType )
589{
590 bool isLiteral;
591 return GetTermType( term, Type(), resultType, isLiteral );
592}
593
594bool GetTermTypeOnlyVariable( const char *term, Type &resultType )
595{
596 bool isLiteral, isVariable = false;
597 bool result = GetTermType( term, Type(), resultType, isLiteral, NULL, &isVariable );
598 return ( result && isVariable );
599}
600
601bool NumOpe_GetType( const char *expression, const Type &baseType, Type &resultType, bool *pIsLiteralCalculation ){
602 extern int cp;
603 int i,i3;
604
605 //リテラル値のみの計算かどうかを判別するためのフラグ
606 bool dummyBool;
607 if( pIsLiteralCalculation == NULL )
608 {
609 pIsLiteralCalculation = &dummyBool;
610 }
611 *pIsLiteralCalculation = true;
612
613 if(expression[0]=='\0'){
614 SetError(1,NULL,cp);
615 return false;
616 }
617
618 if(expression[0]==1&& ( expression[1]==ESC_NEW || expression[1] == ESC_SYSTEM_STATIC_NEW ) ){
619 //New演算子(オブジェクト生成)
620 *pIsLiteralCalculation = false;
621 return Operator_New_GetType(expression+2,baseType, resultType );
622 }
623
624 if( expression[0] == '[' ){
625 if( !baseType.IsPointer() ){
626 return false;
627 }
628
629 resultType = baseType;
630 return true;
631 }
632
633
634 /////////////////////////////////
635 // 式要素を逆ポーランド式で取得
636 /////////////////////////////////
637
638 char *values[255];
639 long calc[255];
640 long stack[255];
641 int pnum;
642 if(!GetNumOpeElements(expression,&pnum,values,calc,stack)){
643 for(i=0;i<pnum;i++){
644 if(values[i]) HeapDefaultFree(values[i]);
645 }
646 return false;
647 }
648
649
650
651 ////////////////////////////////
652 // 演算部分のコード生成を開始
653 ////////////////////////////////
654
655 BOOL bError;
656 bError=0;
657
658 int sp;
659 int type_stack[255];
660 LONG_PTR index_stack[255];
661 bool isNothing_stack[255];
662 _int64 i64data;
663 int idCalc;
664 for(i=0,sp=0;i<pnum;i++){
665 idCalc=calc[i]%100;
666
667 if(idCalc){
668 if(type_stack[sp-2]==DEF_OBJECT){
669 if( idCalc == CALC_AS
670 && type_stack[sp-1] == ( DEF_OBJECT | FLAG_CAST )
671 && index_stack[sp-1] == index_stack[sp-2]
672 || isNothing_stack[sp-2] ){
673 // 同一の型、またはNothingに対するAsはAs演算子を呼び出さない
674 }
675 else if( idCalc == CALC_AS
676 && type_stack[sp-1] == ( DEF_OBJECT | FLAG_CAST )
677 && ( ((CClass *)index_stack[sp-1])->IsEqualsOrSubClass( (CClass *)index_stack[sp-2] ) || ((CClass *)index_stack[sp-2])->IsEqualsOrSubClass( (CClass *)index_stack[sp-1] )
678 )){
679 // ダウンキャストを許可する
680 }
681 else if( idCalc == CALC_AS ){
682 // NumOpe_GetTypeではすべてのキャストを許可する
683 }
684 else{
685 //オーバーロードされたオペレータを呼び出す
686 if(!GetReturnType_OperatorProc(idCalc,baseType,type_stack,index_stack,sp)){
687 goto error;
688 }
689
690 continue;
691 }
692 }
693
694 if(!CheckCalcType(idCalc,type_stack,sp)) goto error;
695 }
696
697 switch(idCalc){
698 //数値
699 case 0:
700 index_stack[sp]=-1;
701 isNothing_stack[sp] = false;
702
703 char *term;
704 term = values[i];
705
706 if( calc[i+1]%100 == CALC_AS ){
707 // As演算子の右辺値
708 //型名
709 if( compiler.StringToType( term, resultType ) ){
710
711 if( resultType.IsObject() ){
712 if( resultType.GetClass().IsBlittableType() ){
713 // Blittable型のときは基本型として扱う
714 // ※ただし、コンパイル中のメソッドがBlittable型クラスに属していないこと
715 if( UserProc::IsLocalAreaCompiling()
716 && UserProc::CompilingUserProc().HasParentClass()
717 && UserProc::CompilingUserProc().GetParentClass().IsBlittableType() )
718 {
719 // コンパイル中のメソッドがBlittable型クラスに属している
720 }
721 else{
722 resultType = resultType.GetClass().GetBlittableType();
723 }
724 }
725 }
726
727 resultType.SetBasicType( resultType.GetBasicType() | FLAG_CAST );
728 }
729 else{
730 SetError(3, term, cp );
731 goto error;
732 }
733
734 type_stack[sp] = resultType.GetBasicType();
735 index_stack[sp] = resultType.GetIndex();
736 sp++;
737
738 break;
739 }
740
741 if(term[0]=='\"'){
742StrLiteral:
743
744 if( !baseType.IsPointer() ){
745 //要求タイプがオブジェクト、または未定のとき
746 type_stack[sp]=DEF_OBJECT;
747 index_stack[sp]=(LONG_PTR)compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr();
748 *pIsLiteralCalculation = false;
749
750 sp++;
751 break;
752 }
753
754 type_stack[sp]=typeOfPtrChar;
755 *pIsLiteralCalculation = false;
756 }
757 else if((term[0]=='e'||term[0]=='E')&&
758 (term[1]=='x'||term[1]=='X')&&
759 term[2]=='\"'){
760 //拡張版リテラル文字列(エスケープシーケンス可能)
761 goto StrLiteral;
762 }
763 else if(IsVariableTopChar(term[0])||
764 term[0]=='*'||
765 (term[0]=='.'&&IsVariableTopChar(term[1])))
766 {
767 //////////////////
768 // 何らかの識別子
769
770 bool isLiteral = true;
771 if( GetTermType( term, baseType, resultType, isLiteral ) ){
772 type_stack[sp] = resultType.GetBasicType();
773 index_stack[sp] = resultType.GetIndex();
774
775 if( !isLiteral ){
776 *pIsLiteralCalculation = false;
777 }
778
779 sp++;
780 break;
781 }
782
783
784 // Nothing
785 if( lstrcmp( term, "Nothing" ) == 0 ){
786 isNothing_stack[sp] = true;
787
788 type_stack[sp] = DEF_OBJECT;
789 if( baseType.IsObject() ){
790 index_stack[sp] = baseType.GetIndex();
791 }
792 else{
793 index_stack[sp] = (LONG_PTR)compiler.GetObjectModule().meta.GetClasses().GetObjectClassPtr();
794 }
795 *pIsLiteralCalculation = false;
796 sp++;
797 break;
798 }
799
800
801 //////////////
802 // 定数の場合
803 //////////////
804
805 i3 = compiler.GetObjectModule().meta.GetGlobalConsts().GetBasicType(term);
806 if(i3){
807 if( compiler.GetObjectModule().meta.GetGlobalConsts().IsStringPtr( term ) ){
808 //リテラル文字列
809 goto StrLiteral;
810 }
811
812 type_stack[sp]=i3;
813 if(IsRealNumberType(i3)){
814 //実数
815 goto Literal;
816 }
817 else if(IsWholeNumberType(i3)){
818 //整数
819 goto Literal;
820 }
821 else if(Is64Type(i3)){
822 //64ビット整数値
823 goto Literal;
824 }
825 else{
826 SetError(1,NULL,0);
827 goto error;
828 }
829 }
830
831
832 /////////////////////////////////
833 // プロパティ用のメソッド
834 /////////////////////////////////
835
836 //配列要素を排除
837 char VarName[VN_SIZE],ArrayElements[VN_SIZE];
838 GetArrayElement(term,VarName,ArrayElements);
839
840 if(GetSubHash(VarName,0)){
841 SetError();
842 Type tempType;
843 GetReturnTypeOfPropertyMethod(term,NULL,tempType);
844
845 //大きな型への暗黙の変換
846 type_stack[sp]=tempType.GetBasicType();
847
848 index_stack[sp]=tempType.GetIndex();
849 *pIsLiteralCalculation = false;
850
851 sp++;
852 break;
853 }
854
855
856
857 //該当する識別子が見当たらないときはエラー扱いにする
858 bError=1;
859 SetError(3,term,cp);
860 type_stack[sp]=DEF_DOUBLE;
861 }
862 else{
863 //リテラル値
864 int base_type = 0;
865 if( !baseType.IsNull() ) base_type = baseType.GetBasicType();
866 type_stack[sp]=GetLiteralValue(term,&i64data,base_type);
867Literal:
868 if((long)i64data==0&&index_stack[sp]==-1) index_stack[sp]=LITERAL_NULL;
869 }
870
871 sp++;
872 break;
873
874 //論理演算子
875 case CALC_XOR:
876 case CALC_OR:
877 case CALC_AND:
878 sp--;
879 type_stack[sp-1]=NeutralizationType(type_stack[sp-1],index_stack[sp-1],type_stack[sp],index_stack[sp]);
880 break;
881 case CALC_NOT:
882 //values[sp-1]=Not values[sp-1]
883 //NOT演算子
884 break;
885
886 //比較演算子
887 case CALC_PE: //values[sp-2] <= values[sp-1]
888 case CALC_QE: //values[sp-2] >= values[sp-1]
889 case CALC_P: //values[sp-2] < values[sp-1]
890 case CALC_Q: //values[sp-2] > values[sp-1]
891 case CALC_NOTEQUAL: //values[sp-2] <> values[sp-1]
892 case CALC_EQUAL: //values[sp-2] = values[sp-1]
893 sp--;
894 type_stack[sp-1]=DEF_LONG;
895 break;
896
897 //ビットシフト
898 case CALC_SHL: //values[sp-2] << values[sp-1]
899 case CALC_SHR: //values[sp-2] >> values[sp-1]
900 sp--;
901 break;
902
903 //算術演算
904 case CALC_ADDITION:
905 case CALC_SUBTRACTION:
906 case CALC_PRODUCT:
907 sp--;
908 type_stack[sp-1]=NeutralizationType(type_stack[sp-1],index_stack[sp-1],type_stack[sp],index_stack[sp]);
909 break;
910 case CALC_MOD:
911 //values[sp-2]%=values[sp-1]
912 //剰余演算
913 sp--;
914 type_stack[sp-1]=NeutralizationType(type_stack[sp-1],index_stack[sp-1],type_stack[sp],index_stack[sp]);
915 break;
916 case CALC_QUOTIENT:
917 //values[sp-2]/=values[sp-1];
918 //除算
919 sp--;
920 type_stack[sp-1]=NeutralizationType(type_stack[sp-1],index_stack[sp-1],type_stack[sp],index_stack[sp]);
921 break;
922 case CALC_INTQUOTIENT:
923 //values[sp-2]/=values[sp-1]
924 //整数除算
925 sp--;
926 type_stack[sp-1]=NeutralizationType(type_stack[sp-1],index_stack[sp-1],type_stack[sp],index_stack[sp]);
927 break;
928 case CALC_MINUSMARK:
929 //values[sp-1]=-values[sp-1]
930 //符号反転
931 break;
932 case CALC_POWER:
933 //べき乗演算(浮動小数点演算のみ)
934 sp--;
935 //未完成
936 break;
937 case CALC_AS:
938 //キャスト
939 type_stack[sp-2]=type_stack[sp-1]&(~FLAG_CAST);
940 index_stack[sp-2]=index_stack[sp-1];
941
942 sp--;
943 break;
944
945 case CALC_BYVAL:
946 //ポインタ型→参照型
947 if( PTR_LEVEL( type_stack[sp-1] ) <= 0 ){
948 //ポインタ型ではないとき
949 SetError( 3, NULL, cp );
950 goto error;
951 }
952
953 type_stack[sp-1] = PTR_LEVEL_DOWN( type_stack[sp-1] );
954 break;
955 }
956 }
957
958 if(bError) goto error;
959
960 if(sp!=1){
961 SetError(1,NULL,cp);
962 goto error;
963 }
964
965 if( *pIsLiteralCalculation ){
966 //右辺値が数値の定数式の場合
967 int base_type = 0;
968 if( !baseType.IsNull() ) base_type = baseType.GetBasicType();
969 Type tempType;
970 StaticCalculation(true, expression,base_type,&i64data,tempType);
971
972 type_stack[0]=tempType.GetBasicType();
973 index_stack[0]=tempType.GetIndex();
974 }
975 else{
976 //右辺値が数値の定数式ではないとき
977 if(IS_LITERAL(index_stack[0])) index_stack[0]=-1;
978 }
979
980 resultType.SetType( type_stack[0], index_stack[0] );
981
982 bool isSuccessful = true;
983 goto finish;
984
985
986 //////////////////
987 // エラー処理
988 //////////////////
989
990error:
991 isSuccessful = false;
992 goto finish;
993
994
995finish:
996 for(i=0;i<pnum;i++){
997 if(values[i]) HeapDefaultFree(values[i]);
998 }
999 return isSuccessful;
1000}
Note: See TracBrowser for help on using the repository browser.