source: dev/BasicCompiler32/NumOpe.cpp@ 122

Last change on this file since 122 was 122, checked in by dai_9181, 18 years ago

(呼び出し単体コードも対応→)関数の戻り値オブジェクトのメンバ・メソッドを一時オブジェクトを介さずに参照できるようにした。

File size: 25.8 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.EnumMethod( 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 *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( !TermOpe( termLeft, baseType, leftType, isLiteral, pbUseHeap, &isClassName ) ){
258 goto globalArea;
259 }
260
261 if( isClassName ){
262 // 静的メンバ/メソッドの場合
263 goto globalArea;
264 }
265
266 if( !leftType.HasMember() ){
267 // メンバを持たない型の場合
268 return false;
269 }
270
271 return TermMemberOpe( leftType.GetClass(), baseType, resultType, termFull, termLeft, member );
272 }
273globalArea:
274
275
276 //////////////////////////////////////////////
277 // クラス名かどうかをチェック(静的メンバ用)
278 //////////////////////////////////////////////
279
280 if( pIsClassName ){
281 if( pobj_DBClass->Find( termFull ) ){
282 *pIsClassName = true;
283 return true;
284 }
285 }
286
287
288 /////////////////////////////////////////////////////////////////
289 // グローバル属性エリア
290 /////////////////////////////////////////////////////////////////
291
292 const int useReg = REG_EAX;
293
294
295 if(lstrcmpi(termFull,"This")==0 && isProcedureCallOnly == false ){
296 //Thisオブジェクト
297 resultType.SetType( DEF_OBJECT, pobj_CompilingClass );
298
299 SetThisPtrToReg( useReg );
300
301 isLiteral = false;
302
303 return true;
304 }
305
306
307 //////////////////////////////////////
308 // 関数(DLL、ユーザー定義、組み込み)
309 //////////////////////////////////////
310 char procName[VN_SIZE];
311 char temporary[8192];
312
313 int i2=GetCallProcName(termFull,procName);
314 if(termFull[i2]=='('){
315 int i4=GetStringInPare_RemovePare(parameter,termFull+i2+1);
316
317 void *pInfo;
318 int idProc=GetProc(procName,(void **)&pInfo);
319
320 if(idProc){
321 //閉じカッコ")"に続く文字がNULLでないとき
322 if(termFull[i2+1+i4+1]!='\0'){
323 SetError(42,NULL,cp);
324 }
325
326
327 {
328 ////////////////
329 // 呼び出し
330 ////////////////
331
332 CallProc(idProc,pInfo,procName,parameter,resultType);
333
334
335 /////////////////////
336 // 戻り値の処理
337 /////////////////////
338
339 //大きな型への暗黙の変換
340 int bigType = AutoBigCast(baseType.GetBasicType(), resultType.GetBasicType() );
341
342 /*
343 ※後でNumOpe内でプッシュする
344 //スタックへプッシュ
345 PushReturnValue( resultType.GetBasicType() );
346 */
347
348 if( resultType.GetBasicType() != bigType ){
349 // 大きな型へ変換された場合
350 // ※レジスタの値をキャストする
351 ExtendRegToBigType( useReg, bigType, resultType.GetBasicType() );
352
353 resultType.SetBasicType( bigType );
354 }
355
356 //SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg);
357 }
358
359
360 if(resultType.IsStruct()){
361 //構造体が戻ったときはヒープ領域にインスタンスが格納されている
362 //※後にfreeする必要あり
363 // TODO: 解放はGCに任せる
364 *pbUseHeap = 1;
365 }
366
367 isLiteral = false;
368
369 return true;
370 }
371 else if(GetConstCalcBuffer(procName,parameter,temporary)){
372 /////////////////////////
373 // マクロ関数
374 /////////////////////////
375
376 //閉じカッコ")"に続く文字がNULLでないときはエラーにする
377 if(termFull[i2+1+i4+1]!='\0') SetError(42,NULL,cp);
378
379 //マクロ関数の場合
380 NumOpe(useReg, temporary,Type(),resultType);
381
382 if(!IS_LITERAL(resultType.GetIndex())){
383 //リテラル値ではなかったとき
384 isLiteral = false;
385 }
386
387 return true;
388 }
389 }
390 else if( isProcedureCallOnly ){
391 // 関数呼び出し以外は受け付けない
392 return false;
393 }
394
395
396 ////////////////////////////////
397 // インデクサ(getアクセサ)
398 ////////////////////////////////
399
400 char VarName[VN_SIZE],ArrayElements[VN_SIZE];
401 GetArrayElement(termFull,VarName,ArrayElements);
402 if(ArrayElements[0]){
403 GetVarType(VarName,resultType,false);
404 if( resultType.IsObject() ){
405 CallIndexerGetterProc(/*UseReg,*/&resultType.GetClass(),VarName,ArrayElements,resultType);
406
407 isLiteral = false;
408
409 return true;
410 }
411 }
412
413
414 ////////////////////////////////
415 // 変数
416 ////////////////////////////////
417
418 RELATIVE_VAR relativeVar;
419 if(GetVarOffset(
420 false, //エラー表示なし
421 false, //読み込み専用
422 termFull,
423 &relativeVar,resultType)){
424 //////////
425 // 変数
426 //////////
427
428 if( !VarToReg( relativeVar, baseType, resultType ) ){
429 SetError(11,termFull,cp);
430 }
431
432 isLiteral = false;
433
434 return true;
435 }
436
437
438 /////////////////////////////////
439 // プロパティ用のメソッド
440 /////////////////////////////////
441
442 //配列要素を排除
443 GetArrayElement(termFull,VarName,ArrayElements);
444
445 if(GetSubHash(VarName,0)){
446
447 {
448 CallPropertyMethod(termFull,NULL,resultType);
449
450 //大きな型への暗黙の変換
451 int bigType = AutoBigCast(baseType.GetBasicType(), resultType.GetBasicType() );
452
453 if( resultType.GetBasicType() != bigType ){
454 // 大きな型へ変換された場合
455 // ※レジスタの値をキャストする
456 ExtendRegToBigType( REG_EAX, bigType, resultType.GetBasicType() );
457
458 resultType.SetBasicType( bigType );
459 }
460
461 //SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg);
462 }
463
464
465 if(resultType.IsStruct()){
466 //構造体が戻ったときはヒープ領域にインスタンスが格納されている
467 //※後にfreeする必要あり
468 // TODO: 解放はGCに任せる
469 *pbUseHeap = 1;
470 }
471
472 isLiteral = false;
473
474 return true;
475 }
476
477
478 return false;
479}
480
481
482bool NumOpe( int reg,
483 const char *expression,
484 const Type &baseType,
485 Type &resultType,
486 BOOL *pbUseHeap ){
487
488 if( !NumOpe( expression, baseType, resultType, pbUseHeap ) ){
489 return false;
490 }
491
492 if( reg != REG_EAX ){
493 // TODO: 未実装
494 SetError();
495 }
496
497 if( resultType.IsReal() ){
498 //fld ptr[esp]
499 op_fld_ptr_esp( resultType.GetBasicType() );
500
501 //add esp,size
502 op_add_esp( resultType.GetBasicSize() );
503 }
504 else{
505 //pop eax
506 op_pop(REG_EAX);
507
508 if( resultType.Is64() ){
509 //pop edx
510 op_pop(REG_EDX);
511 }
512 }
513 return true;
514}
515bool NumOpe( const char *expression,
516 const Type &baseType,
517 Type &resultType,
518 BOOL *pbUseHeap ){
519
520 int i,i2,i3;
521 char temporary[1024],temp2[1024];
522
523 if(expression[0]=='\0'){
524 SetError(1,NULL,cp);
525 return false;
526 }
527
528 if(expression[0]==1&& expression[1]==ESC_NEW ){
529 //New演算子(オブジェクト生成)
530
531 if( !Operator_New( expression+2, baseType, resultType ) ){
532 return false;
533 }
534
535 return true;
536 }
537
538 if( !baseType.IsNull() && expression[0] == '[' ){
539 // リテラル配列の場合
540
541 if( !baseType.IsPointer() ){
542 SetError(1,NULL,cp);
543 return false;
544 }
545 Type tempBaseType( baseType );
546 tempBaseType.PtrLevelDown();
547
548 char *buffer = (char *)malloc( lstrlen( expression ) + 1 );
549 lstrcpy( buffer, expression );
550 RemoveStringBracket( buffer );
551
552 void *binary = malloc( 1 );
553 int num = 0;
554
555 i = 0;
556 while( buffer[i] ){
557 i = GetOneParameter( buffer, i, temporary );
558 if( buffer[i] == ',' ){
559 i++;
560 }
561
562 Type resultType;
563 _int64 i64data;
564 if( !StaticCalculation( true, temporary, tempBaseType.GetBasicType(), &i64data, resultType ) ){
565 return false;
566 }
567 if( !resultType.IsWhole() ){
568 // TODO: 実数に未対応
569 SetError();
570 return false;
571 }
572
573 binary = realloc( binary, ( num + 1 ) * tempBaseType.GetSize() );
574 memcpy( (char *)binary + (num * tempBaseType.GetSize()), &i64data, tempBaseType.GetSize() );
575 num++;
576 }
577
578 i2 = dataTable.AddBinary( binary, num * tempBaseType.GetSize() );
579
580 //mov eax,i2
581 op_mov_RV(REG_EAX,i2);
582 obp-=sizeof(long);
583 pobj_DataTableSchedule->add();
584 obp+=sizeof(long);
585
586 free( buffer );
587
588 resultType = baseType;
589
590 //push eax
591 op_push( REG_EAX );
592
593 return true;
594 }
595
596
597 /////////////////////////////////
598 // 式要素を逆ポーランド式で取得
599 /////////////////////////////////
600
601 char *values[255];
602 long calc[255];
603 long stack[255];
604 int pnum;
605 if(!GetNumOpeElements(expression,&pnum,values,calc,stack)){
606 for(i=0;i<pnum;i++){
607 if(values[i]) HeapDefaultFree(values[i]);
608 }
609 return false;
610 }
611
612
613 BOOL bError;
614 bError=0;
615
616 //リテラル値のみの計算かどうかを判別するためのフラグ
617 BOOL bLiteralCalculation=1;
618
619 //リテラル演算の場合を考慮した演算前のバッファ位置
620 int BeforeObp;
621 BeforeObp=obp;
622
623 //リテラル演算の場合を考慮した演算前のプロシージャスケジュール位置
624 //※64ビットの掛け算、除算などで特殊関数が呼ばれるため
625 int Before_ProcAddrScheduleNum;
626 Before_ProcAddrScheduleNum=pobj_SubAddrSchedule->num;
627
628 //リテラル演算の場合を考慮した演算前のデータテーブルスケジュール位置
629 int Before_DataTableScheduleNum;
630 Before_DataTableScheduleNum=pobj_DataTableSchedule->num;
631
632 //リテラル演算の場合を考慮した演算前の再配置スケジュール
633 CReloc *pobj_BackReloc;
634 pobj_BackReloc=new CReloc();
635 pobj_BackReloc->copy(pobj_Reloc);
636
637 double dbl;
638 int sp;
639 int type_stack[255];
640 bool isNothing_stack[255];
641 LONG_PTR index_stack[255];
642 BOOL bUseHeap[255];
643 _int64 i64data;
644 for(i=0,sp=0;i<pnum;i++){
645 int idCalc;
646 idCalc=calc[i]%100;
647
648 if(idCalc){
649 if(type_stack[sp-2]==DEF_OBJECT){
650 if( idCalc == CALC_AS
651 && type_stack[sp-1] == ( DEF_OBJECT | FLAG_CAST )
652 && index_stack[sp-1] == index_stack[sp-2]
653 || isNothing_stack[sp-2] ){
654 // 同一の型、またはNothingに対するAsはAs演算子を呼び出さない
655 }
656 else if( idCalc == CALC_AS
657 && type_stack[sp-1] == ( DEF_OBJECT | FLAG_CAST )
658 && ( ((CClass *)index_stack[sp-1])->IsEqualsOrSubClass( (CClass *)index_stack[sp-2] ) || ((CClass *)index_stack[sp-2])->IsEqualsOrSubClass( (CClass *)index_stack[sp-1] )
659 )){
660 // ダウンキャストを許可する
661 }
662 else{
663 //オーバーロードされたオペレータを呼び出す
664 i2=CallOperatorProc(idCalc,baseType,type_stack,index_stack,bUseHeap,sp);
665 if(i2==0){
666 if(idCalc==CALC_EQUAL) lstrcpy(temp2,"==");
667 else GetCalcName(idCalc,temp2);
668 sprintf(temporary,"Operator %s",temp2);
669 SetError(27,temporary,cp);
670 goto error;
671 }
672 else if(i2==-1) goto error;
673
674 continue;
675 }
676 }
677
678 if(!CheckCalcType(idCalc,type_stack,sp)) goto error;
679 }
680
681 switch(idCalc){
682 //数値
683 case 0:
684 index_stack[sp]=-1;
685 isNothing_stack[sp] = false;
686 bUseHeap[sp]=0;
687
688 char *term;
689 term=values[i];
690
691 if( calc[i+1]%100 == CALC_AS ){
692 // As演算子の右辺値
693 //型名
694 if( Type::StringToType( term, resultType ) ){
695 resultType.SetBasicType( resultType.GetBasicType() | FLAG_CAST );
696 }
697 else{
698 SetError(3, term, cp );
699 goto error;
700 }
701
702 type_stack[sp] = resultType.GetBasicType();
703 index_stack[sp] = resultType.GetIndex();
704 sp++;
705
706 break;
707 }
708
709 if(term[0]=='\"'){
710 //リテラル文字列
711 if(!RemoveStringQuotes(term)){
712 SetError(43,NULL,cp);
713 goto error;
714 }
715 i3=lstrlen(term);
716StrLiteral:
717
718 if( baseType.IsObject() || baseType.IsNull() ){
719 //要求タイプがオブジェクト、または未定のとき
720
721 //String型オブジェクトを生成
722 NewStringObject(term);
723
724 type_stack[sp]=DEF_OBJECT;
725 index_stack[sp]=(LONG_PTR)pobj_DBClass->GetStringClassPtr();
726 bLiteralCalculation=0;
727
728 sp++;
729 break;
730 }
731
732
733 type_stack[sp]=typeOfPtrChar;
734 bLiteralCalculation=0;
735
736 i2=dataTable.AddString(term,i3);
737
738 //push DataSize
739 OpBuffer[obp++]=(char)0x68;
740 *((long *)(OpBuffer+obp))=i2;
741 pobj_DataTableSchedule->add();
742 obp+=sizeof(long);
743 }
744 else if((term[0]=='e'||term[0]=='E')&&
745 (term[1]=='x'||term[1]=='X')&&
746 term[2]=='\"'){
747 //拡張版リテラル文字列(エスケープシーケンス可能)
748 if(!RemoveStringQuotes(term+2)){
749 SetError(43,NULL,cp);
750 goto error;
751 }
752 i3=FormatString_EscapeSequence(term+2);
753 term+=2;
754
755 goto StrLiteral;
756 }
757 else if(IsVariableTopChar(term[0])||
758 term[0]=='*'||
759 (term[0]=='.'&&IsVariableTopChar(term[1]))){
760 //////////////////
761 // 何らかの識別子
762
763 bool isLiteral;
764 if( TermOpe( term, baseType, resultType, isLiteral, &bUseHeap[sp] ) ){
765 if(resultType.IsNull()){
766 //戻り値が存在しないとき
767 for(i2=0;;i2++){
768 if(term[i2]=='('||term[i2]=='\0'){
769 term[i2]=0;
770 break;
771 }
772 }
773 SetError(38,term,cp);
774
775 goto error;
776 }
777
778 type_stack[sp] = resultType.GetBasicType();
779 index_stack[sp] = resultType.GetIndex();
780
781 if( !isLiteral ){
782 bLiteralCalculation=0;
783 }
784
785 if( resultType.GetBasicType() & FLAG_CAST ){
786 // 型名のみ
787 SetError();
788 }
789 else{
790 if( resultType.IsReal() ){
791 //sub esp,size
792 //fstp ptr[esp]
793 op_fstp_push( resultType );
794 }
795 else{
796 if( resultType.Is64() ){
797 //push edx
798 op_push( REG_EDX );
799 }
800 else{
801 ExtendTypeTo32( resultType.GetBasicType(), REG_EAX );
802 }
803
804 //push eax
805 op_push( REG_EAX );
806 }
807 }
808
809 sp++;
810 break;
811 }
812
813
814 // Nothing
815 if( lstrcmp( term, "Nothing" ) == 0 ){
816 isNothing_stack[sp] = true;
817
818 type_stack[sp] = DEF_OBJECT;
819 if( baseType.IsObject() ){
820 index_stack[sp] = baseType.GetIndex();
821 }
822 else{
823 index_stack[sp] = (LONG_PTR)pobj_DBClass->GetObjectClassPtr();
824 }
825
826 bLiteralCalculation = 0;
827
828 //push 0
829 op_push_V( 0 );
830
831 sp++;
832 break;
833 }
834
835
836 //////////////
837 // 定数の場合
838 //////////////
839
840 i3 = CDBConst::obj.GetBasicType(term);
841 if(i3){
842 if( CDBConst::obj.IsStringPtr( term ) ){
843 //リテラル文字列
844
845 double dbl = CDBConst::obj.GetDoubleData(term);
846 memcpy(&i64data,&dbl,sizeof(double));
847
848 //バイト数
849 i3=lstrlen((char *)i64data);
850
851 memcpy(term,(char *)i64data,i3);
852 term[i3]=0;
853 goto StrLiteral;
854 }
855
856 type_stack[sp]=i3;
857 if(IsRealNumberType(i3)){
858 //実数
859 double dbl = CDBConst::obj.GetDoubleData(term);
860 memcpy(&i64data,&dbl,sizeof(double));
861 goto Literal;
862 }
863 else if(IsWholeNumberType(i3)){
864 //整数
865 i64data = CDBConst::obj.GetWholeData(term);
866 goto Literal;
867 }
868 else{
869 SetError(300,NULL,cp);
870 goto error;
871 }
872 }
873
874
875 //該当する識別子が見当たらないときはエラー扱いにする
876 bError=1;
877 SetError(3,term,cp);
878 type_stack[sp]=DEF_DOUBLE;
879 }
880 else{
881 //リテラル値
882 type_stack[sp]=GetLiteralValue(term,&i64data,baseType.GetBasicType());
883Literal:
884 if(type_stack[sp]==DEF_INT64||
885 type_stack[sp]==DEF_QWORD||
886 type_stack[sp]==DEF_DOUBLE){
887 //64ビット(符号有り整数/実数)
888
889 //push HILONG(dbl)
890 op_push_V((long)*(long *)(((char *)(&i64data))+4));
891
892 //push LOLONG(dbl)
893 op_push_V(*(long *)(&i64data));
894 }
895 else if(type_stack[sp]==DEF_SINGLE){
896 //single実数
897
898 float flt;
899 memcpy(&dbl,&i64data,sizeof(double));
900 flt=(float)dbl;
901 memcpy(&i3,&flt,sizeof(long));
902
903 //push term
904 op_push_V(i3);
905 }
906 else{
907 //その他
908
909 //push term
910 op_push_V((long)i64data);
911
912 if((long)i64data==0) index_stack[sp]=LITERAL_NULL;
913 }
914
915
916 //リテラル値の種類
917 if(Is64Type(type_stack[sp])==0&&IsRealNumberType(type_stack[sp])==0){
918 //整数(符号有り/無し)
919
920 index_stack[sp]=GetLiteralIndex(i64data);
921 }
922 }
923 sp++;
924 break;
925
926 //論理演算子
927 case CALC_XOR:
928 //value[sp-2] xor= value[sp-1]
929 //xor演算
930 if(!Calc_Xor(type_stack,index_stack,&sp)) goto error;
931 break;
932 case CALC_OR:
933 //value[sp-2] or= value[sp-1]
934 //or演算
935 if(!Calc_Or(type_stack,index_stack,&sp)) goto error;
936 break;
937 case CALC_AND:
938 //value[sp-2] and= value[sp-1]
939 //and演算
940 if(!Calc_And(type_stack,index_stack,&sp)) goto error;
941 break;
942 case CALC_NOT:
943 //value[sp-1]=Not value[sp-1]
944 //NOT演算子
945 if(!Calc_Not(type_stack,sp)) goto error;
946 break;
947
948 //比較演算子
949 case CALC_PE:
950 //value[sp-2]<=value[sp-1]
951 if(!Calc_Relation_PE(type_stack,index_stack,&sp)) goto error;
952 break;
953 case CALC_QE:
954 //value[sp-2]>=value[sp-1]
955 if(!Calc_Relation_QE(type_stack,index_stack,&sp)) goto error;
956 break;
957 case CALC_P:
958 //value[sp-2]<value[sp-1]
959 if(!Calc_Relation_P(type_stack,index_stack,&sp)) goto error;
960 break;
961 case CALC_Q:
962 //value[sp-2]>value[sp-1]
963 if(!Calc_Relation_Q(type_stack,index_stack,&sp)) goto error;
964 break;
965 case CALC_NOTEQUAL:
966 //value[sp-2]<>value[sp-1]
967 if(!Calc_Relation_NotEqual(type_stack,&sp)) goto error;
968 break;
969 case CALC_EQUAL:
970 //value[sp-2]=value[sp-1]
971 if(!Calc_Relation_Equal(type_stack,&sp)) goto error;
972 break;
973
974 //ビットシフト
975 case CALC_SHL:
976 //value[sp-2]=value[sp-2]<<value[sp-1]
977 if(!Calc_SHL(type_stack,&sp)) goto error;
978 break;
979 case CALC_SHR:
980 //value[sp-2]=value[sp-2]>>value[sp-1]
981 if(!Calc_SHR(type_stack,&sp)) goto error;
982 break;
983
984 //算術演算
985 case CALC_ADDITION:
986 case CALC_SUBTRACTION:
987 case CALC_PRODUCT:
988 if(!CalcTwoTerm_Arithmetic(idCalc,type_stack,index_stack,&sp)) goto error;
989 break;
990
991 case CALC_MOD:
992 //value[sp-2]%=value[sp-1]
993 //剰余演算
994 if(!Calc_Mod(type_stack,&sp)) goto error;
995 break;
996 case CALC_QUOTIENT:
997 //value[sp-2]/=value[sp-1];
998 //除算
999 if(!Calc_Divide(type_stack,&sp,baseType.GetBasicType())) goto error;
1000 break;
1001 case CALC_INTQUOTIENT:
1002 //value[sp-2]/=value[sp-1]
1003 //整数除算
1004 if(!Calc_IntDivide(type_stack,index_stack,&sp)) goto error;
1005 break;
1006 case CALC_MINUSMARK:
1007 //value[sp-1]=-value[sp-1]
1008 //符号反転
1009 if(!Calc_MinusMark(type_stack,sp)) goto error;
1010 index_stack[sp-1]=-1;
1011 break;
1012 case CALC_POWER:
1013 //べき乗演算(浮動小数点演算のみ)
1014 if(!Calc_Power(type_stack,&sp)) goto error;
1015 break;
1016 case CALC_AS:
1017 //キャスト
1018 if(!Calc_Cast(type_stack,index_stack,&sp)) goto error;
1019 break;
1020
1021 case CALC_BYVAL:
1022 //ポインタ型→参照型
1023 if( PTR_LEVEL( type_stack[sp-1] ) <= 0 ){
1024 //ポインタ型ではないとき
1025 SetError( 3, NULL, cp );
1026 goto error;
1027 }
1028
1029 type_stack[sp-1] = PTR_LEVEL_DOWN( type_stack[sp-1] );
1030
1031 break;
1032
1033 default:
1034 SetError(300,NULL,cp);
1035 goto error;
1036 }
1037 }
1038
1039 if(bError) goto error;
1040
1041 if(sp!=1){
1042 SetError(1,NULL,cp);
1043 goto error;
1044 }
1045
1046 if(bLiteralCalculation){
1047 //右辺値が数値の定数式の場合
1048 Type resultType;
1049 StaticCalculation(true, expression,baseType.GetBasicType(),&i64data,resultType);
1050
1051 obp=BeforeObp;
1052 pobj_SubAddrSchedule->num=Before_ProcAddrScheduleNum;
1053 pobj_DataTableSchedule->num=Before_DataTableScheduleNum;
1054 pobj_Reloc->copy(pobj_BackReloc);
1055
1056 if( resultType.GetBasicSize() == sizeof(_int64) ){
1057 //64ビット(符号有り整数/実数)
1058
1059 //push HILONG(i64data)
1060 op_push_V((long)*(long *)(((char *)(&i64data))+4));
1061
1062 //push LOLONG(i64data)
1063 op_push_V(*(long *)(&i64data));
1064 }
1065 else if( resultType.IsSingle() ){
1066 //single実数
1067
1068 memcpy(&dbl,&i64data,sizeof(_int64));
1069
1070 float flt;
1071 flt=(float)dbl;
1072 memcpy(&i3,&flt,sizeof(long));
1073
1074 //push flt
1075 op_push_V(i3);
1076 }
1077 else{
1078 //整数(符号有り/無し)
1079
1080 i3=(long)i64data;
1081
1082 if(resultType.GetBasicSize()==sizeof(char)) i3=i3&0x000000FF;
1083 if(resultType.GetBasicSize()==sizeof(short)) i3=i3&0x0000FFFF;
1084
1085 //push term
1086 op_push_V(i3);
1087 }
1088
1089 type_stack[0]=resultType.GetBasicType();
1090 index_stack[0]=resultType.GetIndex();
1091 }
1092 else{
1093 //右辺値が数値の定数式ではないとき
1094 if(IS_LITERAL(index_stack[0])) index_stack[0]=-1;
1095 }
1096
1097 if(pbUseHeap) *pbUseHeap=bUseHeap[0];
1098
1099 resultType.SetType( type_stack[0], index_stack[0] );
1100
1101 bool isSuccessful = true;
1102 goto finish;
1103
1104
1105error:
1106 isSuccessful = false;
1107 goto finish;
1108
1109
1110finish:
1111
1112 for(i=0;i<pnum;i++){
1113 if(values[i]) HeapDefaultFree(values[i]);
1114 }
1115
1116 //再配置スケジュールバックアップ情報を解放
1117 delete pobj_BackReloc;
1118
1119 return isSuccessful;
1120}
Note: See TracBrowser for help on using the repository browser.