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

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

COM修飾子に対応。COMインターフェイスを呼び出せるようにした

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