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

Last change on this file since 700 was 700, checked in by イグトランス (egtra), 16 years ago

CRequireFilesの管理をhash_setベースへ。保存時にFileIndexの記録を行っていなかった問題を修正。rev.669でコミットし忘れのcompiler_x86/NumOpe.cppを追加。

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