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

Last change on this file since 538 was 536, checked in by dai_9181, 17 years ago

Compiler::pCompilingClassメンバをprivateにし、setter/getterにあたるメソッドを用意した。

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