source: dev/trunk/abdev/BasicCompiler64/NumOpe.cpp@ 350

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

インターフェイスを実装

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