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

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