source: dev/trunk/ab5.0/abdev/compiler_x86/NumOpe.cpp@ 696

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

If/While/Doなどのステートメントに引き渡す式の戻り値がクラス型の場合はBoolean型へのキャストを試みるようにした。

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