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

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

PareOrBracket列挙型を導入。

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