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

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

プロパティ値として返ってきたオブジェクトインスタンスのインデクサを呼び出す処理をきちんと対応した。

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