source: dev/trunk/abdev/BasicCompiler32/NumOpe.cpp@ 412

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

CClass::GetStaticDefiningStringAsMemberOffsetsメソッドを追加。
エラーコード142を追加。

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