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

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

配列範囲外にアクセスしてしまう危険性があったので修正。

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