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

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