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

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

GCのバグをいくつか修正

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