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

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

UserProc::SetParamsAndReturnTypeメソッドをリファクタリング
LexicalAnalysis.hのインクルードを除去した

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