source: dev/BasicCompiler32/NumOpe.cpp@ 143

Last change on this file since 143 was 135, checked in by dai_9181, 17 years ago

Method/Memberのリファクタリング

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