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

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