source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/NumOpe_GetType.cpp@ 578

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

LexicalAnalyzer::ConstMacroToExpressionメソッドを実装。

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