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

Last change on this file since 361 was 361, checked in by dai_9181, 16 years ago

Catchのオーバーロードを実装中

File size: 31.9 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 int i,i2,i3;
593 char temporary[1024],temp2[1024];
594
595 if(expression[0]=='\0'){
596 SetError(1,NULL,cp);
597 return false;
598 }
599
600 if( !baseType.IsNull() && expression[0] == '[' ){
601 // リテラル配列の場合
602
603 int dataTableOffset;
604 if( !compiler.GetObjectModule().dataTable.MakeLiteralArrayBuffer( expression, baseType, dataTableOffset ) )
605 {
606 return false;
607 }
608
609 //mov reg,i2
610 compiler.codeGenerator.op_mov_RV( sizeof(_int64), *pReg, dataTableOffset, Schedule::DataTable );
611
612 resultType = baseType;
613
614 return true;
615 }
616
617 bool isLiteralCalculation;
618 if( NumOpe_GetType( expression, baseType, resultType, &isLiteralCalculation ) )
619 {
620 if( isLiteralCalculation )
621 {
622 //右辺値が数値の定数式の場合
623 _int64 i64data;
624 StaticCalculation(true, expression,baseType.GetBasicType(),&i64data,resultType);
625
626 if(resultType.IsReal()){
627 if(baseType.IsReal()) resultType=baseType;
628
629 int xmmReg = pobj_reg->GetNextXmmReg();
630 *pReg = xmmReg;
631
632 if(resultType.IsDouble()){
633 i3 = compiler.GetObjectModule().dataTable.Add( i64data );
634
635 //movlpd xmm_reg,qword ptr[data table offset]
636 compiler.codeGenerator.op_movlpd_RM( xmmReg, 0, i3, MOD_DISP32, Schedule::DataTable );
637 }
638 if(resultType.IsSingle()){
639 double dbl;
640 memcpy(&dbl,&i64data,sizeof(_int64));
641
642 float flt;
643 int i32data;
644 flt=(float)dbl;
645 memcpy(&i32data,&flt,sizeof(long));
646
647 i3 = compiler.GetObjectModule().dataTable.Add( i32data );
648
649 //movss xmm_reg,dword ptr[data table offset]
650 compiler.codeGenerator.op_movss_RM( xmmReg, 0, i3, MOD_DISP32, Schedule::DataTable );
651 }
652 }
653 else{
654 if(!resultType.Is64()){
655 //整数(符号有り/無し)
656
657 i3=(long)i64data;
658
659 if(resultType.GetBasicSize()==sizeof(char)) i3=i3&0x000000FF;
660 if(resultType.GetBasicSize()==sizeof(short)) i3=i3&0x0000FFFF;
661
662 i64data=(_int64)i3;
663 }
664
665 //mov reg,i64data
666 compiler.codeGenerator.op_mov_RV64(*pReg,i64data);
667 }
668 return true;
669 }
670 }
671
672 if( expression[0] == 1 )
673 {
674 if( expression[1]==ESC_NEW )
675 {
676 //New演算子(オブジェクト生成)
677
678 if( pobj_BlockReg->check(REG_RAX) ){
679 SetError();
680 }
681
682 //////////////////////////////////////////////////////
683 ///// レジスタ資源のバックアップ
684 { BACKUP_REGISTER_RESOURCE
685 //////////////////////////////////////////////////////
686
687 if( !Operator_New( expression+2, baseType, resultType ) ){
688 return false;
689 }
690
691 /////////////////////////////////////////////
692 ////// レジスタ資源を復元
693 RESTORE_REGISTER_RESOURCE
694 }////////////////////////////////////////////
695
696 //mov reg,rax
697 compiler.codeGenerator.op_mov_RR( *pReg, REG_RAX );
698
699 return true;
700 }
701 else if( expression[1] == ESC_SYSTEM_STATIC_NEW )
702 {
703 // 静的領域にオブジェクトを作る
704
705 // 静的領域にオブジェクトを生成
706 int dataTableOffset;
707 if( !compiler.GetObjectModule().dataTable.MakeConstObjectToProcessStaticBuffer( expression + 2, resultType, dataTableOffset ) )
708 {
709 return false;
710 }
711
712 //mov reg,i2
713 compiler.codeGenerator.op_mov_RV( sizeof(_int64), *pReg, dataTableOffset, Schedule::DataTable);
714
715 return true;
716 }
717 }
718
719
720 /////////////////////////////////
721 // 式要素を逆ポーランド式で取得
722 /////////////////////////////////
723
724 char *values[255];
725 long calc[255];
726 long stack[255];
727 int pnum;
728 if(!GetNumOpeElements(expression,&pnum,values,calc,stack)){
729 for(i=0;i<pnum;i++){
730 if(values[i]) HeapDefaultFree(values[i]);
731 }
732 return 0;
733 }
734
735
736 if( strstr(expression,"xxxxx"))
737 {
738 int test=0;
739 }
740
741 ////////////////////////////////
742 // 演算部分のコード生成を開始
743 ////////////////////////////////
744
745 BOOL bError;
746 bError=0;
747
748 //リテラル値のみの計算かどうかを判別するためのフラグ
749 BOOL bLiteralCalculation=1;
750
751 double dbl;
752 int sp;
753 int type_stack[255];
754 LONG_PTR index_stack[255];
755 bool isNothing_stack[255];
756 BOOL bUseHeap[255];
757 _int64 i64data;
758 int UseReg,XmmReg;
759 BOOL bXmm;
760 for(i=0,sp=0;i<pnum;i++){
761 int idCalc;
762 idCalc=calc[i]%100;
763
764 if(idCalc){
765 if(type_stack[sp-2]==DEF_OBJECT){
766 if( idCalc == CALC_AS
767 && type_stack[sp-1] == ( DEF_OBJECT | FLAG_CAST )
768 && index_stack[sp-1] == index_stack[sp-2]
769 || isNothing_stack[sp-2] ){
770 // 同一の型、またはNothingに対するAsはAs演算子を呼び出さない
771 }
772 else if( idCalc == CALC_AS
773 && type_stack[sp-1] == ( DEF_OBJECT | FLAG_CAST )
774 && ( ((CClass *)index_stack[sp-1])->IsEqualsOrSubClass( (CClass *)index_stack[sp-2] ) || ((CClass *)index_stack[sp-2])->IsEqualsOrSubClass( (CClass *)index_stack[sp-1] )
775 )){
776 // ダウンキャストを許可する
777 }
778 else{
779 //オーバーロードされたオペレータを呼び出す
780 i2=CallOperatorProc(idCalc,baseType,type_stack,index_stack,bUseHeap,sp);
781 if(i2==0){
782 if(idCalc==CALC_EQUAL) lstrcpy(temp2,"==");
783 else GetCalcName(idCalc,temp2);
784 sprintf(temporary,"Operator %s",temp2);
785 SetError(27,temporary,cp);
786 goto error;
787 }
788 else if(i2==-1) goto error;
789
790 continue;
791 }
792 }
793
794 if(!CheckCalcType(idCalc,type_stack,sp)) goto error;
795 }
796
797 switch(idCalc){
798 //数値
799 case 0:
800 index_stack[sp]=-1;
801 isNothing_stack[sp] = false;
802 bUseHeap[sp]=0;
803
804 UseReg=pobj_reg->GetNextReg();
805 XmmReg=pobj_reg->GetNextXmmReg();
806
807 bXmm=0;
808
809 char *term;
810 term=values[i];
811
812 if( calc[i+1]%100 == CALC_AS ){
813 // As演算子の右辺値
814 //型名
815 if( compiler.StringToType( term, resultType ) ){
816 resultType.SetBasicType( resultType.GetBasicType() | FLAG_CAST );
817 }
818 else{
819 SetError(3, term, cp );
820 goto error;
821 }
822
823 type_stack[sp] = resultType.GetBasicType();
824 index_stack[sp] = resultType.GetIndex();
825 sp++;
826
827 break;
828 }
829
830 if( (term[0]=='e'||term[0]=='E')
831 && (term[1]=='x'||term[1]=='X')
832 && term[2]=='\"'
833 || term[0] == '\"' )
834 {
835 bool isEx = true;
836 if( term[0] == '\"' )
837 {
838 isEx = false;
839 }
840
841 if( isEx )
842 {
843 // 拡張版リテラル文字列(エスケープシーケンス可能)
844 if(!RemoveStringQuotes(term+2)){
845 SetError(43,NULL,cp);
846 goto error;
847 }
848 i3=FormatString_EscapeSequence(term+2);
849 term+=2;
850 }
851 else
852 {
853 // 通常文字列
854 if(!RemoveStringQuotes(term)){
855 SetError(43,NULL,cp);
856 goto error;
857 }
858 i3=lstrlen(term);
859 }
860
861 if( !baseType.IsPointer() )
862 {
863 //要求タイプがオブジェクト、または未定のとき
864
865 //String型オブジェクトを生成
866 i2 = compiler.GetObjectModule().dataTable.MakeConstStringObjectToProcessStaticBuffer( term );
867
868 //mov reg,i2
869 compiler.codeGenerator.op_mov_RV(sizeof(_int64),UseReg,i2, Schedule::DataTable);
870
871 type_stack[sp]=DEF_OBJECT;
872 index_stack[sp]=(LONG_PTR)compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr();
873 bLiteralCalculation=0;
874
875 if(bXmm) pobj_reg->LockXmmReg();
876 else pobj_reg->LockReg();
877
878 sp++;
879 break;
880 }
881
882StrLiteral:
883
884 type_stack[sp]=typeOfPtrChar;
885 bLiteralCalculation=0;
886
887 i2 = compiler.GetObjectModule().dataTable.AddString( term, i3 );
888
889 //mov reg,i2
890 compiler.codeGenerator.op_mov_RV(sizeof(_int64),UseReg,i2, Schedule::DataTable);
891
892 if(UseReg==REG_R14){
893 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
894 pobj_sf->push(REG_R14);
895 }
896 }
897 else if(IsVariableTopChar(term[0])||
898 term[0]=='*'||
899 (term[0]=='.'&&IsVariableTopChar(term[1])))
900 {
901 //////////////////
902 // 何らかの識別子
903
904 bool isLiteral;
905 if( TermOpe( term, baseType, resultType, isLiteral, &bUseHeap[sp] ) ){
906 if(resultType.IsNull()){
907 //戻り値が存在しないとき
908 for(i2=0;;i2++){
909 if(term[i2]=='('||term[i2]=='\0'){
910 term[i2]=0;
911 break;
912 }
913 }
914 SetError(38,term,cp);
915
916 goto error;
917 }
918
919 type_stack[sp] = resultType.GetBasicType();
920 index_stack[sp] = resultType.GetIndex();
921
922 if( !isLiteral ){
923 bLiteralCalculation=0;
924 }
925
926 if( resultType.GetBasicType() & FLAG_CAST ){
927 // 型名のみ
928 SetError();
929 }
930 else{
931 if( resultType.IsReal() == false && UseReg==REG_R14 ){
932 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
933 pobj_sf->push(REG_R14);
934 }
935 if( resultType.IsReal() && XmmReg==REG_XMM4 ){
936 if(resultType.IsDouble()){
937 //movsd qword ptr[rsp+offset],xmm4 ※スタックフレームを利用
938 pobj_sf->push(REG_XMM4,sizeof(double));
939 }
940 if(resultType.IsSingle()){
941 //movss dword ptr[rsp+offset],xmm4 ※スタックフレームを利用
942 pobj_sf->push(REG_XMM4,sizeof(float));
943 }
944 }
945
946 if( resultType.IsReal() ){
947 pobj_reg->LockXmmReg();
948 }
949 else{
950 pobj_reg->LockReg();
951 }
952 }
953
954 sp++;
955 break;
956 }
957
958
959 // Nothing
960 if( lstrcmp( term, "Nothing" ) == 0 ){
961 isNothing_stack[sp] = true;
962
963 type_stack[sp] = DEF_OBJECT;
964 if( baseType.IsObject() ){
965 index_stack[sp] = baseType.GetIndex();
966 }
967 else{
968 index_stack[sp] = (LONG_PTR)compiler.GetObjectModule().meta.GetClasses().GetObjectClassPtr();
969 }
970
971 bLiteralCalculation = 0;
972
973 //xor reg,reg
974 compiler.codeGenerator.op_zero_reg( UseReg );
975
976 if(UseReg==REG_R14){
977 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
978 pobj_sf->push(REG_R14);
979 }
980
981 pobj_reg->LockReg();
982 sp++;
983 break;
984 }
985
986
987 //////////////
988 // 定数の場合
989 //////////////
990
991 i3 = compiler.GetObjectModule().meta.GetGlobalConsts().GetBasicType(term);
992 if(i3){
993 if( compiler.GetObjectModule().meta.GetGlobalConsts().IsStringPtr( term ) ){
994 //リテラル文字列
995
996 if( baseType.IsObject() || baseType.IsNull() )
997 {
998 //要求タイプがオブジェクト、または未定のとき
999
1000 //String型オブジェクトを生成
1001 NewStringObject(UseReg,term);
1002
1003 type_stack[sp]=DEF_OBJECT;
1004 index_stack[sp]=(LONG_PTR)compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr();
1005 bLiteralCalculation=0;
1006
1007 if(bXmm) pobj_reg->LockXmmReg();
1008 else pobj_reg->LockReg();
1009
1010 sp++;
1011 break;
1012 }
1013
1014 double dbl = compiler.GetObjectModule().meta.GetGlobalConsts().GetDoubleData(term);
1015 memcpy(&i64data,&dbl,sizeof(double));
1016
1017 //バイト数
1018 i3=lstrlen((char *)i64data);
1019
1020 memcpy(term,(char *)i64data,i3);
1021 term[i3]=0;
1022 goto StrLiteral;
1023 }
1024
1025 type_stack[sp] = i3;
1026 if(IsRealNumberType(i3)){
1027 //実数
1028 double dbl = compiler.GetObjectModule().meta.GetGlobalConsts().GetDoubleData(term);
1029 memcpy(&i64data,&dbl,sizeof(double));
1030 goto Literal;
1031 }
1032 else if(IsWholeNumberType(i3)){
1033 //整数
1034 i64data = compiler.GetObjectModule().meta.GetGlobalConsts().GetWholeData(term);
1035 goto Literal;
1036 }
1037 else{
1038 SetError(1,NULL,0);
1039 goto error;
1040 }
1041 }
1042
1043
1044 //該当する識別子が見当たらないときはエラー扱いにする
1045 bError=1;
1046 SetError(3,term,cp);
1047 type_stack[sp]=DEF_DOUBLE;
1048 }
1049 else{
1050 //リテラル値
1051 type_stack[sp]=GetLiteralValue(term,&i64data,baseType.GetBasicType());
1052Literal:
1053 if(type_stack[sp]==DEF_DOUBLE){
1054 //64ビット浮動小数型
1055 bXmm=1;
1056
1057 if(XmmReg==REG_XMM4){
1058 //mov r14,i64data
1059 compiler.codeGenerator.op_mov_RV64(REG_R14,i64data);
1060
1061
1062 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
1063 pobj_sf->push(REG_R14);
1064 }
1065 else{
1066 i3 = compiler.GetObjectModule().dataTable.Add( i64data );
1067
1068 //movlpd xmm_reg,qword ptr[data table offset]
1069 compiler.codeGenerator.op_movlpd_RM( XmmReg, 0, i3, MOD_DISP32, Schedule::DataTable );
1070 }
1071 }
1072 else if(type_stack[sp]==DEF_SINGLE){
1073 //32ビット浮動小数型
1074 bXmm=1;
1075
1076 float flt;
1077 int i32data;
1078 memcpy(&dbl,&i64data,sizeof(double));
1079 flt=(float)dbl;
1080 memcpy(&i32data,&flt,sizeof(long));
1081
1082 if(XmmReg==REG_XMM4){
1083 SetError(); // TODO: 未実装
1084 //push term
1085 //compiler.codeGenerator.op_push_value(i32data);
1086 }
1087 else{
1088 i3=compiler.GetObjectModule().dataTable.Add( i32data );
1089
1090 //movss xmm_reg,dword ptr[data table offset]
1091 compiler.codeGenerator.op_movss_RM( XmmReg, 0, i3, MOD_DISP32, Schedule::DataTable );
1092 }
1093 }
1094 else{
1095 //整数
1096
1097 index_stack[sp]=GetLiteralIndex(i64data);
1098
1099 //mov reg,i64data
1100 compiler.codeGenerator.op_mov_RV64(UseReg,i64data);
1101
1102 if(UseReg==REG_R14){
1103 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
1104 pobj_sf->push(REG_R14);
1105 }
1106 }
1107 }
1108
1109 if(bXmm) pobj_reg->LockXmmReg();
1110 else pobj_reg->LockReg();
1111
1112 sp++;
1113 break;
1114
1115 //論理演算子
1116 case CALC_XOR:
1117 case CALC_OR:
1118 case CALC_AND:
1119 if(!CalcTwoTerm_Logical(idCalc,type_stack,index_stack,&sp)) goto error;
1120 break;
1121 case CALC_NOT:
1122 //value[sp-1]=Not value[sp-1]
1123 //NOT演算子
1124 if(!Calc_Not(type_stack,sp)) goto error;
1125 break;
1126
1127 //比較演算子
1128 case CALC_PE: //value[sp-2] <= value[sp-1]
1129 case CALC_QE: //value[sp-2] >= value[sp-1]
1130 case CALC_P: //value[sp-2] < value[sp-1]
1131 case CALC_Q: //value[sp-2] > value[sp-1]
1132 case CALC_NOTEQUAL: //value[sp-2] <> value[sp-1]
1133 case CALC_EQUAL: //value[sp-2] = value[sp-1]
1134 if(!CalcTwoTerm_Relational(idCalc,type_stack,index_stack,&sp)) goto error;
1135 break;
1136
1137 //ビットシフト
1138 case CALC_SHL: //value[sp-2] << value[sp-1]
1139 case CALC_SHR: //value[sp-2] >> value[sp-1]
1140 if(!Calc_Shift(idCalc,type_stack,&sp)) goto error;
1141 break;
1142
1143 //算術演算
1144 case CALC_ADDITION:
1145 case CALC_SUBTRACTION:
1146 case CALC_PRODUCT:
1147 if(!CalcTwoTerm_Arithmetic(idCalc,type_stack,index_stack,&sp)) goto error;
1148 break;
1149 case CALC_MOD:
1150 //value[sp-2]%=value[sp-1]
1151 //剰余演算
1152 if(!Calc_Mod(type_stack,index_stack,&sp)) goto error;
1153 break;
1154 case CALC_QUOTIENT:
1155 //value[sp-2]/=value[sp-1];
1156 //除算
1157 if(!Calc_Divide(type_stack,&sp,baseType.GetBasicType())) goto error;
1158 break;
1159 case CALC_INTQUOTIENT:
1160 //value[sp-2]/=value[sp-1]
1161 //整数除算
1162 if(!Calc_IntDivide(type_stack,index_stack,&sp)) goto error;
1163 break;
1164 case CALC_MINUSMARK:
1165 //value[sp-1]=-value[sp-1]
1166 //符号反転
1167 if(!Calc_MinusMark(type_stack,sp)) goto error;
1168 break;
1169 case CALC_POWER:
1170 //べき乗演算(浮動小数点演算のみ)
1171 if(!Calc_Power(type_stack,&sp)) goto error;
1172 break;
1173 case CALC_AS:
1174 //キャスト
1175 if(!Calc_Cast(type_stack,index_stack,&sp)) goto error;
1176 break;
1177 case CALC_BYVAL:
1178 //ポインタ型→参照型
1179 if( PTR_LEVEL( type_stack[sp-1] ) <= 0 ){
1180 //ポインタ型ではないとき
1181 SetError( 3, NULL, cp );
1182 goto error;
1183 }
1184
1185 type_stack[sp-1] = PTR_LEVEL_DOWN( type_stack[sp-1] );
1186
1187 break;
1188
1189 default:
1190 SetError(300,NULL,cp);
1191 goto error;
1192 }
1193 }
1194
1195 if(bError) goto error;
1196
1197 if(sp!=1){
1198 SetError(1,NULL,cp);
1199 goto error;
1200 }
1201
1202 if(bLiteralCalculation){
1203 SetError();
1204 }
1205 else{
1206 //右辺値が数値の定数式ではないとき
1207 if(IS_LITERAL(index_stack[0])) index_stack[0]=-1;
1208 }
1209
1210 if(pbUseHeap) *pbUseHeap=bUseHeap[0];
1211
1212 if(IsRealNumberType(type_stack[0]))
1213 *pReg=pobj_reg->UnlockXmmReg();
1214 else
1215 *pReg=pobj_reg->UnlockReg();
1216
1217
1218 resultType.SetType( type_stack[0], index_stack[0] );
1219
1220 bool isSuccessful = true;
1221 goto finish;
1222
1223
1224
1225 //////////////////
1226 // エラー処理
1227 //////////////////
1228
1229error:
1230
1231 isSuccessful = false;
1232 goto finish;
1233
1234
1235
1236
1237finish:
1238
1239 for(i=0;i<pnum;i++){
1240 if(values[i]) HeapDefaultFree(values[i]);
1241 }
1242
1243 return isSuccessful;
1244}
1245
1246bool NumOpe( int *pReg,
1247 const char *expression,
1248 const Type &baseType,
1249 Type &resultType,
1250 BOOL *pbUseHeap )
1251{
1252 BOOL bInitRegSwitch=0;
1253 if(!pobj_reg){
1254 bInitRegSwitch=1;
1255
1256 //作業用レジスタを取得
1257 pobj_reg=new CRegister(*pReg);
1258 }
1259
1260 //エラー時の復旧用
1261 CRegister objReg_Backup;
1262 objReg_Backup=*pobj_reg;
1263
1264 *pReg = pobj_reg->GetNextReg();
1265
1266
1267 bool result = _numope( pReg, expression, baseType, resultType, pbUseHeap );
1268
1269
1270 if( !result )
1271 {
1272 *pobj_reg=objReg_Backup;
1273 }
1274
1275 if(bInitRegSwitch){
1276 //整合性をチェック(バグ回避)
1277 if( result )
1278 {
1279 pobj_reg->bug_check();
1280 }
1281
1282 //作業レジスタを解放
1283 delete pobj_reg;
1284 pobj_reg=0;
1285 }
1286
1287 return result;
1288}
Note: See TracBrowser for help on using the repository browser.