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

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

不正なByValに対するエラーメッセージが正確に表示されなくなるバグを修正

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