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

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

DataTable::AddWStringメソッドを追加。

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