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

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

関数の戻り値がクラス型のとき、直接インデクサ指定できるような対応を行った。ただし、この対応は暫定的なものであるため、後ほど改修が必要。

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