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

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