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

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

UserProc::SetParamsAndReturnTypeメソッドをリファクタリング
LexicalAnalysis.hのインクルードを除去した

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