source: dev/trunk/abdev/BasicCompiler32/NumOpe.cpp@ 415

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

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

File size: 31.2 KB
RevLine 
[206]1#include "stdafx.h"
2
[183]3#include <jenga/include/smoothie/Smoothie.h>
4
5#include <Compiler.h>
6
[3]7#include "../BasicCompiler_Common/common.h"
8#include "Opcode.h"
9
10void PushReturnValue(int type){
11 //関数の戻り値をスタックへプッシュする
12 //※この処理内では、esi、ediは使用不可
13
[64]14 if(type==DEF_OBJECT || type==DEF_STRUCT){
[3]15 //push eax
[225]16 compiler.codeGenerator.op_push(REG_EAX);
[3]17 }
18 else if(type==DEF_DOUBLE){
19 //sub esp,8
[225]20 compiler.codeGenerator.op_sub_esp(8);
[3]21
22 //fstp qword ptr[esp]
[225]23 compiler.codeGenerator.op_fstp_basereg( DEF_DOUBLE, REG_ESP );
[3]24 }
25 else if(type==DEF_SINGLE){
26 //sub esp,4
[225]27 compiler.codeGenerator.op_sub_esp(4);
[3]28
29 //fstp dword ptr[esp]
[225]30 compiler.codeGenerator.op_fstp_basereg( DEF_SINGLE, REG_ESP );
[3]31 }
32 else if(type==DEF_INT64||type==DEF_QWORD){
33 //push edx
[225]34 compiler.codeGenerator.op_push(REG_EDX);
[3]35
36 //push eax
[225]37 compiler.codeGenerator.op_push(REG_EAX);
[3]38 }
39 else if(type==DEF_LONG){
40 //push eax
[225]41 compiler.codeGenerator.op_push(REG_EAX);
[3]42 }
[183]43 else if(type==DEF_INTEGER || (Smoothie::IsUnicode()&&type==DEF_CHAR)){
[3]44 //movsx ebx,ax
[225]45 compiler.codeGenerator.op_movsx_R32R16( REG_EBX, REG_EAX );
[3]46
47 //push ebx
[225]48 compiler.codeGenerator.op_push(REG_EBX);
[3]49 }
[183]50 else if(type==DEF_SBYTE || (Smoothie::IsUnicode()==false&&type==DEF_CHAR)){
[3]51 //movsx ebx,al
[225]52 compiler.codeGenerator.op_movsx_R32R8( REG_EBX, REG_EAX );
[3]53
54 //push ebx
[225]55 compiler.codeGenerator.op_push(REG_EBX);
[3]56 }
[36]57 else if(type==DEF_DWORD||type==DEF_WORD||type==DEF_BYTE||type==DEF_BOOLEAN||
[3]58 IsPtrType(type)){
59 //push eax
[225]60 compiler.codeGenerator.op_push(REG_EAX);
[3]61 }
[64]62 else{
63 SetError();
[3]64 }
65}
66
[76]67void NewStringObject( const char *str ){
[3]68 ///////////////////////////////////////////////////////
69 // lpszTextを元にStringオブジェクトを生成し、
[64]70 // オブジェクトポインタをregに格納する
[3]71 ///////////////////////////////////////////////////////
72
[76]73 char *parameter = (char *)malloc( lstrlen( str ) + 32 );
[319]74 sprintf( parameter, "%s%c%c*Char", str, 1, ESC_AS );
[64]75
[265]76 Operator_New( *compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr(), "", parameter, Type( DEF_OBJECT, *compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr() ) );
[3]77
[64]78 free( parameter );
[3]79}
80
[97]81void ExtendRegToBigType( int reg, int bigBasicType, int baseBasicType ){
82 if( reg != REG_EAX ){
83 SetError();
84 }
85 switch( Type::GetBasicSize( bigBasicType ) ){
86 case sizeof(_int64):
87 ExtendTypeTo64(baseBasicType);
88 break;
89 case sizeof(long):
90 ExtendTypeTo32(baseBasicType,reg);
91 break;
92 case sizeof(short):
93 ExtendTypeTo16(baseBasicType,reg);
94 break;
95 }
96}
[3]97
[97]98
99
100bool VarToReg( RELATIVE_VAR &relativeVar, const Type &baseType, Type &resultType ){
101 const int useReg = REG_EAX;
102
103 //大きな型への暗黙の変換
104 int bigType = AutoBigCast(baseType.GetBasicType(),resultType.GetBasicType());
105
106 if(resultType.GetBasicType()&FLAG_PTR){
107 //配列ポインタ
108 resultType.SetBasicType( GetPtrType(resultType.GetBasicType()^FLAG_PTR) );
109
110 SetVarPtrToReg(useReg, &relativeVar);
111 }
112 else if( resultType.IsStruct() ){
113 //構造体ポインタをeaxへ格納(構造体は値型)
114 SetVarPtrToReg(useReg, &relativeVar);
115 }
116 else if( resultType.IsReal() ){
117 // 実数
118 SetReg_RealVariable( resultType.GetBasicType(), &relativeVar );
119 }
120 else if( resultType.IsWhole() || resultType.IsObject()){
121 //整数型
[290]122 SetReg_WholeVariable(resultType,&relativeVar,useReg);
[97]123 }
124 else if( resultType.IsStruct() ){
125 //構造体ポインタをUseRegへ格納(構造体は値型)
126 SetVarPtrToReg(useReg,&relativeVar);
127 }
128 else{
129 return false;
130 }
131
132 if( resultType.GetBasicType() != bigType ){
133 // 大きな型へ変換された場合
134 // ※レジスタの値をキャストする
135 ExtendRegToBigType( useReg, bigType, resultType.GetBasicType() );
136
137 resultType.SetBasicType( bigType );
138 }
139
140 return true;
141}
[415]142bool TermMemberOpe( const Type &leftType, const Type &baseType, Type &resultType, const char *termFull, const char *termLeft, const char *member, bool &isVariable, RELATIVE_VAR &relativeVar )
[290]143{
144 const CClass &objClass = leftType.GetClass();
145
[97]146 const int useReg = REG_EAX;
147
[334]148
149 ////////////////////////////////
150 // インデクサ(getアクセサ)
151 ////////////////////////////////
152 char VarName[VN_SIZE],ArrayElements[VN_SIZE];
153 GetArrayElement(member,VarName,ArrayElements);
154 if(ArrayElements[0]){
155 Type classType;
[398]156 if( VarName[0] == '\0' )
157 {
158 classType = leftType;
[403]159
160 if( classType.IsObject() )
161 {
162 // 既にuseRegにオブジェクトポインタが格納されており、それに対するインデクサを呼び出す場合
163 // ※「プロパティ値として返ってきたオブジェクトインスタンスのインデクサを呼び出す」場合にここにくる
164
165 //オブジェクトポインタをスタックに入れておく
166 //push useReg
167 compiler.codeGenerator.op_push( useReg );
168 }
[398]169 }
170 else
171 {
172 GetMemberType( leftType, VarName, classType, 0, false );
[334]173
[403]174 if( classType.IsObject() )
175 {
176 // クラス型のメンバに対するインデクサを呼び出す場合
[334]177
[403]178 //オブジェクトポインタをecxにコピー
179 compiler.codeGenerator.op_mov_RR( REG_ECX, useReg );
180
[415]181 RELATIVE_VAR tempRelativeVar;
182 tempRelativeVar.dwKind=VAR_DIRECTMEM;
[403]183
[398]184 if( !_member_offset(
185 true, //エラー表示あり
186 false, //読み込み専用
187 leftType,
[415]188 VarName,&tempRelativeVar,classType,0)){
[398]189 return false;
190 }
[334]191
[398]192 // オブジェクトメンバのポインタをeaxにコピー
[415]193 if( !VarToReg( tempRelativeVar, baseType, resultType ) ){
[398]194 SetError(11,termFull,cp);
195 }
[334]196
197
[398]198 //オブジェクトポインタをスタックに入れておく
199 //push eax
200 compiler.codeGenerator.op_push( REG_EAX );
201 }
[403]202 }
[334]203
[403]204 if( classType.IsObject() )
205 {
[334]206 char objectFullName[VN_SIZE], dummyArrayElements[VN_SIZE];
207 GetArrayElement(termFull,objectFullName,dummyArrayElements);
208
209 CallIndexerGetterProc(/*UseReg,*/classType,objectFullName, ArrayElements,resultType, PROCFLAG_NEW );
210
211 compiler.codeGenerator.op_pop();
212
213 return true;
214 }
215 }
216
217
218 ///////////////////////////////////////////////////////////////////
219 // メンバを検索
220 ///////////////////////////////////////////////////////////////////
[290]221 if( GetMemberType( leftType, member, resultType, 0, false ) ){
[97]222 // メンバが見つかったとき
223
224 //オブジェクトポインタをecxにコピー
[225]225 compiler.codeGenerator.op_mov_RR( REG_ECX, useReg );
[97]226
227 relativeVar.dwKind=VAR_DIRECTMEM;
228
229 if( !_member_offset(
230 true, //エラー表示あり
231 false, //読み込み専用
[290]232 leftType,
[97]233 member,&relativeVar,resultType,0)){
234 return false;
235 }
236
[415]237 // 変数として扱う
238 isVariable = true;
[97]239
240 return true;
241 }
242
243
244 ///////////////////////////////////////////////////////////////////
245 // 動的メソッドを検索
246 ///////////////////////////////////////////////////////////////////
[206]247 vector<const UserProc *> userProcs;
[97]248
249 char methodName[VN_SIZE], lpPtrOffset[VN_SIZE], parameter[VN_SIZE], dummy[1];
[206]250 ReferenceKind refType;
[403]251 bool isParameterInBracket = false;
[97]252 lstrcpy( methodName, member );
[403]253 GetVarFormatString( methodName, parameter, lpPtrOffset, dummy, refType, &isParameterInBracket );
[97]254
[350]255 objClass.EnumDynamicMethodsOrInterfaceMethods( methodName, userProcs );
[97]256 if(userProcs.size()){
257 //オーバーロードを解決
[206]258 const UserProc *pUserProc = OverloadSolutionWithStrParam(termFull,userProcs,parameter,termLeft);
[97]259
[398]260 if( pUserProc )
261 {
[403]262 if(
263 pUserProc->Params().size() == 0 // 仮引数の個数は0
264 && parameter[0] // 実引数は1つ以上
265 && pUserProc->ReturnType().IsObject() // 戻り値がクラス型の場合
266 && isParameterInBracket ) // 実引数は[]で囲まれている
[398]267 {
[403]268 // プロパティ値として返ってきたオブジェクトインスタンスのインデクサを呼び出す
269
270 // まずはプロパティ値を取得
[415]271 bool dummyIsVariable;
272 RELATIVE_VAR dummyRelativeVar;
273 TermMemberOpe( leftType, baseType, resultType, termFull, termLeft, methodName, dummyIsVariable, dummyRelativeVar );
[97]274
[403]275 // 戻り値のオブジェクトインスタンスのインデクサを呼び出す
[398]276 char temporary[VN_SIZE], temp2[VN_SIZE];
277 sprintf( temporary, "[%s]", parameter );
278 sprintf( temp2, "%s.%s", termLeft, methodName );
279 Type classType = resultType;
[415]280 return TermMemberOpe( classType, baseType, resultType, termFull, temp2, temporary, isVariable, relativeVar );
[398]281 }
282
[97]283 resultType = pUserProc->ReturnType();
284
285 {
286 //オブジェクトポインタをスタックに入れておく
287 //push reg
[225]288 compiler.codeGenerator.op_push( useReg );
[97]289
[290]290 if( !Opcode_CallProc(parameter,pUserProc,PROCFLAG_NEW,termLeft) ){
[97]291
292 return false;
293 }
294
[225]295 compiler.codeGenerator.op_pop();
[97]296
297 /////////////////////
298 // 戻り値の処理
299 /////////////////////
300
301 //大きな型への暗黙の変換
302 int bigType = AutoBigCast(baseType.GetBasicType(), resultType.GetBasicType() );
303
304 if( resultType.GetBasicType() != bigType ){
305 // 大きな型へ変換された場合
306 // ※レジスタの値をキャストする
307 ExtendRegToBigType( REG_EAX, bigType, resultType.GetBasicType() );
308
309 resultType.SetBasicType( bigType );
310 }
311
312 //SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg);
[290]313
[299]314 // 型パラメータを解決
315 ResolveFormalGenericTypeParameter( resultType, leftType, pUserProc );
[97]316 }
317
318 return true;
319 }
320 }
321
[370]322 SetError();
323
[97]324 return false;
325}
[415]326bool _TermOpe( const char *term, const Type &baseType, Type &resultType, bool &isLiteral, BOOL *pbUseHeap, bool *pIsClassName, bool isProcedureCallOnly, bool &isVariable, RELATIVE_VAR &relativeVar, bool isWriteAccess )
327{
[97]328 char parameter[VN_SIZE];
329
330 // Withを解決
331 char termFull[VN_SIZE];
332 if(term[0]=='.'){
333 GetWithName(termFull);
334 lstrcat(termFull,term);
335 }
336 else lstrcpy(termFull,term);
337
338 char termLeft[VN_SIZE];
339 lstrcpy(termLeft,termFull);
340
341 // パース
342 char member[VN_SIZE];
[206]343 ReferenceKind refType;
344 if( SplitMemberName( termFull, termLeft, member, refType ) ){
[97]345 ///////////////////////////////////////////////////////////////////
346 // オブジェクトとメンバに分解できるとき
347 // termLeft.member
348 ///////////////////////////////////////////////////////////////////
349
350 isLiteral = false;
351
352 // オブジェクト側の型を取得
353 bool isClassName = false;
354 Type leftType;
[331]355 if( GetTermType( termLeft, Type(), leftType, isLiteral, &isClassName ) ){
[265]356 if( isClassName == false && compiler.GetObjectModule().meta.GetBlittableTypes().IsExist( leftType ) ){
[128]357 // 左側のオブジェクト部分がBlittable型のとき
358
359 char temporary[VN_SIZE];
360 lstrcpy( temporary, termLeft );
361 sprintf( termLeft, "%s(%s)",
[265]362 compiler.GetObjectModule().meta.GetBlittableTypes().Find( leftType ).GetCreateStaticMethodFullName().c_str(),
[128]363 temporary );
364 }
365 }
366
[415]367 if( !TermOpe( termLeft, baseType, leftType, isLiteral, pbUseHeap, &isClassName ) ){
[103]368 goto globalArea;
[97]369 }
370
371 if( isClassName ){
372 // 静的メンバ/メソッドの場合
373 goto globalArea;
374 }
375
376 if( !leftType.HasMember() ){
377 // メンバを持たない型の場合
[370]378 if( isProcedureCallOnly )
379 {
380 SetError(1,NULL,cp);
381 }
[97]382 return false;
383 }
384
[415]385 return TermMemberOpe( leftType, baseType, resultType, termFull, termLeft, member, isVariable, relativeVar );
[97]386 }
[106]387globalArea:
[97]388
389
390 //////////////////////////////////////////////
391 // クラス名かどうかをチェック(静的メンバ用)
392 //////////////////////////////////////////////
393
394 if( pIsClassName ){
[265]395 if( compiler.GetObjectModule().meta.GetClasses().Find( termFull ) ){
[97]396 *pIsClassName = true;
397 return true;
398 }
399 }
400
401
402 /////////////////////////////////////////////////////////////////
403 // グローバル属性エリア
404 /////////////////////////////////////////////////////////////////
405
406 const int useReg = REG_EAX;
407
408
[122]409 if(lstrcmpi(termFull,"This")==0 && isProcedureCallOnly == false ){
[412]410 if( compiler.pCompilingClass == NULL )
411 {
412 SetError(142,NULL,cp);
413 return false;
414 }
415
[97]416 //Thisオブジェクト
[206]417 resultType.SetType( DEF_OBJECT, compiler.pCompilingClass );
[97]418
419 SetThisPtrToReg( useReg );
420
421 isLiteral = false;
422
423 return true;
424 }
425
426
427 //////////////////////////////////////
428 // 関数(DLL、ユーザー定義、組み込み)
429 //////////////////////////////////////
430 char procName[VN_SIZE];
431 char temporary[8192];
432
433 int i2=GetCallProcName(termFull,procName);
434 if(termFull[i2]=='('){
435 int i4=GetStringInPare_RemovePare(parameter,termFull+i2+1);
436
437 void *pInfo;
438 int idProc=GetProc(procName,(void **)&pInfo);
439
[327]440 if(idProc)
441 {
442 if(termFull[i2+1+i4+1]!='\0')
443 {
444 //閉じカッコ")"に続く文字がNULLでないとき
[97]445 SetError(42,NULL,cp);
446 }
447
448
449 {
450 ////////////////
451 // 呼び出し
452 ////////////////
453
[331]454 CallProc(idProc,pInfo,procName,parameter, baseType,resultType);
[97]455
456
457 /////////////////////
458 // 戻り値の処理
459 /////////////////////
460
461 //大きな型への暗黙の変換
462 int bigType = AutoBigCast(baseType.GetBasicType(), resultType.GetBasicType() );
463
464 /*
465 ※後でNumOpe内でプッシュする
466 //スタックへプッシュ
467 PushReturnValue( resultType.GetBasicType() );
468 */
469
470 if( resultType.GetBasicType() != bigType ){
471 // 大きな型へ変換された場合
472 // ※レジスタの値をキャストする
473 ExtendRegToBigType( useReg, bigType, resultType.GetBasicType() );
474
475 resultType.SetBasicType( bigType );
476 }
477
478 //SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg);
479 }
480
481
482 if(resultType.IsStruct()){
483 //構造体が戻ったときはヒープ領域にインスタンスが格納されている
484 //※後にfreeする必要あり
485 // TODO: 解放はGCに任せる
486 *pbUseHeap = 1;
487 }
488
489 isLiteral = false;
490
491 return true;
492 }
[208]493
[265]494 ConstMacro *pConstMacro = compiler.GetObjectModule().meta.GetGlobalConstMacros().Find( procName );
[206]495 if( pConstMacro )
496 {
497 if( pConstMacro->GetCalcBuffer( parameter, temporary ) )
498 {
499 /////////////////////////
500 // マクロ関数
501 /////////////////////////
[97]502
[206]503 //閉じカッコ")"に続く文字がNULLでないときはエラーにする
504 if(termFull[i2+1+i4+1]!='\0') SetError(42,NULL,cp);
[97]505
[206]506 //マクロ関数の場合
507 NumOpe(useReg, temporary,Type(),resultType);
[97]508
[206]509 if(!IS_LITERAL(resultType.GetIndex())){
510 //リテラル値ではなかったとき
511 isLiteral = false;
512 }
513
514 return true;
[97]515 }
516 }
517 }
[122]518 else if( isProcedureCallOnly ){
519 // 関数呼び出し以外は受け付けない
520 return false;
521 }
[97]522
523
524 ////////////////////////////////
525 // インデクサ(getアクセサ)
526 ////////////////////////////////
527
528 char VarName[VN_SIZE],ArrayElements[VN_SIZE];
529 GetArrayElement(termFull,VarName,ArrayElements);
530 if(ArrayElements[0]){
[293]531 Type classType;
532 GetVarType(VarName,classType,false);
533 if( classType.IsObject() )
[292]534 {
[293]535 CallIndexerGetterProc(/*UseReg,*/classType,VarName, ArrayElements,resultType);
[97]536
537 isLiteral = false;
538
539 return true;
540 }
541 }
542
543
544 ////////////////////////////////
545 // 変数
546 ////////////////////////////////
547
548 if(GetVarOffset(
549 false, //エラー表示なし
[415]550 isWriteAccess,
[97]551 termFull,
552 &relativeVar,resultType)){
553 //////////
554 // 変数
555 //////////
556
[415]557 // 変数として扱う
558 isVariable = true;
[97]559
560 isLiteral = false;
561
562 return true;
563 }
564
565
566 /////////////////////////////////
567 // プロパティ用のメソッド
568 /////////////////////////////////
569
570 //配列要素を排除
571 GetArrayElement(termFull,VarName,ArrayElements);
572
573 if(GetSubHash(VarName,0)){
574
575 {
576 CallPropertyMethod(termFull,NULL,resultType);
577
578 //大きな型への暗黙の変換
579 int bigType = AutoBigCast(baseType.GetBasicType(), resultType.GetBasicType() );
580
581 if( resultType.GetBasicType() != bigType ){
582 // 大きな型へ変換された場合
583 // ※レジスタの値をキャストする
584 ExtendRegToBigType( REG_EAX, bigType, resultType.GetBasicType() );
585
586 resultType.SetBasicType( bigType );
587 }
588
589 //SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg);
590 }
591
592
593 if(resultType.IsStruct()){
594 //構造体が戻ったときはヒープ領域にインスタンスが格納されている
595 //※後にfreeする必要あり
596 // TODO: 解放はGCに任せる
597 *pbUseHeap = 1;
598 }
599
600 isLiteral = false;
601
602 return true;
603 }
604
[370]605 if( isProcedureCallOnly )
606 {
607 SetError(3, termLeft, cp );
608 }
[97]609
610 return false;
611}
612
[415]613bool TermOpe( const char *term, const Type &baseType, Type &resultType, bool &isLiteral, BOOL *pbUseHeap, bool *pIsClassName, bool isProcedureCallOnly, bool isWriteAccess )
614{
615 RELATIVE_VAR relativeVar;
616 bool isVariable = false;
617 bool result = _TermOpe( term, baseType, resultType, isLiteral, pbUseHeap, pIsClassName, isProcedureCallOnly, isVariable, relativeVar, isWriteAccess );
[97]618
[415]619 if( isVariable )
620 {
621 // 変数の場合はeaxに変数ポインタを格納する
622 if( !VarToReg( relativeVar, baseType, resultType ) ){
623 SetError(11,term,cp);
624 }
625 }
626
627 return result;
628}
629bool TermOpeOnlyVariable( const char *term, Type &resultType, RELATIVE_VAR &relativeVar, bool isWriteAccess )
630{
631 bool isLiteral, isVariable = false;
632 bool result = _TermOpe( term, Type(), resultType, isLiteral, NULL, NULL, false, isVariable, relativeVar, isWriteAccess );
633
634 if( !isVariable )
635 {
636 SetError();
637 }
638
639 return result;
640}
641
642
[97]643bool NumOpe( int reg,
644 const char *expression,
645 const Type &baseType,
646 Type &resultType,
647 BOOL *pbUseHeap ){
648
649 if( !NumOpe( expression, baseType, resultType, pbUseHeap ) ){
650 return false;
651 }
652
653 if( reg != REG_EAX ){
654 // TODO: 未実装
655 SetError();
656 }
657
658 if( resultType.IsReal() ){
659 //fld ptr[esp]
[225]660 compiler.codeGenerator.op_fld_ptr_esp( resultType.GetBasicType() );
[97]661
662 //add esp,size
[225]663 compiler.codeGenerator.op_add_esp( resultType.GetBasicSize() );
[97]664 }
665 else{
666 //pop eax
[225]667 compiler.codeGenerator.op_pop(REG_EAX);
[97]668
669 if( resultType.Is64() ){
670 //pop edx
[225]671 compiler.codeGenerator.op_pop(REG_EDX);
[97]672 }
673 }
674 return true;
675}
[76]676bool NumOpe( const char *expression,
677 const Type &baseType,
678 Type &resultType,
[254]679 BOOL *pbUseHeap )
680{
[97]681 int i,i2,i3;
682 char temporary[1024],temp2[1024];
[3]683
[76]684 if(expression[0]=='\0'){
[3]685 SetError(1,NULL,cp);
[76]686 return false;
[3]687 }
688
[93]689 if( !baseType.IsNull() && expression[0] == '[' ){
690 // リテラル配列の場合
[3]691
[355]692 int dataTableOffset;
693 if( !compiler.GetObjectModule().dataTable.MakeLiteralArrayBuffer( expression, baseType, dataTableOffset ) )
694 {
[93]695 return false;
696 }
697
698 //mov eax,i2
[355]699 compiler.codeGenerator.op_mov_RV(REG_EAX,dataTableOffset, Schedule::DataTable );
[93]700
701 resultType = baseType;
702
703 //push eax
[225]704 compiler.codeGenerator.op_push( REG_EAX );
[93]705
706 return true;
707 }
708
[254]709 bool isLiteralCalculation;
[355]710 if( NumOpe_GetType( expression, baseType, resultType, &isLiteralCalculation ) )
[254]711 {
[355]712 if( isLiteralCalculation )
713 {
714 //右辺値が数値の定数式の場合
715 _int64 i64data;
716 StaticCalculation(true, expression,baseType.GetBasicType(),&i64data,resultType);
[93]717
[355]718 if( resultType.GetBasicSize() == sizeof(_int64) ){
719 //64ビット(符号有り整数/実数)
[254]720
[355]721 //push HILONG(i64data)
722 compiler.codeGenerator.op_push_V((long)*(long *)(((char *)(&i64data))+4));
[254]723
[355]724 //push LOLONG(i64data)
725 compiler.codeGenerator.op_push_V(*(long *)(&i64data));
726 }
727 else if( resultType.IsSingle() ){
728 //single実数
[254]729
[355]730 double dbl;
731 memcpy(&dbl,&i64data,sizeof(_int64));
[254]732
[355]733 float flt;
734 flt=(float)dbl;
735 long l;
736 memcpy(&l,&flt,sizeof(long));
[254]737
[355]738 //push flt
739 compiler.codeGenerator.op_push_V(l);
740 }
741 else{
742 //整数(符号有り/無し)
[254]743
[355]744 long l = (long)i64data;
[254]745
[355]746 if(resultType.GetBasicSize()==sizeof(char)) l = l & 0x000000FF;
747 if(resultType.GetBasicSize()==sizeof(short)) l = l & 0x0000FFFF;
[254]748
[355]749 //push term
750 compiler.codeGenerator.op_push_V(l);
751 }
752 return true;
[254]753 }
754 }
755
[355]756 if(expression[0]==1 )
757 {
758 if( expression[1]==ESC_NEW ){
759 //New演算子(オブジェクト生成)
[254]760
[355]761 if( !Operator_New( expression+2, baseType, resultType ) ){
762 return false;
763 }
764
765 return true;
[254]766 }
[355]767 else if( expression[1] == ESC_SYSTEM_STATIC_NEW )
768 {
769 // 静的領域にオブジェクトを作る
[254]770
[355]771 // 静的領域にオブジェクトを生成
772 int dataTableOffset;
773 if( !compiler.GetObjectModule().dataTable.MakeConstObjectToProcessStaticBuffer( expression + 2, resultType, dataTableOffset ) )
774 {
775 return false;
776 }
777
778 // push value
779 compiler.codeGenerator.op_push_V( dataTableOffset, Schedule::DataTable );
780
781 return true;
782 }
[254]783 }
784
785
[3]786 /////////////////////////////////
787 // 式要素を逆ポーランド式で取得
788 /////////////////////////////////
789
790 char *values[255];
791 long calc[255];
792 long stack[255];
793 int pnum;
[76]794 if(!GetNumOpeElements(expression,&pnum,values,calc,stack)){
[3]795 for(i=0;i<pnum;i++){
796 if(values[i]) HeapDefaultFree(values[i]);
797 }
[76]798 return false;
[3]799 }
800
801
802 BOOL bError;
803 bError=0;
804
805 //リテラル値のみの計算かどうかを判別するためのフラグ
806 BOOL bLiteralCalculation=1;
807
808 double dbl;
809 int sp;
[76]810 int type_stack[255];
[79]811 bool isNothing_stack[255];
[3]812 LONG_PTR index_stack[255];
813 BOOL bUseHeap[255];
814 _int64 i64data;
815 for(i=0,sp=0;i<pnum;i++){
816 int idCalc;
817 idCalc=calc[i]%100;
818
819 if(idCalc){
[76]820 if(type_stack[sp-2]==DEF_OBJECT){
[79]821 if( idCalc == CALC_AS
822 && type_stack[sp-1] == ( DEF_OBJECT | FLAG_CAST )
823 && index_stack[sp-1] == index_stack[sp-2]
824 || isNothing_stack[sp-2] ){
825 // 同一の型、またはNothingに対するAsはAs演算子を呼び出さない
[3]826 }
[94]827 else if( idCalc == CALC_AS
828 && type_stack[sp-1] == ( DEF_OBJECT | FLAG_CAST )
829 && ( ((CClass *)index_stack[sp-1])->IsEqualsOrSubClass( (CClass *)index_stack[sp-2] ) || ((CClass *)index_stack[sp-2])->IsEqualsOrSubClass( (CClass *)index_stack[sp-1] )
830 )){
831 // ダウンキャストを許可する
832 }
[79]833 else{
834 //オーバーロードされたオペレータを呼び出す
835 i2=CallOperatorProc(idCalc,baseType,type_stack,index_stack,bUseHeap,sp);
836 if(i2==0){
837 if(idCalc==CALC_EQUAL) lstrcpy(temp2,"==");
838 else GetCalcName(idCalc,temp2);
839 sprintf(temporary,"Operator %s",temp2);
840 SetError(27,temporary,cp);
841 goto error;
842 }
843 else if(i2==-1) goto error;
[3]844
[79]845 continue;
846 }
[3]847 }
848
[76]849 if(!CheckCalcType(idCalc,type_stack,sp)) goto error;
[3]850 }
851
852 switch(idCalc){
853 //数値
854 case 0:
855 index_stack[sp]=-1;
[79]856 isNothing_stack[sp] = false;
[3]857 bUseHeap[sp]=0;
858
859 char *term;
860 term=values[i];
861
[97]862 if( calc[i+1]%100 == CALC_AS ){
863 // As演算子の右辺値
864 //型名
[299]865 if( compiler.StringToType( term, resultType ) ){
[97]866 resultType.SetBasicType( resultType.GetBasicType() | FLAG_CAST );
867 }
868 else{
869 SetError(3, term, cp );
870 goto error;
871 }
872
873 type_stack[sp] = resultType.GetBasicType();
874 index_stack[sp] = resultType.GetIndex();
875 sp++;
876
877 break;
878 }
879
[319]880 if( (term[0]=='e'||term[0]=='E')
881 && (term[1]=='x'||term[1]=='X')
882 && term[2]=='\"'
883 || term[0] == '\"' )
884 {
885 bool isEx = true;
886 if( term[0] == '\"' )
887 {
888 isEx = false;
889 }
[3]890
[319]891 if( isEx )
892 {
893 // 拡張版リテラル文字列(エスケープシーケンス可能)
894 if(!RemoveStringQuotes(term+2)){
895 SetError(43,NULL,cp);
896 goto error;
897 }
898 i3=FormatString_EscapeSequence(term+2);
899 term+=2;
900 }
901 else
902 {
903 // 通常文字列
904 if(!RemoveStringQuotes(term)){
905 SetError(43,NULL,cp);
906 goto error;
907 }
908 i3=lstrlen(term);
909 }
[355]910
911 if( !baseType.IsPointer() )
912 {
913 //要求タイプがオブジェクト、または未定のとき
914
915 //String型オブジェクトを生成
916 i2 = compiler.GetObjectModule().dataTable.MakeConstStringObjectToProcessStaticBuffer( term );
917
918 // push value
919 compiler.codeGenerator.op_push_V( i2, Schedule::DataTable );
920
921 type_stack[sp]=DEF_OBJECT;
922 index_stack[sp]=(LONG_PTR)compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr();
923 bLiteralCalculation=0;
924
925 sp++;
926 break;
927 }
[319]928StrLiteral:
[76]929 type_stack[sp]=typeOfPtrChar;
[3]930 bLiteralCalculation=0;
931
[265]932 i2=compiler.GetObjectModule().dataTable.AddString(term,i3);
[3]933
934 //push DataSize
[237]935 compiler.codeGenerator.op_push_V( i2, Schedule::DataTable );
[3]936 }
937 else if(IsVariableTopChar(term[0])||
938 term[0]=='*'||
939 (term[0]=='.'&&IsVariableTopChar(term[1]))){
940 //////////////////
941 // 何らかの識別子
942
[97]943 bool isLiteral;
944 if( TermOpe( term, baseType, resultType, isLiteral, &bUseHeap[sp] ) ){
945 if(resultType.IsNull()){
946 //戻り値が存在しないとき
947 for(i2=0;;i2++){
948 if(term[i2]=='('||term[i2]=='\0'){
949 term[i2]=0;
950 break;
[49]951 }
952 }
[97]953 SetError(38,term,cp);
[3]954
[97]955 goto error;
956 }
[3]957
[97]958 type_stack[sp] = resultType.GetBasicType();
959 index_stack[sp] = resultType.GetIndex();
[3]960
[97]961 if( !isLiteral ){
[3]962 bLiteralCalculation=0;
[97]963 }
[3]964
[97]965 if( resultType.GetBasicType() & FLAG_CAST ){
966 // 型名のみ
967 SetError();
968 }
969 else{
970 if( resultType.IsReal() ){
971 //sub esp,size
972 //fstp ptr[esp]
[225]973 compiler.codeGenerator.op_fstp_push( resultType );
[3]974 }
[97]975 else{
976 if( resultType.Is64() ){
977 //push edx
[225]978 compiler.codeGenerator.op_push( REG_EDX );
[97]979 }
980 else{
981 ExtendTypeTo32( resultType.GetBasicType(), REG_EAX );
982 }
[3]983
[97]984 //push eax
[225]985 compiler.codeGenerator.op_push( REG_EAX );
[3]986 }
987 }
988
[97]989 sp++;
990 break;
[3]991 }
992
993
[67]994 // Nothing
995 if( lstrcmp( term, "Nothing" ) == 0 ){
[79]996 isNothing_stack[sp] = true;
997
[76]998 type_stack[sp] = DEF_OBJECT;
999 if( baseType.IsObject() ){
1000 index_stack[sp] = baseType.GetIndex();
[67]1001 }
1002 else{
[265]1003 index_stack[sp] = (LONG_PTR)compiler.GetObjectModule().meta.GetClasses().GetObjectClassPtr();
[67]1004 }
[3]1005
[67]1006 bLiteralCalculation = 0;
1007
1008 //push 0
[225]1009 compiler.codeGenerator.op_push_V( 0 );
[67]1010
1011 sp++;
1012 break;
1013 }
1014
[3]1015
1016 //////////////
1017 // 定数の場合
1018 //////////////
1019
[265]1020 i3 = compiler.GetObjectModule().meta.GetGlobalConsts().GetBasicType(term);
[8]1021 if(i3){
[265]1022 if( compiler.GetObjectModule().meta.GetGlobalConsts().IsStringPtr( term ) ){
[103]1023 //リテラル文字列
1024
[319]1025 if( baseType.IsObject() || baseType.IsNull() )
1026 {
1027 //要求タイプがオブジェクト、または未定のとき
1028
1029 //String型オブジェクトを生成
1030 NewStringObject(term);
1031
1032 type_stack[sp]=DEF_OBJECT;
1033 index_stack[sp]=(LONG_PTR)compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr();
1034 bLiteralCalculation=0;
1035
1036 sp++;
1037 break;
1038 }
1039
[265]1040 double dbl = compiler.GetObjectModule().meta.GetGlobalConsts().GetDoubleData(term);
[103]1041 memcpy(&i64data,&dbl,sizeof(double));
1042
1043 //バイト数
1044 i3=lstrlen((char *)i64data);
1045
1046 memcpy(term,(char *)i64data,i3);
1047 term[i3]=0;
1048 goto StrLiteral;
1049 }
1050
[76]1051 type_stack[sp]=i3;
[3]1052 if(IsRealNumberType(i3)){
1053 //実数
[265]1054 double dbl = compiler.GetObjectModule().meta.GetGlobalConsts().GetDoubleData(term);
[3]1055 memcpy(&i64data,&dbl,sizeof(double));
1056 goto Literal;
1057 }
1058 else if(IsWholeNumberType(i3)){
1059 //整数
[265]1060 i64data = compiler.GetObjectModule().meta.GetGlobalConsts().GetWholeData(term);
[3]1061 goto Literal;
1062 }
1063 else{
1064 SetError(300,NULL,cp);
1065 goto error;
1066 }
1067 }
1068
1069
1070 //該当する識別子が見当たらないときはエラー扱いにする
1071 bError=1;
1072 SetError(3,term,cp);
[76]1073 type_stack[sp]=DEF_DOUBLE;
[3]1074 }
1075 else{
1076 //リテラル値
[76]1077 type_stack[sp]=GetLiteralValue(term,&i64data,baseType.GetBasicType());
[3]1078Literal:
[76]1079 if(type_stack[sp]==DEF_INT64||
1080 type_stack[sp]==DEF_QWORD||
1081 type_stack[sp]==DEF_DOUBLE){
[3]1082 //64ビット(符号有り整数/実数)
1083
1084 //push HILONG(dbl)
[225]1085 compiler.codeGenerator.op_push_V((long)*(long *)(((char *)(&i64data))+4));
[3]1086
1087 //push LOLONG(dbl)
[225]1088 compiler.codeGenerator.op_push_V(*(long *)(&i64data));
[3]1089 }
[76]1090 else if(type_stack[sp]==DEF_SINGLE){
[3]1091 //single実数
1092
1093 float flt;
1094 memcpy(&dbl,&i64data,sizeof(double));
1095 flt=(float)dbl;
1096 memcpy(&i3,&flt,sizeof(long));
1097
1098 //push term
[225]1099 compiler.codeGenerator.op_push_V(i3);
[3]1100 }
1101 else{
1102 //その他
1103
1104 //push term
[225]1105 compiler.codeGenerator.op_push_V((long)i64data);
[3]1106
1107 if((long)i64data==0) index_stack[sp]=LITERAL_NULL;
1108 }
1109
1110
1111 //リテラル値の種類
[76]1112 if(Is64Type(type_stack[sp])==0&&IsRealNumberType(type_stack[sp])==0){
[3]1113 //整数(符号有り/無し)
1114
1115 index_stack[sp]=GetLiteralIndex(i64data);
1116 }
1117 }
1118 sp++;
1119 break;
1120
1121 //論理演算子
1122 case CALC_XOR:
1123 //value[sp-2] xor= value[sp-1]
1124 //xor演算
[76]1125 if(!Calc_Xor(type_stack,index_stack,&sp)) goto error;
[3]1126 break;
1127 case CALC_OR:
1128 //value[sp-2] or= value[sp-1]
1129 //or演算
[76]1130 if(!Calc_Or(type_stack,index_stack,&sp)) goto error;
[3]1131 break;
1132 case CALC_AND:
1133 //value[sp-2] and= value[sp-1]
1134 //and演算
[76]1135 if(!Calc_And(type_stack,index_stack,&sp)) goto error;
[3]1136 break;
1137 case CALC_NOT:
1138 //value[sp-1]=Not value[sp-1]
1139 //NOT演算子
[76]1140 if(!Calc_Not(type_stack,sp)) goto error;
[3]1141 break;
1142
1143 //比較演算子
1144 case CALC_PE:
1145 //value[sp-2]<=value[sp-1]
[76]1146 if(!Calc_Relation_PE(type_stack,index_stack,&sp)) goto error;
[3]1147 break;
1148 case CALC_QE:
1149 //value[sp-2]>=value[sp-1]
[76]1150 if(!Calc_Relation_QE(type_stack,index_stack,&sp)) goto error;
[3]1151 break;
1152 case CALC_P:
1153 //value[sp-2]<value[sp-1]
[76]1154 if(!Calc_Relation_P(type_stack,index_stack,&sp)) goto error;
[3]1155 break;
1156 case CALC_Q:
1157 //value[sp-2]>value[sp-1]
[76]1158 if(!Calc_Relation_Q(type_stack,index_stack,&sp)) goto error;
[3]1159 break;
1160 case CALC_NOTEQUAL:
1161 //value[sp-2]<>value[sp-1]
[76]1162 if(!Calc_Relation_NotEqual(type_stack,&sp)) goto error;
[3]1163 break;
1164 case CALC_EQUAL:
1165 //value[sp-2]=value[sp-1]
[76]1166 if(!Calc_Relation_Equal(type_stack,&sp)) goto error;
[3]1167 break;
1168
1169 //ビットシフト
1170 case CALC_SHL:
1171 //value[sp-2]=value[sp-2]<<value[sp-1]
[76]1172 if(!Calc_SHL(type_stack,&sp)) goto error;
[3]1173 break;
1174 case CALC_SHR:
1175 //value[sp-2]=value[sp-2]>>value[sp-1]
[76]1176 if(!Calc_SHR(type_stack,&sp)) goto error;
[3]1177 break;
1178
1179 //算術演算
1180 case CALC_ADDITION:
1181 case CALC_SUBTRACTION:
1182 case CALC_PRODUCT:
[76]1183 if(!CalcTwoTerm_Arithmetic(idCalc,type_stack,index_stack,&sp)) goto error;
[3]1184 break;
1185
1186 case CALC_MOD:
1187 //value[sp-2]%=value[sp-1]
1188 //剰余演算
[76]1189 if(!Calc_Mod(type_stack,&sp)) goto error;
[3]1190 break;
1191 case CALC_QUOTIENT:
1192 //value[sp-2]/=value[sp-1];
1193 //除算
[76]1194 if(!Calc_Divide(type_stack,&sp,baseType.GetBasicType())) goto error;
[3]1195 break;
1196 case CALC_INTQUOTIENT:
1197 //value[sp-2]/=value[sp-1]
1198 //整数除算
[76]1199 if(!Calc_IntDivide(type_stack,index_stack,&sp)) goto error;
[3]1200 break;
1201 case CALC_MINUSMARK:
1202 //value[sp-1]=-value[sp-1]
1203 //符号反転
[76]1204 if(!Calc_MinusMark(type_stack,sp)) goto error;
[3]1205 index_stack[sp-1]=-1;
1206 break;
1207 case CALC_POWER:
1208 //べき乗演算(浮動小数点演算のみ)
[76]1209 if(!Calc_Power(type_stack,&sp)) goto error;
[3]1210 break;
1211 case CALC_AS:
1212 //キャスト
[76]1213 if(!Calc_Cast(type_stack,index_stack,&sp)) goto error;
[3]1214 break;
1215
[41]1216 case CALC_BYVAL:
1217 //ポインタ型→参照型
[76]1218 if( PTR_LEVEL( type_stack[sp-1] ) <= 0 ){
[41]1219 //ポインタ型ではないとき
1220 SetError( 3, NULL, cp );
1221 goto error;
1222 }
1223
[76]1224 type_stack[sp-1] = PTR_LEVEL_DOWN( type_stack[sp-1] );
[41]1225
1226 break;
1227
[3]1228 default:
1229 SetError(300,NULL,cp);
[41]1230 goto error;
[3]1231 }
1232 }
1233
1234 if(bError) goto error;
1235
1236 if(sp!=1){
1237 SetError(1,NULL,cp);
1238 goto error;
1239 }
1240
1241 if(bLiteralCalculation){
1242 //右辺値が数値の定数式の場合
[254]1243 SetError();
[3]1244 }
1245 else{
1246 //右辺値が数値の定数式ではないとき
1247 if(IS_LITERAL(index_stack[0])) index_stack[0]=-1;
1248 }
1249
1250 if(pbUseHeap) *pbUseHeap=bUseHeap[0];
1251
[76]1252 resultType.SetType( type_stack[0], index_stack[0] );
1253
1254 bool isSuccessful = true;
[3]1255 goto finish;
1256
1257
1258error:
[76]1259 isSuccessful = false;
[3]1260 goto finish;
1261
1262
1263finish:
1264
1265 for(i=0;i<pnum;i++){
1266 if(values[i]) HeapDefaultFree(values[i]);
1267 }
1268
[363]1269 // 強制終了を防ぐためのダミー(原因不明)
1270 if( lstrcmp( expression, "-1/t" ) == 0 )
1271 {
1272 }
1273
[76]1274 return isSuccessful;
[3]1275}
Note: See TracBrowser for help on using the repository browser.