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

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

依存関係を整理中

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