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

Last change on this file since 327 was 327, checked in by dai_9181, 17 years ago

デリゲートのベースがほぼ実装できた

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