| [206] | 1 | #include "stdafx.h"
 | 
|---|
 | 2 | 
 | 
|---|
| [183] | 3 | #include <jenga/include/smoothie/Smoothie.h>
 | 
|---|
| [198] | 4 | #include <Compiler.h>
 | 
|---|
 | 5 | 
 | 
|---|
| [3] | 6 | #include "../BasicCompiler_Common/common.h"
 | 
|---|
 | 7 | #include "Opcode.h"
 | 
|---|
 | 8 | 
 | 
|---|
| [308] | 9 | void SetVariableFromRax( const Type &varType, int CalcType,RELATIVE_VAR *pRelativeVar){
 | 
|---|
| [3] | 10 |     /////////////////////////////////////////////////
 | 
|---|
 | 11 |     // raxの内容を変数にコピーするコードを抽出
 | 
|---|
 | 12 |     /////////////////////////////////////////////////
 | 
|---|
 | 13 | 
 | 
|---|
| [308] | 14 |     if( varType.IsBoolean() )
 | 
|---|
 | 15 |     {
 | 
|---|
| [36] | 16 |         //bool
 | 
|---|
 | 17 |         SetBooleanVariable(CalcType,pRelativeVar);
 | 
|---|
 | 18 |     }
 | 
|---|
| [308] | 19 |     else if( varType.IsReal() )
 | 
|---|
 | 20 |     {
 | 
|---|
| [64] | 21 |         // Double/Single型変数へレジスタの値を代入
 | 
|---|
| [308] | 22 |         SetRealVariable(varType.GetBasicType(), CalcType, pRelativeVar);
 | 
|---|
| [3] | 23 |     }
 | 
|---|
| [308] | 24 |     else if( varType.IsWhole() || varType.IsObject() )
 | 
|---|
 | 25 |     {
 | 
|---|
| [64] | 26 |         //整数変数へraxの値を格納する
 | 
|---|
| [308] | 27 |         SetWholeVariable( varType.GetSize(), CalcType, pRelativeVar );
 | 
|---|
| [3] | 28 |     }
 | 
|---|
| [55] | 29 |     else{
 | 
|---|
 | 30 |         SetError(300,NULL,cp);
 | 
|---|
 | 31 |     }
 | 
|---|
| [3] | 32 | }
 | 
|---|
| [129] | 33 | void OpcodeCalc(const char *Command){
 | 
|---|
| [3] | 34 |     int i,i2,i3;
 | 
|---|
 | 35 |     char variable[VN_SIZE];
 | 
|---|
 | 36 | 
 | 
|---|
 | 37 | 
 | 
|---|
 | 38 |     //////////////////////////////////////
 | 
|---|
 | 39 |     // インクリメント・デクリメント
 | 
|---|
 | 40 |     //////////////////////////////////////
 | 
|---|
 | 41 | 
 | 
|---|
 | 42 |     for(i=0;;i++){
 | 
|---|
 | 43 |         if(Command[i]=='\"'){
 | 
|---|
 | 44 |             //ダブルクォートは不正なのでエラー扱い
 | 
|---|
 | 45 |             variable[i]=0;
 | 
|---|
 | 46 |             SetError(3,variable,cp);
 | 
|---|
 | 47 |             return;
 | 
|---|
 | 48 |         }
 | 
|---|
 | 49 | 
 | 
|---|
 | 50 |         if(Command[i]=='('){
 | 
|---|
 | 51 |             i2=GetStringInPare(variable+i,Command+i);
 | 
|---|
 | 52 |             i+=i2-1;
 | 
|---|
 | 53 |             continue;
 | 
|---|
 | 54 |         }
 | 
|---|
 | 55 |         if(Command[i]=='['){
 | 
|---|
 | 56 |             i2=GetStringInBracket(variable+i,Command+i);
 | 
|---|
 | 57 |             i+=i2-1;
 | 
|---|
 | 58 |             continue;
 | 
|---|
 | 59 |         }
 | 
|---|
 | 60 |         if(Command[i]=='\0'){
 | 
|---|
 | 61 | 
 | 
|---|
 | 62 |             ///////////////////////////////////
 | 
|---|
 | 63 |             // インクリメント・デクリメント
 | 
|---|
 | 64 |             ///////////////////////////////////
 | 
|---|
 | 65 | 
 | 
|---|
 | 66 |             if(i>2){
 | 
|---|
 | 67 |                 if(Command[i-2]=='+'&&Command[i-1]=='+'){
 | 
|---|
 | 68 |                     //インクリメント
 | 
|---|
 | 69 |                     variable[i-2]=0;
 | 
|---|
 | 70 |                     IncDec(CALC_ADDITION,variable,"1");
 | 
|---|
 | 71 |                     return;
 | 
|---|
 | 72 |                 }
 | 
|---|
 | 73 |                 else if(Command[i-2]=='-'&&Command[i-1]=='-'){
 | 
|---|
 | 74 |                     //デクリメント
 | 
|---|
 | 75 |                     variable[i-2]=0;
 | 
|---|
 | 76 |                     IncDec(CALC_SUBTRACTION,variable,"1");
 | 
|---|
 | 77 |                     return;
 | 
|---|
 | 78 |                 }
 | 
|---|
 | 79 |             }
 | 
|---|
 | 80 | 
 | 
|---|
 | 81 | 
 | 
|---|
 | 82 |             //先端部分の識別子をエラーキーワードにする
 | 
|---|
 | 83 |             for(i=0;;i++){
 | 
|---|
 | 84 |                 if(!IsVariableChar(Command[i])){
 | 
|---|
 | 85 |                     variable[i]=0;
 | 
|---|
 | 86 |                     break;
 | 
|---|
 | 87 |                 }
 | 
|---|
 | 88 |                 variable[i]=Command[i];
 | 
|---|
 | 89 |             }
 | 
|---|
 | 90 | 
 | 
|---|
| [75] | 91 |             if(GetVarType(variable,Type(),0)){
 | 
|---|
| [3] | 92 |                 //変数リストに該当したとき
 | 
|---|
 | 93 |                 SetError(1,NULL,cp);
 | 
|---|
 | 94 |             }
 | 
|---|
 | 95 |             else{
 | 
|---|
| [266] | 96 |                 if( compiler.GetObjectModule().meta.GetGlobalConsts().IsExist(variable)
 | 
|---|
 | 97 |                     || compiler.GetObjectModule().meta.GetGlobalConstMacros().IsExist(variable) )
 | 
|---|
| [206] | 98 |                 {
 | 
|---|
| [3] | 99 |                     //定数リストに該当したとき
 | 
|---|
 | 100 |                     SetError(1,NULL,cp);
 | 
|---|
 | 101 |                 }
 | 
|---|
 | 102 |                 else{
 | 
|---|
 | 103 |                     //変数リスト、定数リストに該当しないとき
 | 
|---|
 | 104 |                     SetError(3,variable,cp);
 | 
|---|
 | 105 |                 }
 | 
|---|
 | 106 |             }
 | 
|---|
 | 107 |             return;
 | 
|---|
 | 108 |         }
 | 
|---|
 | 109 | 
 | 
|---|
 | 110 |         i2=GetCalcId(Command+i,&i3);
 | 
|---|
 | 111 |         if(i2){
 | 
|---|
 | 112 |             variable[i]=0;
 | 
|---|
 | 113 | 
 | 
|---|
 | 114 |             if(Command[i]=='=') break;
 | 
|---|
 | 115 | 
 | 
|---|
 | 116 |             if(Command[i+1+i3]=='='){
 | 
|---|
 | 117 |                 IncDec(i2,variable,Command+i+1+i3+1);
 | 
|---|
 | 118 |                 return;
 | 
|---|
 | 119 |             }
 | 
|---|
 | 120 |         }
 | 
|---|
 | 121 | 
 | 
|---|
 | 122 |         variable[i]=Command[i];
 | 
|---|
 | 123 |     }
 | 
|---|
 | 124 | 
 | 
|---|
 | 125 |     if(Command[i+1]=='\0'){
 | 
|---|
 | 126 |         SetError(1,NULL,cp);
 | 
|---|
 | 127 |         return;
 | 
|---|
 | 128 |     }
 | 
|---|
 | 129 | 
 | 
|---|
 | 130 | 
 | 
|---|
 | 131 | 
 | 
|---|
 | 132 |     ///////////////////////////////////////////////////////////////
 | 
|---|
 | 133 |     // インデクサのsetアクセサ([]=演算子のオーバーロードに対応)
 | 
|---|
 | 134 |     ///////////////////////////////////////////////////////////////
 | 
|---|
 | 135 | 
 | 
|---|
 | 136 |     char ObjName[VN_SIZE],array_element[VN_SIZE];
 | 
|---|
 | 137 |     GetArrayElement(variable,ObjName,array_element);
 | 
|---|
 | 138 |     if(array_element[0]){
 | 
|---|
| [75] | 139 |         Type varType;
 | 
|---|
 | 140 |         if( GetVarType(ObjName,varType,0) && varType.IsObject() ){
 | 
|---|
| [3] | 141 |             char temporary[VN_SIZE];
 | 
|---|
 | 142 |             sprintf(temporary,"%s.%c%c%c",ObjName,1,ESC_OPERATOR,CALC_ARRAY_SET);
 | 
|---|
 | 143 | 
 | 
|---|
 | 144 |             char temp2[VN_SIZE];
 | 
|---|
 | 145 |             sprintf(temp2,"%s,%s",array_element,Command+i+1);
 | 
|---|
 | 146 | 
 | 
|---|
 | 147 |             int idProc;
 | 
|---|
| [75] | 148 |             void *pProc;
 | 
|---|
 | 149 |             idProc=GetProc(temporary,(void **)&pProc);
 | 
|---|
| [331] | 150 |             if( idProc )
 | 
|---|
 | 151 |             {
 | 
|---|
 | 152 |                 CallProc(
 | 
|---|
 | 153 |                     idProc,
 | 
|---|
 | 154 |                     pProc,
 | 
|---|
 | 155 |                     temporary,
 | 
|---|
 | 156 |                     temp2,
 | 
|---|
 | 157 |                     Type(),         // ベースタイプはなし
 | 
|---|
 | 158 |                     Type()
 | 
|---|
 | 159 |                 );
 | 
|---|
| [3] | 160 |                 return;
 | 
|---|
 | 161 |             }
 | 
|---|
 | 162 |         }
 | 
|---|
 | 163 |     }
 | 
|---|
 | 164 | 
 | 
|---|
 | 165 | 
 | 
|---|
| [64] | 166 |     if( lstrcmpi( variable, "This" ) == 0 ){
 | 
|---|
 | 167 |         SetError(133,NULL,cp);
 | 
|---|
 | 168 |         return;
 | 
|---|
 | 169 |     }
 | 
|---|
| [3] | 170 | 
 | 
|---|
| [64] | 171 | 
 | 
|---|
| [3] | 172 |     ////////////////////////////////////////
 | 
|---|
 | 173 |     // 変数のタイプ型を識別して、演算を行う
 | 
|---|
 | 174 |     ////////////////////////////////////////
 | 
|---|
 | 175 | 
 | 
|---|
| [75] | 176 |     Type varType;
 | 
|---|
| [3] | 177 | 
 | 
|---|
 | 178 |     //型を識別
 | 
|---|
| [75] | 179 |     if( !GetVarType(variable,varType,false) ){
 | 
|---|
| [3] | 180 | 
 | 
|---|
 | 181 |         // プロパティ用のメソッドを呼び出す
 | 
|---|
| [75] | 182 |         if(!CallPropertyMethod( variable, Command+i+1, Type() )){
 | 
|---|
| [3] | 183 |             //エラーを表示
 | 
|---|
| [75] | 184 |             GetVarType(variable,varType,true);
 | 
|---|
| [3] | 185 |         }
 | 
|---|
 | 186 | 
 | 
|---|
 | 187 |         return;
 | 
|---|
 | 188 |     }
 | 
|---|
 | 189 | 
 | 
|---|
 | 190 |     //NumOpe...(rax、またはxmm0に答えが格納される)
 | 
|---|
 | 191 |     int reg=REG_RAX;
 | 
|---|
| [75] | 192 |     BOOL bCalcUseHeap;
 | 
|---|
 | 193 |     Type calcType;
 | 
|---|
 | 194 |     if( !NumOpe(®,Command+i+1,varType,calcType,&bCalcUseHeap) ){
 | 
|---|
 | 195 |         return;
 | 
|---|
 | 196 |     }
 | 
|---|
| [3] | 197 | 
 | 
|---|
| [75] | 198 |     if(reg!=REG_RAX&&calcType.IsWhole()||
 | 
|---|
 | 199 |         varType.IsNull()||calcType.IsNull()){
 | 
|---|
| [64] | 200 |         SetError(300,NULL,cp);
 | 
|---|
 | 201 |     }
 | 
|---|
 | 202 | 
 | 
|---|
| [3] | 203 |     //結果を格納しているレジスタをブロッキング
 | 
|---|
 | 204 |     pobj_BlockReg->lock(reg);
 | 
|---|
 | 205 | 
 | 
|---|
 | 206 |     //変数アドレスを取得
 | 
|---|
 | 207 |     RELATIVE_VAR VarRelativeVar;
 | 
|---|
| [370] | 208 |     bool result = GetVarOffsetReadWrite(
 | 
|---|
| [3] | 209 |         variable,
 | 
|---|
 | 210 |         &VarRelativeVar,
 | 
|---|
| [370] | 211 |         varType);
 | 
|---|
| [3] | 212 | 
 | 
|---|
 | 213 |     //レジスタのブロッキングを解除
 | 
|---|
 | 214 |     pobj_BlockReg->clear();
 | 
|---|
 | 215 | 
 | 
|---|
| [370] | 216 |     if( !result )
 | 
|---|
 | 217 |     {
 | 
|---|
 | 218 |         return;
 | 
|---|
 | 219 |     }
 | 
|---|
 | 220 | 
 | 
|---|
| [75] | 221 |     if(varType.GetBasicType()&FLAG_PTR){
 | 
|---|
| [3] | 222 |         SetError(14,variable,cp);
 | 
|---|
 | 223 |         return;
 | 
|---|
 | 224 |     }
 | 
|---|
 | 225 | 
 | 
|---|
| [75] | 226 |     if( varType.IsStruct() ){
 | 
|---|
| [64] | 227 |         //構造体インスタンスへの代入
 | 
|---|
| [75] | 228 |         SetStructVariableFromRax(varType,calcType,&VarRelativeVar,bCalcUseHeap);
 | 
|---|
| [3] | 229 |         return;
 | 
|---|
 | 230 |     }
 | 
|---|
 | 231 | 
 | 
|---|
| [75] | 232 |     if( calcType.IsObject() && !calcType.Equals( varType ) ){
 | 
|---|
| [116] | 233 |         bool isUpCast = false;
 | 
|---|
 | 234 |         if( varType.IsObject() ){
 | 
|---|
 | 235 |             if( varType.GetClass().IsEqualsOrSubClass( &calcType.GetClass() ) ){
 | 
|---|
 | 236 |                 isUpCast = true;
 | 
|---|
 | 237 |             }
 | 
|---|
 | 238 |         }
 | 
|---|
 | 239 |         if( !isUpCast ){
 | 
|---|
 | 240 |             //キャスト演算子のオーバーロードに対応する
 | 
|---|
 | 241 |             CallCastOperatorProc(REG_RAX,calcType,bCalcUseHeap,varType);
 | 
|---|
 | 242 |         }
 | 
|---|
| [3] | 243 |     }
 | 
|---|
 | 244 | 
 | 
|---|
| [266] | 245 |     if( varType.IsObject() && compiler.GetObjectModule().meta.GetBlittableTypes().IsExist( calcType ) ){
 | 
|---|
| [128] | 246 |         // Blittable型をオブジェクトとして扱う
 | 
|---|
| [206] | 247 |         vector<const UserProc *> userProcs;
 | 
|---|
| [266] | 248 |         compiler.GetObjectModule().meta.GetBlittableTypes().GetClass( calcType ).GetStaticMethods().Enum( "_Create", userProcs );
 | 
|---|
| [128] | 249 |         if( userProcs.size() != 1 ){
 | 
|---|
 | 250 |             SetError();
 | 
|---|
 | 251 |             return;
 | 
|---|
 | 252 |         }
 | 
|---|
| [206] | 253 |         const UserProc *pUserProc = userProcs[0];
 | 
|---|
| [3] | 254 | 
 | 
|---|
| [128] | 255 |         // mov rcx, rax
 | 
|---|
| [226] | 256 |         compiler.codeGenerator.op_mov_RR( REG_RCX, REG_RAX );
 | 
|---|
| [128] | 257 | 
 | 
|---|
 | 258 |         // call System.[TypeClass]._Create
 | 
|---|
| [226] | 259 |         compiler.codeGenerator.op_call( pUserProc );
 | 
|---|
| [128] | 260 | 
 | 
|---|
 | 261 |         calcType = pUserProc->ReturnType();
 | 
|---|
 | 262 |     }
 | 
|---|
 | 263 | 
 | 
|---|
| [3] | 264 |     /////////////////////////////////
 | 
|---|
 | 265 |     // 右辺、左辺の型チェックを行う
 | 
|---|
 | 266 |     /////////////////////////////////
 | 
|---|
 | 267 | 
 | 
|---|
| [75] | 268 |     CheckDifferentType(varType,calcType,0,0);
 | 
|---|
| [3] | 269 | 
 | 
|---|
 | 270 | 
 | 
|---|
 | 271 |     /////////////////////////////////////////////////
 | 
|---|
 | 272 |     // rax(実数はxmm0)の内容を変数にコピー
 | 
|---|
 | 273 |     /////////////////////////////////////////////////
 | 
|---|
| [308] | 274 |     SetVariableFromRax(varType,calcType.GetBasicType(),&VarRelativeVar);
 | 
|---|
| [3] | 275 | }
 | 
|---|