| [206] | 1 | #include "stdafx.h"
 | 
|---|
 | 2 | 
 | 
|---|
| [183] | 3 | #include <jenga/include/smoothie/LexicalAnalysis.h>
 | 
|---|
 | 4 | 
 | 
|---|
 | 5 | #include <LexicalScopingImpl.h>
 | 
|---|
 | 6 | #include <Compiler.h>
 | 
|---|
 | 7 | 
 | 
|---|
| [3] | 8 | #include "../BasicCompiler_Common/common.h"
 | 
|---|
 | 9 | #include "Opcode.h"
 | 
|---|
 | 10 | 
 | 
|---|
| [129] | 11 | void OpcodeOthers( const char *Command ){
 | 
|---|
| [3] | 12 |     int i,i2;
 | 
|---|
 | 13 | 
 | 
|---|
| [122] | 14 |     char leftTerm[8192];
 | 
|---|
 | 15 |     int lastParePos = 0;
 | 
|---|
| [3] | 16 |     for(i=0;;i++){
 | 
|---|
| [122] | 17 |         if(Command[i]=='\"'){
 | 
|---|
 | 18 |             //ダブルクォートは不正なのでエラー扱い
 | 
|---|
 | 19 |             leftTerm[i]=0;
 | 
|---|
 | 20 |             SetError(3,leftTerm,cp);
 | 
|---|
 | 21 |             return;
 | 
|---|
 | 22 |         }
 | 
|---|
 | 23 | 
 | 
|---|
 | 24 |         if(Command[i]=='('){
 | 
|---|
 | 25 |             lastParePos = i;
 | 
|---|
 | 26 |             i2=GetStringInPare(leftTerm+i,Command+i);
 | 
|---|
| [3] | 27 |             i+=i2-1;
 | 
|---|
 | 28 |             continue;
 | 
|---|
 | 29 |         }
 | 
|---|
| [122] | 30 |         if(Command[i]=='['){
 | 
|---|
 | 31 |             i2=GetStringInBracket(leftTerm+i,Command+i);
 | 
|---|
 | 32 |             i+=i2-1;
 | 
|---|
| [3] | 33 |             continue;
 | 
|---|
 | 34 |         }
 | 
|---|
| [122] | 35 |         if(Command[i]=='\0'){
 | 
|---|
 | 36 |             leftTerm[i] = 0;
 | 
|---|
| [3] | 37 |             break;
 | 
|---|
 | 38 |         }
 | 
|---|
| [122] | 39 | 
 | 
|---|
 | 40 |         if( IsNumCalcMark( Command, i ) ){
 | 
|---|
 | 41 |             leftTerm[i] = 0;
 | 
|---|
 | 42 |             break;
 | 
|---|
 | 43 |         }
 | 
|---|
 | 44 | 
 | 
|---|
 | 45 |         leftTerm[i]=Command[i];
 | 
|---|
| [3] | 46 |     }
 | 
|---|
 | 47 |     if(!(
 | 
|---|
| [122] | 48 |         IsVariableTopChar(leftTerm[0])||
 | 
|---|
 | 49 |         leftTerm[0]=='.'||
 | 
|---|
 | 50 |         (leftTerm[0]==1&&leftTerm[1]==ESC_PSMEM)
 | 
|---|
| [3] | 51 |         )){
 | 
|---|
 | 52 |         SetError(1,NULL,cp);
 | 
|---|
 | 53 |         return;
 | 
|---|
 | 54 |     }
 | 
|---|
 | 55 | 
 | 
|---|
 | 56 | 
 | 
|---|
| [122] | 57 |     if(Command[i]=='\0' && lastParePos == 0){
 | 
|---|
| [3] | 58 |         //////////////////////////////
 | 
|---|
 | 59 |         // パラメータ無しのマクロ検索
 | 
|---|
 | 60 |         //////////////////////////////
 | 
|---|
 | 61 | 
 | 
|---|
| [206] | 62 |         const UserProc *pUserProc = GetSubHash(Command);
 | 
|---|
| [3] | 63 | 
 | 
|---|
 | 64 |         //GetSubHash内でエラー提示が行われた場合
 | 
|---|
| [75] | 65 |         if(pUserProc==(UserProc *)-1) return;
 | 
|---|
| [3] | 66 | 
 | 
|---|
| [75] | 67 |         if(pUserProc==0){
 | 
|---|
| [3] | 68 |             char temporary[VN_SIZE];
 | 
|---|
 | 69 |             lstrcpy(temporary,Command);
 | 
|---|
 | 70 | 
 | 
|---|
 | 71 |             CharUpper(temporary);
 | 
|---|
| [75] | 72 |             pUserProc=GetSubHash(temporary);
 | 
|---|
| [3] | 73 | 
 | 
|---|
 | 74 |             //GetSubHash内でエラー提示が行われた場合
 | 
|---|
| [75] | 75 |             if(pUserProc==(UserProc *)-1) return;
 | 
|---|
| [3] | 76 |         }
 | 
|---|
 | 77 | 
 | 
|---|
| [75] | 78 |         if(pUserProc){
 | 
|---|
| [122] | 79 |             if( !pUserProc->IsMacro() ){
 | 
|---|
 | 80 |                 SetError(10,Command,cp);
 | 
|---|
 | 81 |             }
 | 
|---|
| [3] | 82 | 
 | 
|---|
| [75] | 83 |             Opcode_CallProc("",pUserProc,0,"",0);
 | 
|---|
| [3] | 84 | 
 | 
|---|
 | 85 |             return;
 | 
|---|
 | 86 |         }
 | 
|---|
 | 87 |     }
 | 
|---|
 | 88 |     else if(IsNumCalcMark(Command,i)){
 | 
|---|
 | 89 |         //代入演算
 | 
|---|
 | 90 |         OpcodeCalc(Command);
 | 
|---|
 | 91 |         return;
 | 
|---|
 | 92 |     }
 | 
|---|
 | 93 | 
 | 
|---|
 | 94 | 
 | 
|---|
| [122] | 95 |     Type resultType;
 | 
|---|
 | 96 |     bool isLiteral;
 | 
|---|
 | 97 |     BOOL bUseHeap;
 | 
|---|
| [128] | 98 |     bool result = TermOpe( leftTerm, Type(), resultType, isLiteral, &bUseHeap, false, NULL, true );
 | 
|---|
| [122] | 99 |     if( result ){
 | 
|---|
| [3] | 100 | 
 | 
|---|
 | 101 |         /////////////////////
 | 
|---|
 | 102 |         // 戻り値の処理
 | 
|---|
 | 103 |         /////////////////////
 | 
|---|
 | 104 | 
 | 
|---|
| [76] | 105 |         if( resultType.IsReal() ){
 | 
|---|
| [3] | 106 |             //fstp st(0)
 | 
|---|
| [236] | 107 |             compiler.codeGenerator.PutOld(
 | 
|---|
 | 108 |                 (char)0xDD,
 | 
|---|
 | 109 |                 (char)0xD8
 | 
|---|
 | 110 |             );
 | 
|---|
| [3] | 111 |         }
 | 
|---|
| [76] | 112 |         else if( resultType.IsStruct() ){
 | 
|---|
| [51] | 113 |             //mov ebx,eax
 | 
|---|
| [225] | 114 |             compiler.codeGenerator.op_mov_RR(REG_EBX,REG_EAX);
 | 
|---|
| [3] | 115 | 
 | 
|---|
| [76] | 116 |             FreeTempObject(REG_EBX,&resultType.GetClass());
 | 
|---|
| [3] | 117 |         }
 | 
|---|
| [122] | 118 | 
 | 
|---|
 | 119 |         //成功
 | 
|---|
| [3] | 120 |         return;
 | 
|---|
 | 121 |     }
 | 
|---|
 | 122 | 
 | 
|---|
| [122] | 123 |     // 失敗
 | 
|---|
 | 124 |     SetError(1, NULL,cp);
 | 
|---|
| [3] | 125 | }
 | 
|---|
 | 126 | 
 | 
|---|
 | 127 | void OpcodeIf(char *Parameter){
 | 
|---|
| [241] | 128 |     int i,i2;
 | 
|---|
| [76] | 129 |     Type tempType;
 | 
|---|
| [3] | 130 | 
 | 
|---|
 | 131 |     for(i=0;;i++){
 | 
|---|
 | 132 |         if(Parameter[i]=='\0'){
 | 
|---|
 | 133 |             SetError(21,NULL,cp);
 | 
|---|
 | 134 |             return;
 | 
|---|
 | 135 |         }
 | 
|---|
 | 136 |         if(Parameter[i]==1&&Parameter[i+1]==ESC_THEN){
 | 
|---|
 | 137 |             Parameter[i]=0;
 | 
|---|
 | 138 |             break;
 | 
|---|
 | 139 |         }
 | 
|---|
 | 140 |     }
 | 
|---|
 | 141 | 
 | 
|---|
| [245] | 142 |     const CodeGenerator::PertialSchedule *pIfPertialSchedule = NULL;
 | 
|---|
| [76] | 143 |     if( !NumOpe(Parameter,Type(),tempType) ){
 | 
|---|
| [3] | 144 |         //NumOpe内でエラー
 | 
|---|
 | 145 |     }
 | 
|---|
| [76] | 146 |     else if( tempType.IsDouble() ){
 | 
|---|
| [3] | 147 |         //fld qword ptr[esp]
 | 
|---|
| [225] | 148 |         compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);
 | 
|---|
| [3] | 149 | 
 | 
|---|
 | 150 |         //push 0
 | 
|---|
| [225] | 151 |         compiler.codeGenerator.op_push_V(0);
 | 
|---|
| [3] | 152 | 
 | 
|---|
 | 153 |         //fild dword ptr[esp]
 | 
|---|
| [225] | 154 |         compiler.codeGenerator.op_fld_ptr_esp(DEF_LONG);
 | 
|---|
| [3] | 155 | 
 | 
|---|
 | 156 |         //add esp,sizeof(double)+sizeof(long)
 | 
|---|
| [225] | 157 |         compiler.codeGenerator.op_add_esp(sizeof(double)+sizeof(long));
 | 
|---|
| [3] | 158 | 
 | 
|---|
 | 159 |         //fcompp
 | 
|---|
| [225] | 160 |         compiler.codeGenerator.op_fcompp();
 | 
|---|
| [3] | 161 | 
 | 
|---|
 | 162 |         //fnstsw ax
 | 
|---|
| [225] | 163 |         compiler.codeGenerator.op_fnstsw_ax();
 | 
|---|
| [3] | 164 | 
 | 
|---|
 | 165 |         //test ah,40
 | 
|---|
| [225] | 166 |         compiler.codeGenerator.op_test_ah( (char)0x40 );
 | 
|---|
| [3] | 167 | 
 | 
|---|
 | 168 |         //jne (endif、または else まで)
 | 
|---|
| [241] | 169 |         pIfPertialSchedule = compiler.codeGenerator.op_jne( 0, sizeof(long), true );
 | 
|---|
| [3] | 170 |     }
 | 
|---|
| [76] | 171 |     else if( tempType.IsSingle() ){
 | 
|---|
| [3] | 172 |         //fld dword ptr[esp]
 | 
|---|
| [225] | 173 |         compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);
 | 
|---|
| [3] | 174 | 
 | 
|---|
 | 175 |         //push 0
 | 
|---|
| [225] | 176 |         compiler.codeGenerator.op_push_V(0);
 | 
|---|
| [3] | 177 | 
 | 
|---|
 | 178 |         //fild dword ptr[esp]
 | 
|---|
| [225] | 179 |         compiler.codeGenerator.op_fld_ptr_esp(DEF_LONG);
 | 
|---|
| [3] | 180 | 
 | 
|---|
 | 181 |         //add esp,sizeof(float)+sizeof(long)
 | 
|---|
| [225] | 182 |         compiler.codeGenerator.op_add_esp(sizeof(float)+sizeof(long));
 | 
|---|
| [3] | 183 | 
 | 
|---|
 | 184 |         //fcompp
 | 
|---|
| [225] | 185 |         compiler.codeGenerator.op_fcompp();
 | 
|---|
| [3] | 186 | 
 | 
|---|
 | 187 |         //fnstsw ax
 | 
|---|
| [225] | 188 |         compiler.codeGenerator.op_fnstsw_ax();
 | 
|---|
| [3] | 189 | 
 | 
|---|
 | 190 |         //test ah,40
 | 
|---|
| [225] | 191 |         compiler.codeGenerator.op_test_ah( (char)0x40 );
 | 
|---|
| [3] | 192 | 
 | 
|---|
 | 193 |         //jne (endif、または else まで)
 | 
|---|
| [241] | 194 |         pIfPertialSchedule = compiler.codeGenerator.op_jne( 0, sizeof(long), true );
 | 
|---|
| [3] | 195 |     }
 | 
|---|
| [76] | 196 |     else if( tempType.Is64() ){
 | 
|---|
| [3] | 197 |         //64ビット型
 | 
|---|
 | 198 | 
 | 
|---|
 | 199 |         //pop eax
 | 
|---|
| [225] | 200 |         compiler.codeGenerator.op_pop(REG_EAX);
 | 
|---|
| [3] | 201 | 
 | 
|---|
 | 202 |         //pop ebx
 | 
|---|
| [225] | 203 |         compiler.codeGenerator.op_pop(REG_EBX);
 | 
|---|
| [3] | 204 | 
 | 
|---|
 | 205 |         //cmp eax,0
 | 
|---|
| [236] | 206 |         compiler.codeGenerator.op_cmp_value( sizeof(long), REG_EAX, 0 );
 | 
|---|
| [3] | 207 | 
 | 
|---|
 | 208 |         //jne
 | 
|---|
| [245] | 209 |         const CodeGenerator::PertialSchedule *pTempPertialSchedule1 = compiler.codeGenerator.op_jne( 0, sizeof(char), true );
 | 
|---|
| [3] | 210 | 
 | 
|---|
 | 211 |         //cmp ebx,0
 | 
|---|
| [236] | 212 |         compiler.codeGenerator.op_cmp_value( sizeof(long), REG_EBX, 0 );
 | 
|---|
| [3] | 213 | 
 | 
|---|
 | 214 |         //jne
 | 
|---|
| [245] | 215 |         const CodeGenerator::PertialSchedule *pTempPertialSchedule2 = compiler.codeGenerator.op_jne( 0, sizeof(char), true );
 | 
|---|
| [3] | 216 | 
 | 
|---|
 | 217 |         //jmp (endif、または else までジャンプ)
 | 
|---|
| [241] | 218 |         pIfPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
 | 
|---|
| [3] | 219 | 
 | 
|---|
| [241] | 220 |         compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule1 );
 | 
|---|
 | 221 |         compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule2 );
 | 
|---|
| [3] | 222 |     }
 | 
|---|
 | 223 |     else{
 | 
|---|
 | 224 |         //32ビット型
 | 
|---|
 | 225 | 
 | 
|---|
 | 226 |         //pop eax
 | 
|---|
| [225] | 227 |         compiler.codeGenerator.op_pop(REG_EAX);
 | 
|---|
| [3] | 228 | 
 | 
|---|
 | 229 |         //cmp eax,0
 | 
|---|
| [236] | 230 |         compiler.codeGenerator.op_cmp_value( sizeof(long), REG_EAX, 0 );
 | 
|---|
| [3] | 231 | 
 | 
|---|
 | 232 |         //je (endif、または else まで条件ジャンプ)
 | 
|---|
| [241] | 233 |         pIfPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
 | 
|---|
| [3] | 234 |     }
 | 
|---|
 | 235 | 
 | 
|---|
 | 236 | 
 | 
|---|
 | 237 |     /////////////////////////
 | 
|---|
 | 238 |     // If内をコード化
 | 
|---|
 | 239 |     /////////////////////////
 | 
|---|
 | 240 | 
 | 
|---|
 | 241 |     //レキシカルスコープをレベルアップ
 | 
|---|
| [183] | 242 |     GetLexicalScopes().Start( obp, SCOPE_TYPE_IF );
 | 
|---|
| [3] | 243 | 
 | 
|---|
 | 244 |     i2=CompileBuffer(ESC_ENDIF,0);
 | 
|---|
 | 245 | 
 | 
|---|
 | 246 |     //レキシカルスコープをレベルダウン
 | 
|---|
| [183] | 247 |     GetLexicalScopes().End();
 | 
|---|
| [3] | 248 | 
 | 
|---|
 | 249 | 
 | 
|---|
| [241] | 250 |     if( pIfPertialSchedule == NULL ) return;
 | 
|---|
| [3] | 251 | 
 | 
|---|
 | 252 |     if(i2==ESC_ELSE){
 | 
|---|
 | 253 |         //jmp (endifまで)
 | 
|---|
| [245] | 254 |         const CodeGenerator::PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
 | 
|---|
| [3] | 255 | 
 | 
|---|
| [241] | 256 |         compiler.codeGenerator.opfix_JmpPertialSchedule( pIfPertialSchedule );
 | 
|---|
| [3] | 257 | 
 | 
|---|
 | 258 | 
 | 
|---|
 | 259 |         /////////////////////////
 | 
|---|
 | 260 |         // Else内をコード化
 | 
|---|
 | 261 |         /////////////////////////
 | 
|---|
 | 262 | 
 | 
|---|
 | 263 |         //レキシカルスコープをレベルアップ
 | 
|---|
| [183] | 264 |         GetLexicalScopes().Start( obp, SCOPE_TYPE_IF );
 | 
|---|
| [3] | 265 | 
 | 
|---|
 | 266 |         CompileBuffer(ESC_ENDIF,0);
 | 
|---|
 | 267 | 
 | 
|---|
 | 268 |         //レキシカルスコープをレベルダウン
 | 
|---|
| [183] | 269 |         GetLexicalScopes().End();
 | 
|---|
| [3] | 270 | 
 | 
|---|
 | 271 | 
 | 
|---|
| [241] | 272 |         compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
 | 
|---|
| [3] | 273 |     }
 | 
|---|
 | 274 |     else{
 | 
|---|
| [241] | 275 |         compiler.codeGenerator.opfix_JmpPertialSchedule( pIfPertialSchedule );
 | 
|---|
| [3] | 276 |     }
 | 
|---|
 | 277 | }
 | 
|---|
 | 278 | 
 | 
|---|
 | 279 | int GetLabelAddress(char *LabelName,int LineNum){
 | 
|---|
 | 280 |     extern int MaxLabelNum;
 | 
|---|
 | 281 |     extern LABEL *pLabelNames;
 | 
|---|
 | 282 |     int i;
 | 
|---|
 | 283 | 
 | 
|---|
 | 284 |     if(LabelName){
 | 
|---|
 | 285 |         for(i=0;i<MaxLabelNum;i++){
 | 
|---|
 | 286 |             if(pLabelNames[i].pName){
 | 
|---|
 | 287 |                 if(lstrcmp(LabelName,pLabelNames[i].pName)==0) return pLabelNames[i].address;
 | 
|---|
 | 288 |             }
 | 
|---|
 | 289 |         }
 | 
|---|
 | 290 |     }
 | 
|---|
 | 291 |     else{
 | 
|---|
 | 292 |         for(i=0;i<MaxLabelNum;i++){
 | 
|---|
 | 293 |             if(pLabelNames[i].pName==0){
 | 
|---|
 | 294 |                 if(LineNum==pLabelNames[i].line) return pLabelNames[i].address;
 | 
|---|
 | 295 |             }
 | 
|---|
 | 296 |         }
 | 
|---|
 | 297 |     }
 | 
|---|
 | 298 |     return -1;
 | 
|---|
 | 299 | }
 | 
|---|
 | 300 | void OpcodeGoto(char *Parameter){
 | 
|---|
 | 301 |     extern HANDLE hHeap;
 | 
|---|
 | 302 |     int i,LineNum;
 | 
|---|
 | 303 | 
 | 
|---|
 | 304 |     if(Parameter[0]=='*'){
 | 
|---|
 | 305 |         i=GetLabelAddress(Parameter+1,0);
 | 
|---|
 | 306 | 
 | 
|---|
| [246] | 307 |         if( i == -1 )
 | 
|---|
 | 308 |         {
 | 
|---|
 | 309 |             //jmp ...(schedule)
 | 
|---|
 | 310 |             compiler.codeGenerator.op_jmp_goto_schedule( GotoLabelSchedule( (const std::string)(Parameter + 1), obp, cp ) );
 | 
|---|
| [3] | 311 |         }
 | 
|---|
| [246] | 312 |         else
 | 
|---|
 | 313 |         {
 | 
|---|
 | 314 |             //jmp ...
 | 
|---|
 | 315 |             compiler.codeGenerator.op_jmp( i-obp, sizeof(long), false, true );
 | 
|---|
 | 316 |         }
 | 
|---|
| [3] | 317 |     }
 | 
|---|
 | 318 |     else{
 | 
|---|
 | 319 |         LineNum=atoi(Parameter);
 | 
|---|
 | 320 |         i=GetLabelAddress(0,LineNum);
 | 
|---|
 | 321 | 
 | 
|---|
| [246] | 322 |         if( i == -1 )
 | 
|---|
 | 323 |         {
 | 
|---|
 | 324 |             //jmp ...(schedule)
 | 
|---|
 | 325 |             compiler.codeGenerator.op_jmp_goto_schedule( GotoLabelSchedule( LineNum, obp, cp ) );
 | 
|---|
| [3] | 326 |         }
 | 
|---|
| [246] | 327 |         else
 | 
|---|
 | 328 |         {
 | 
|---|
 | 329 |             //jmp ...
 | 
|---|
 | 330 |             compiler.codeGenerator.op_jmp( i-obp, sizeof(long), false, true );
 | 
|---|
 | 331 |         }
 | 
|---|
| [3] | 332 |     }
 | 
|---|
 | 333 | }
 | 
|---|
 | 334 | void OpcodeWhile(char *Parameter){
 | 
|---|
 | 335 |     extern HANDLE hHeap;
 | 
|---|
 | 336 | 
 | 
|---|
 | 337 |     //Continueアドレスのバックアップとセット
 | 
|---|
| [241] | 338 |     compiler.codeGenerator.ContinueAreaBegin();
 | 
|---|
| [3] | 339 | 
 | 
|---|
 | 340 |     if(!Parameter[0]) SetError(10,"While",cp);
 | 
|---|
 | 341 | 
 | 
|---|
| [245] | 342 |     const CodeGenerator::PertialSchedule *pWhilePertialSchedule = NULL;
 | 
|---|
| [76] | 343 |     Type tempType;
 | 
|---|
 | 344 |     if( !NumOpe(Parameter,Type(),tempType) ){
 | 
|---|
 | 345 |         //ダミー
 | 
|---|
 | 346 |     }
 | 
|---|
 | 347 |     else if( tempType.IsDouble() ){
 | 
|---|
| [3] | 348 |         //fld qword ptr[esp]
 | 
|---|
| [225] | 349 |         compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);
 | 
|---|
| [3] | 350 | 
 | 
|---|
 | 351 |         //push 0
 | 
|---|
| [225] | 352 |         compiler.codeGenerator.op_push_V(0);
 | 
|---|
| [3] | 353 | 
 | 
|---|
 | 354 |         //fild dword ptr[esp]
 | 
|---|
| [225] | 355 |         compiler.codeGenerator.op_fld_ptr_esp(DEF_LONG);
 | 
|---|
| [3] | 356 | 
 | 
|---|
 | 357 |         //add esp,sizeof(double)+sizeof(long)
 | 
|---|
| [225] | 358 |         compiler.codeGenerator.op_add_esp(sizeof(double)+sizeof(long));
 | 
|---|
| [3] | 359 | 
 | 
|---|
 | 360 |         //fcompp
 | 
|---|
| [225] | 361 |         compiler.codeGenerator.op_fcompp();
 | 
|---|
| [3] | 362 | 
 | 
|---|
 | 363 |         //fnstsw ax
 | 
|---|
| [225] | 364 |         compiler.codeGenerator.op_fnstsw_ax();
 | 
|---|
| [3] | 365 | 
 | 
|---|
 | 366 |         //test ah,40
 | 
|---|
| [225] | 367 |         compiler.codeGenerator.op_test_ah( (char)0x40 );
 | 
|---|
| [3] | 368 | 
 | 
|---|
 | 369 |         //jne (Wend まで)
 | 
|---|
| [241] | 370 |         pWhilePertialSchedule = compiler.codeGenerator.op_jne( 0, sizeof(long), true );
 | 
|---|
| [3] | 371 |     }
 | 
|---|
| [76] | 372 |     else if( tempType.IsSingle() ){
 | 
|---|
| [3] | 373 |         //fld dword ptr[esp]
 | 
|---|
| [225] | 374 |         compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);
 | 
|---|
| [3] | 375 | 
 | 
|---|
 | 376 |         //push 0
 | 
|---|
| [225] | 377 |         compiler.codeGenerator.op_push_V(0);
 | 
|---|
| [3] | 378 | 
 | 
|---|
 | 379 |         //fild dword ptr[esp]
 | 
|---|
| [225] | 380 |         compiler.codeGenerator.op_fld_ptr_esp(DEF_LONG);
 | 
|---|
| [3] | 381 | 
 | 
|---|
 | 382 |         //add esp,sizeof(float)+sizeof(long)
 | 
|---|
| [225] | 383 |         compiler.codeGenerator.op_add_esp(sizeof(float)+sizeof(long));
 | 
|---|
| [3] | 384 | 
 | 
|---|
 | 385 |         //fcompp
 | 
|---|
| [225] | 386 |         compiler.codeGenerator.op_fcompp();
 | 
|---|
| [3] | 387 | 
 | 
|---|
 | 388 |         //fnstsw ax
 | 
|---|
| [225] | 389 |         compiler.codeGenerator.op_fnstsw_ax();
 | 
|---|
| [3] | 390 | 
 | 
|---|
| [241] | 391 |         //test ah,40h
 | 
|---|
| [225] | 392 |         compiler.codeGenerator.op_test_ah( (char)0x40 );
 | 
|---|
| [3] | 393 | 
 | 
|---|
 | 394 |         //jne (Wend まで)
 | 
|---|
| [241] | 395 |         pWhilePertialSchedule = compiler.codeGenerator.op_jne( 0, sizeof(long), true );
 | 
|---|
| [3] | 396 |     }
 | 
|---|
| [76] | 397 |     else if( tempType.Is64() ){
 | 
|---|
| [3] | 398 |         //64ビット型
 | 
|---|
 | 399 | 
 | 
|---|
 | 400 |         //pop eax
 | 
|---|
| [225] | 401 |         compiler.codeGenerator.op_pop(REG_EAX);
 | 
|---|
| [3] | 402 | 
 | 
|---|
 | 403 |         //pop ebx
 | 
|---|
| [225] | 404 |         compiler.codeGenerator.op_pop(REG_EBX);
 | 
|---|
| [3] | 405 | 
 | 
|---|
 | 406 |         //cmp eax,0
 | 
|---|
| [236] | 407 |         compiler.codeGenerator.op_cmp_value( sizeof(long), REG_EAX, 0 );
 | 
|---|
| [3] | 408 | 
 | 
|---|
 | 409 |         //jne
 | 
|---|
| [245] | 410 |         const CodeGenerator::PertialSchedule *pTempPertialSchedule1 = compiler.codeGenerator.op_jne( 0, sizeof(char), true );
 | 
|---|
| [3] | 411 | 
 | 
|---|
 | 412 |         //cmp ebx,0
 | 
|---|
| [236] | 413 |         compiler.codeGenerator.op_cmp_value( sizeof(long), REG_EBX, 0 );
 | 
|---|
| [3] | 414 | 
 | 
|---|
 | 415 |         //jne
 | 
|---|
| [245] | 416 |         const CodeGenerator::PertialSchedule *pTempPertialSchedule2 = compiler.codeGenerator.op_jne( 0, sizeof(char), true );
 | 
|---|
| [3] | 417 | 
 | 
|---|
| [241] | 418 |         //jmp (Wendまでジャンプ)
 | 
|---|
 | 419 |         pWhilePertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
 | 
|---|
| [3] | 420 | 
 | 
|---|
| [241] | 421 |         compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule1 );
 | 
|---|
 | 422 |         compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule2 );
 | 
|---|
| [3] | 423 |     }
 | 
|---|
 | 424 |     else{
 | 
|---|
 | 425 |         //その他整数型
 | 
|---|
 | 426 | 
 | 
|---|
 | 427 |         //pop eax
 | 
|---|
| [225] | 428 |         compiler.codeGenerator.op_pop(REG_EAX);
 | 
|---|
| [3] | 429 | 
 | 
|---|
 | 430 |         //cmp eax,0
 | 
|---|
| [236] | 431 |         compiler.codeGenerator.op_cmp_value( sizeof(long), REG_EAX, 0 );
 | 
|---|
| [3] | 432 | 
 | 
|---|
 | 433 |         //je (Wend まで)
 | 
|---|
| [241] | 434 |         pWhilePertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
 | 
|---|
| [3] | 435 |     }
 | 
|---|
 | 436 | 
 | 
|---|
 | 437 |     //レキシカルスコープをレベルアップ
 | 
|---|
| [183] | 438 |     GetLexicalScopes().Start( obp, SCOPE_TYPE_WHILE );
 | 
|---|
| [3] | 439 | 
 | 
|---|
 | 440 |     //While内をコンパイル
 | 
|---|
 | 441 |     CompileBuffer(0,COM_WEND);
 | 
|---|
 | 442 | 
 | 
|---|
| [183] | 443 |     GetLexicalScopes().CallDestructorsOfScopeEnd();
 | 
|---|
| [3] | 444 | 
 | 
|---|
 | 445 |     //jmp ...
 | 
|---|
| [241] | 446 |     compiler.codeGenerator.op_jmp_continue();
 | 
|---|
| [3] | 447 | 
 | 
|---|
 | 448 |     //レキシカルスコープをレベルダウン
 | 
|---|
| [183] | 449 |     GetLexicalScopes().End();
 | 
|---|
| [3] | 450 | 
 | 
|---|
| [241] | 451 |     if( pWhilePertialSchedule )
 | 
|---|
 | 452 |     {
 | 
|---|
 | 453 |         compiler.codeGenerator.opfix_JmpPertialSchedule( pWhilePertialSchedule );
 | 
|---|
 | 454 |     }
 | 
|---|
| [3] | 455 | 
 | 
|---|
| [241] | 456 |     compiler.codeGenerator.ContinueAreaEnd();
 | 
|---|
| [3] | 457 | }
 | 
|---|
 | 458 | 
 | 
|---|
 | 459 | char szNextVariable[VN_SIZE];
 | 
|---|
 | 460 | void OpcodeFor(char *Parameter){
 | 
|---|
 | 461 |     extern HANDLE hHeap;
 | 
|---|
| [241] | 462 |     int i,i2;
 | 
|---|
| [3] | 463 |     char temporary[VN_SIZE],variable[VN_SIZE],JudgeNum[VN_SIZE],StepNum[VN_SIZE];
 | 
|---|
 | 464 | 
 | 
|---|
 | 465 |     //第1パラメータを取得
 | 
|---|
 | 466 |     i=GetOneParameter(Parameter,0,temporary);
 | 
|---|
 | 467 |     if(!Parameter[i]){
 | 
|---|
 | 468 |         SetError(12,"For",cp);
 | 
|---|
 | 469 |         goto ErrorStep;
 | 
|---|
 | 470 |     }
 | 
|---|
 | 471 | 
 | 
|---|
 | 472 |     for(i2=0;;i2++){
 | 
|---|
 | 473 |         if(temporary[i2]=='='){
 | 
|---|
 | 474 |             variable[i2]=0;
 | 
|---|
 | 475 | 
 | 
|---|
 | 476 |             //カウンタ初期化
 | 
|---|
 | 477 |             OpcodeCalc(temporary);
 | 
|---|
 | 478 |             break;
 | 
|---|
 | 479 |         }
 | 
|---|
 | 480 |         if(temporary[i2]=='\0'){
 | 
|---|
 | 481 |             SetError(12,"For",cp);
 | 
|---|
 | 482 |             goto ErrorStep;
 | 
|---|
 | 483 |         }
 | 
|---|
 | 484 |         variable[i2]=temporary[i2];
 | 
|---|
 | 485 |     }
 | 
|---|
 | 486 | 
 | 
|---|
 | 487 |     //jmp ...
 | 
|---|
| [245] | 488 |     const CodeGenerator::PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
 | 
|---|
| [3] | 489 | 
 | 
|---|
 | 490 |     //Continueアドレスのバックアップとセット
 | 
|---|
| [241] | 491 |     compiler.codeGenerator.ContinueAreaBegin();
 | 
|---|
| [3] | 492 | 
 | 
|---|
 | 493 |     //第2パラメータを取得(to~)
 | 
|---|
 | 494 |     i=GetOneParameter(Parameter,i,JudgeNum);
 | 
|---|
 | 495 | 
 | 
|---|
 | 496 |     //第3パラメータを取得(step~)
 | 
|---|
 | 497 |     if(Parameter[i]){
 | 
|---|
 | 498 |         i=GetOneParameter(Parameter,i,StepNum);
 | 
|---|
 | 499 |         if(Parameter[i]) SetError(12,"For",cp);
 | 
|---|
 | 500 |     }
 | 
|---|
 | 501 |     else lstrcpy(StepNum,"1");
 | 
|---|
 | 502 | 
 | 
|---|
 | 503 |     //カウンタを増加させる
 | 
|---|
 | 504 |     sprintf(temporary,"%s=(%s)+(%s)",variable,variable,StepNum);
 | 
|---|
 | 505 |     OpcodeCalc(temporary);
 | 
|---|
 | 506 | 
 | 
|---|
| [241] | 507 |     compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
 | 
|---|
| [3] | 508 | 
 | 
|---|
 | 509 |     //増加か減少かを区別する
 | 
|---|
 | 510 |     sprintf(temporary,"(%s)>=0",StepNum);
 | 
|---|
| [76] | 511 |     NumOpe(temporary,Type(),Type());
 | 
|---|
| [3] | 512 | 
 | 
|---|
 | 513 |     //pop eax
 | 
|---|
| [225] | 514 |     compiler.codeGenerator.op_pop(REG_EAX);
 | 
|---|
| [3] | 515 | 
 | 
|---|
 | 516 |     //cmp eax,0
 | 
|---|
| [236] | 517 |     compiler.codeGenerator.op_cmp_value( sizeof(long), REG_EAX, 0 );
 | 
|---|
| [3] | 518 | 
 | 
|---|
 | 519 |     //je [カウンタ減少の場合の判定]
 | 
|---|
| [241] | 520 |     pTempPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
 | 
|---|
| [3] | 521 | 
 | 
|---|
 | 522 |     //判定(カウンタ増加の場合)
 | 
|---|
 | 523 |     sprintf(temporary,"%s<=(%s)",variable,JudgeNum);
 | 
|---|
| [76] | 524 |     NumOpe(temporary,Type(),Type());
 | 
|---|
| [3] | 525 | 
 | 
|---|
 | 526 |     //pop eax
 | 
|---|
| [225] | 527 |     compiler.codeGenerator.op_pop(REG_EAX);
 | 
|---|
| [3] | 528 | 
 | 
|---|
 | 529 |     //jmp [カウンタ減少の場合の判定を飛び越す]
 | 
|---|
| [245] | 530 |     const CodeGenerator::PertialSchedule *pTempPertialSchedule2 = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
 | 
|---|
| [3] | 531 | 
 | 
|---|
| [241] | 532 |     //jeジャンプ先のオフセット値
 | 
|---|
 | 533 |     compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
 | 
|---|
| [3] | 534 | 
 | 
|---|
 | 535 |     //判定(カウンタ減少の場合)
 | 
|---|
 | 536 |     sprintf(temporary,"%s>=(%s)",variable,JudgeNum);
 | 
|---|
| [76] | 537 |     NumOpe(temporary,Type(),Type());
 | 
|---|
| [3] | 538 | 
 | 
|---|
 | 539 |     //pop eax
 | 
|---|
| [225] | 540 |     compiler.codeGenerator.op_pop(REG_EAX);
 | 
|---|
| [3] | 541 | 
 | 
|---|
| [241] | 542 |     //jmpジャンプ先のオフセット値
 | 
|---|
 | 543 |     compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule2 );
 | 
|---|
| [3] | 544 | 
 | 
|---|
 | 545 |     //cmp eax,0
 | 
|---|
| [236] | 546 |     compiler.codeGenerator.op_cmp_value( sizeof(long), REG_EAX, 0 );
 | 
|---|
| [3] | 547 | 
 | 
|---|
 | 548 | ErrorStep:
 | 
|---|
 | 549 | 
 | 
|---|
 | 550 |     //je ...
 | 
|---|
| [241] | 551 |     pTempPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
 | 
|---|
| [3] | 552 | 
 | 
|---|
 | 553 |     //レキシカルスコープをレベルアップ
 | 
|---|
| [183] | 554 |     GetLexicalScopes().Start( obp, SCOPE_TYPE_FOR );
 | 
|---|
| [3] | 555 | 
 | 
|---|
 | 556 |     //For内をコンパイル
 | 
|---|
 | 557 |     CompileBuffer(0,COM_NEXT);
 | 
|---|
 | 558 | 
 | 
|---|
| [183] | 559 |     GetLexicalScopes().CallDestructorsOfScopeEnd();
 | 
|---|
| [3] | 560 | 
 | 
|---|
 | 561 |     if(szNextVariable[0]){
 | 
|---|
 | 562 |         if(lstrcmp(szNextVariable,variable)!=0){
 | 
|---|
 | 563 |             SetError(55,szNextVariable,cp);
 | 
|---|
 | 564 |         }
 | 
|---|
 | 565 |     }
 | 
|---|
 | 566 | 
 | 
|---|
 | 567 |     //jmp ...
 | 
|---|
| [241] | 568 |     compiler.codeGenerator.op_jmp_continue();
 | 
|---|
| [3] | 569 | 
 | 
|---|
 | 570 |     //レキシカルスコープをレベルダウン
 | 
|---|
| [183] | 571 |     GetLexicalScopes().End();
 | 
|---|
| [3] | 572 | 
 | 
|---|
| [241] | 573 |     //jeジャンプ先のオフセット値
 | 
|---|
 | 574 |     compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
 | 
|---|
| [3] | 575 | 
 | 
|---|
 | 576 |     //Continueアドレスを復元
 | 
|---|
| [241] | 577 |     compiler.codeGenerator.ContinueAreaEnd();
 | 
|---|
| [3] | 578 | }
 | 
|---|
 | 579 | 
 | 
|---|
 | 580 | void OpcodeDo(char *Parameter){
 | 
|---|
 | 581 |     extern HANDLE hHeap;
 | 
|---|
| [76] | 582 |     int i,i2,i3,i4;
 | 
|---|
| [3] | 583 | 
 | 
|---|
 | 584 |     if(Parameter[0]) SetError(10,"Do",cp);
 | 
|---|
 | 585 | 
 | 
|---|
 | 586 |     //Continueアドレスのバックアップとセット
 | 
|---|
| [241] | 587 |     compiler.codeGenerator.ContinueAreaBegin();
 | 
|---|
| [3] | 588 | 
 | 
|---|
 | 589 |     //レキシカルスコープをレベルアップ
 | 
|---|
| [183] | 590 |     GetLexicalScopes().Start( obp, SCOPE_TYPE_DO );
 | 
|---|
| [3] | 591 | 
 | 
|---|
 | 592 |     //Do内をコンパイル
 | 
|---|
 | 593 |     CompileBuffer(0,COM_LOOP);
 | 
|---|
 | 594 | 
 | 
|---|
| [183] | 595 |     GetLexicalScopes().CallDestructorsOfScopeEnd();
 | 
|---|
| [3] | 596 | 
 | 
|---|
| [245] | 597 |     const CodeGenerator::PertialSchedule *pDoPertialSchedule = NULL;
 | 
|---|
| [241] | 598 | 
 | 
|---|
| [3] | 599 |     extern char *basbuf;
 | 
|---|
 | 600 |     char temporary[VN_SIZE];
 | 
|---|
 | 601 |     for(i=cp-1;;i--){
 | 
|---|
 | 602 |         if(IsCommandDelimitation(basbuf[i])){
 | 
|---|
 | 603 |             i+=3;
 | 
|---|
 | 604 |             if(!(basbuf[i]=='0'||basbuf[i]=='1')){
 | 
|---|
 | 605 |                 //無条件ループ
 | 
|---|
 | 606 |                 break;
 | 
|---|
 | 607 |             }
 | 
|---|
 | 608 |             i3=i;
 | 
|---|
 | 609 | 
 | 
|---|
 | 610 |             for(i+=2,i2=0;;i++,i2++){
 | 
|---|
 | 611 |                 if(IsCommandDelimitation(basbuf[i])){
 | 
|---|
 | 612 |                     temporary[i2]=0;
 | 
|---|
 | 613 |                     break;
 | 
|---|
 | 614 |                 }
 | 
|---|
 | 615 |                 temporary[i2]=basbuf[i];
 | 
|---|
 | 616 |             }
 | 
|---|
 | 617 | 
 | 
|---|
| [76] | 618 |             Type tempType;
 | 
|---|
 | 619 |             NumOpe(temporary,Type(),tempType);
 | 
|---|
| [3] | 620 | 
 | 
|---|
| [76] | 621 |             if( tempType.IsDouble() ){
 | 
|---|
| [3] | 622 |                 //fld qword ptr[esp]
 | 
|---|
| [225] | 623 |                 compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);
 | 
|---|
| [3] | 624 | 
 | 
|---|
 | 625 |                 //push 0
 | 
|---|
| [225] | 626 |                 compiler.codeGenerator.op_push_V(0);
 | 
|---|
| [3] | 627 | 
 | 
|---|
 | 628 |                 //fild dword ptr[esp]
 | 
|---|
| [225] | 629 |                 compiler.codeGenerator.op_fld_ptr_esp(DEF_LONG);
 | 
|---|
| [3] | 630 | 
 | 
|---|
 | 631 |                 //add esp,sizeof(double)+sizeof(long)
 | 
|---|
| [225] | 632 |                 compiler.codeGenerator.op_add_esp(sizeof(double)+sizeof(long));
 | 
|---|
| [3] | 633 | 
 | 
|---|
 | 634 |                 //fcompp
 | 
|---|
| [225] | 635 |                 compiler.codeGenerator.op_fcompp();
 | 
|---|
| [3] | 636 | 
 | 
|---|
 | 637 |                 //fnstsw ax
 | 
|---|
| [225] | 638 |                 compiler.codeGenerator.op_fnstsw_ax();
 | 
|---|
| [3] | 639 | 
 | 
|---|
 | 640 |                 //test ah,40
 | 
|---|
| [225] | 641 |                 compiler.codeGenerator.op_test_ah( (char)0x40 );
 | 
|---|
| [3] | 642 | 
 | 
|---|
 | 643 |                 if(basbuf[i3]=='0'){
 | 
|---|
 | 644 |                     //While
 | 
|---|
 | 645 | 
 | 
|---|
 | 646 |                     //jne 5(ループ終了)
 | 
|---|
| [241] | 647 |                     pDoPertialSchedule = compiler.codeGenerator.op_jne( 0, sizeof(char), true );
 | 
|---|
| [3] | 648 |                 }
 | 
|---|
 | 649 |                 else if(basbuf[i3]=='1'){
 | 
|---|
 | 650 |                     //Until
 | 
|---|
 | 651 | 
 | 
|---|
 | 652 |                     //je 5(ループ終了)
 | 
|---|
| [241] | 653 |                     pDoPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(char), true );
 | 
|---|
| [3] | 654 |                 }
 | 
|---|
 | 655 |             }
 | 
|---|
| [76] | 656 |             else if( tempType.IsSingle() ){
 | 
|---|
| [3] | 657 |                 //fld dword ptr[esp]
 | 
|---|
| [225] | 658 |                 compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);
 | 
|---|
| [3] | 659 | 
 | 
|---|
 | 660 |                 //push 0
 | 
|---|
| [225] | 661 |                 compiler.codeGenerator.op_push_V(0);
 | 
|---|
| [3] | 662 | 
 | 
|---|
 | 663 |                 //fild dword ptr[esp]
 | 
|---|
| [225] | 664 |                 compiler.codeGenerator.op_fld_ptr_esp(DEF_LONG);
 | 
|---|
| [3] | 665 | 
 | 
|---|
 | 666 |                 //add esp,sizeof(float)+sizeof(long)
 | 
|---|
| [225] | 667 |                 compiler.codeGenerator.op_add_esp(sizeof(float)+sizeof(long));
 | 
|---|
| [3] | 668 | 
 | 
|---|
 | 669 |                 //fcompp
 | 
|---|
| [225] | 670 |                 compiler.codeGenerator.op_fcompp();
 | 
|---|
| [3] | 671 | 
 | 
|---|
 | 672 |                 //fnstsw ax
 | 
|---|
| [225] | 673 |                 compiler.codeGenerator.op_fnstsw_ax();
 | 
|---|
| [3] | 674 | 
 | 
|---|
 | 675 |                 //test ah,40
 | 
|---|
| [225] | 676 |                 compiler.codeGenerator.op_test_ah( (char)0x40 );
 | 
|---|
| [3] | 677 | 
 | 
|---|
 | 678 |                 if(basbuf[i3]=='0'){
 | 
|---|
 | 679 |                     //While
 | 
|---|
 | 680 | 
 | 
|---|
 | 681 |                     //jne 5(ループ終了)
 | 
|---|
| [241] | 682 |                     pDoPertialSchedule = compiler.codeGenerator.op_jne( 0, sizeof(char), true );
 | 
|---|
| [3] | 683 |                 }
 | 
|---|
 | 684 |                 else if(basbuf[i3]=='1'){
 | 
|---|
 | 685 |                     //Until
 | 
|---|
 | 686 | 
 | 
|---|
 | 687 |                     //je 5(ループ終了)
 | 
|---|
| [241] | 688 |                     pDoPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(char), true );
 | 
|---|
| [3] | 689 |                 }
 | 
|---|
 | 690 |             }
 | 
|---|
| [76] | 691 |             else if( tempType.Is64() ){
 | 
|---|
| [3] | 692 |                 //64ビット型
 | 
|---|
 | 693 | 
 | 
|---|
 | 694 |                 //pop eax
 | 
|---|
| [225] | 695 |                 compiler.codeGenerator.op_pop(REG_EAX);
 | 
|---|
| [3] | 696 | 
 | 
|---|
 | 697 |                 //pop ebx
 | 
|---|
| [225] | 698 |                 compiler.codeGenerator.op_pop(REG_EBX);
 | 
|---|
| [3] | 699 | 
 | 
|---|
 | 700 |                 //cmp eax,0
 | 
|---|
| [236] | 701 |                 compiler.codeGenerator.op_cmp_value( sizeof(long), REG_EAX, 0 );
 | 
|---|
| [3] | 702 | 
 | 
|---|
 | 703 |                 //jne
 | 
|---|
 | 704 |                 OpBuffer[obp++]=(char)0x0F;
 | 
|---|
 | 705 |                 OpBuffer[obp++]=(char)0x85;
 | 
|---|
 | 706 |                 obp+=sizeof(long);
 | 
|---|
 | 707 |                 i2=obp;
 | 
|---|
 | 708 | 
 | 
|---|
 | 709 | 
 | 
|---|
 | 710 |                 //cmp ebx,0
 | 
|---|
| [236] | 711 |                 compiler.codeGenerator.op_cmp_value( sizeof(long), REG_EBX, 0 );
 | 
|---|
| [3] | 712 | 
 | 
|---|
 | 713 |                 //jne
 | 
|---|
 | 714 |                 OpBuffer[obp++]=(char)0x0F;
 | 
|---|
 | 715 |                 OpBuffer[obp++]=(char)0x85;
 | 
|---|
 | 716 |                 obp+=sizeof(long);
 | 
|---|
 | 717 |                 i4=obp;
 | 
|---|
 | 718 | 
 | 
|---|
 | 719 | 
 | 
|---|
 | 720 |                 if(basbuf[i3]=='0'){
 | 
|---|
 | 721 |                     //While
 | 
|---|
 | 722 | 
 | 
|---|
 | 723 |                     //jmp 5(ループ終了)
 | 
|---|
| [241] | 724 |                     pDoPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(char), true );
 | 
|---|
| [3] | 725 | 
 | 
|---|
 | 726 |                     *((long *)(OpBuffer+i2-sizeof(long)))=obp-i2;
 | 
|---|
 | 727 |                     *((long *)(OpBuffer+i4-sizeof(long)))=obp-i4;
 | 
|---|
 | 728 |                 }
 | 
|---|
 | 729 |                 else if(basbuf[i3]=='1'){
 | 
|---|
 | 730 |                     //Until
 | 
|---|
 | 731 | 
 | 
|---|
 | 732 |                     //jmp 2(ループを続ける)
 | 
|---|
 | 733 |                     OpBuffer[obp++]=(char)0xEB;
 | 
|---|
 | 734 |                     OpBuffer[obp++]=(char)0x02;
 | 
|---|
 | 735 | 
 | 
|---|
 | 736 |                     *((long *)(OpBuffer+i2-sizeof(long)))=obp-i2;
 | 
|---|
 | 737 |                     *((long *)(OpBuffer+i4-sizeof(long)))=obp-i4;
 | 
|---|
 | 738 | 
 | 
|---|
 | 739 |                     //jmp 5(ループ終了)
 | 
|---|
| [241] | 740 |                     pDoPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(char), true );
 | 
|---|
| [3] | 741 |                 }
 | 
|---|
 | 742 |             }
 | 
|---|
 | 743 |             else{
 | 
|---|
 | 744 |                 //pop eax
 | 
|---|
| [225] | 745 |                 compiler.codeGenerator.op_pop(REG_EAX);
 | 
|---|
| [3] | 746 | 
 | 
|---|
 | 747 |                 //cmp eax,0
 | 
|---|
| [236] | 748 |                 compiler.codeGenerator.op_cmp_value( sizeof(long), REG_EAX, 0 );
 | 
|---|
| [3] | 749 | 
 | 
|---|
 | 750 |                 if(basbuf[i3]=='0'){
 | 
|---|
 | 751 |                     //While
 | 
|---|
 | 752 | 
 | 
|---|
 | 753 |                     //je 5(ループ終了)
 | 
|---|
| [241] | 754 |                     pDoPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(char), true );
 | 
|---|
| [3] | 755 |                 }
 | 
|---|
 | 756 |                 else if(basbuf[i3]=='1'){
 | 
|---|
 | 757 |                     //Until
 | 
|---|
 | 758 | 
 | 
|---|
 | 759 |                     //jne 5(ループ終了)
 | 
|---|
| [241] | 760 |                     pDoPertialSchedule = compiler.codeGenerator.op_jne( 0, sizeof(char), true );
 | 
|---|
| [3] | 761 |                 }
 | 
|---|
 | 762 |             }
 | 
|---|
 | 763 |             break;
 | 
|---|
 | 764 |         }
 | 
|---|
 | 765 |     }
 | 
|---|
 | 766 | 
 | 
|---|
 | 767 |     //jmp ...
 | 
|---|
| [241] | 768 |     compiler.codeGenerator.op_jmp_continue();
 | 
|---|
| [3] | 769 | 
 | 
|---|
| [241] | 770 |     if( pDoPertialSchedule )
 | 
|---|
 | 771 |     {
 | 
|---|
 | 772 |         compiler.codeGenerator.opfix_JmpPertialSchedule( pDoPertialSchedule );
 | 
|---|
 | 773 |     }
 | 
|---|
 | 774 | 
 | 
|---|
| [3] | 775 |     //jmp ...
 | 
|---|
| [245] | 776 |     const CodeGenerator::PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
 | 
|---|
| [3] | 777 | 
 | 
|---|
 | 778 |     //レキシカルスコープをレベルダウン
 | 
|---|
| [183] | 779 |     GetLexicalScopes().End();
 | 
|---|
| [3] | 780 | 
 | 
|---|
| [243] | 781 |     //jmpジャンプ先のオフセット値
 | 
|---|
 | 782 |     compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
 | 
|---|
| [3] | 783 | 
 | 
|---|
 | 784 |     //Continueアドレスを復元
 | 
|---|
| [241] | 785 |     compiler.codeGenerator.ContinueAreaEnd();
 | 
|---|
| [3] | 786 | }
 | 
|---|
 | 787 | void OpcodeContinue(void){
 | 
|---|
 | 788 |     //jmp ...(Continue addr)
 | 
|---|
| [241] | 789 |     compiler.codeGenerator.op_jmp_continue();
 | 
|---|
| [3] | 790 | }
 | 
|---|
 | 791 | 
 | 
|---|
 | 792 | void OpcodeExitSub(void){
 | 
|---|
 | 793 |     extern DWORD *pExitSubSchedule;
 | 
|---|
 | 794 |     extern int ExitSubScheduleNum;
 | 
|---|
 | 795 |     extern HANDLE hHeap;
 | 
|---|
 | 796 | 
 | 
|---|
| [76] | 797 |     if( UserProc::IsGlobalAreaCompiling() ){
 | 
|---|
| [3] | 798 |         SetError(12,"Exit Sub/Function",cp);
 | 
|---|
 | 799 |         return;
 | 
|---|
 | 800 |     }
 | 
|---|
 | 801 | 
 | 
|---|
| [34] | 802 |     //未解放のローカルオブジェクトのデストラクタを呼び出す
 | 
|---|
| [183] | 803 |     GetLexicalScopes().CallDestructorsOfReturn();
 | 
|---|
| [34] | 804 | 
 | 
|---|
| [3] | 805 |     //jmp ...(End Sub/Function)
 | 
|---|
 | 806 |     OpBuffer[obp++]=(char)0xE9;
 | 
|---|
 | 807 | 
 | 
|---|
 | 808 |     pExitSubSchedule=(DWORD *)HeapReAlloc(hHeap,0,pExitSubSchedule,(ExitSubScheduleNum+1)*sizeof(DWORD));
 | 
|---|
 | 809 |     pExitSubSchedule[ExitSubScheduleNum]=obp;
 | 
|---|
 | 810 |     ExitSubScheduleNum++;
 | 
|---|
 | 811 | 
 | 
|---|
 | 812 |     obp+=sizeof(long);
 | 
|---|
 | 813 | }
 | 
|---|
 | 814 | 
 | 
|---|
 | 815 | void AddCaseSchedule(void){
 | 
|---|
 | 816 |     extern DWORD *pCaseSchedule;
 | 
|---|
 | 817 |     extern int CaseScheduleNum;
 | 
|---|
 | 818 |     extern HANDLE hHeap;
 | 
|---|
 | 819 | 
 | 
|---|
 | 820 |     pCaseSchedule=(DWORD *)HeapReAlloc(hHeap,0,pCaseSchedule,(CaseScheduleNum+1)*sizeof(DWORD));
 | 
|---|
 | 821 |     pCaseSchedule[CaseScheduleNum]=obp;
 | 
|---|
 | 822 |     CaseScheduleNum++;
 | 
|---|
 | 823 | }
 | 
|---|
 | 824 | 
 | 
|---|
 | 825 | int CaseTypeSize;
 | 
|---|
| [76] | 826 | void OpcodeSelect(const char *lpszParms){
 | 
|---|
| [3] | 827 |     extern DWORD *pCaseSchedule;
 | 
|---|
 | 828 |     extern int CaseScheduleNum;
 | 
|---|
 | 829 |     extern int NowCaseSchedule;
 | 
|---|
 | 830 |     extern int CaseTypeSize;
 | 
|---|
 | 831 |     extern HANDLE hHeap;
 | 
|---|
 | 832 |     extern char *basbuf;
 | 
|---|
| [76] | 833 |     int i,i2,i3,sw,NowCaseCp;
 | 
|---|
| [3] | 834 |     char temporary[VN_SIZE];
 | 
|---|
 | 835 | 
 | 
|---|
 | 836 |     DWORD *temp_pCaseSchedule;
 | 
|---|
 | 837 |     int temp_CaseScheduleNum;
 | 
|---|
 | 838 |     int temp_NowCaseSchedule;
 | 
|---|
 | 839 |     int temp_CaseTypeSize;
 | 
|---|
 | 840 | 
 | 
|---|
 | 841 |     temp_pCaseSchedule=pCaseSchedule;
 | 
|---|
 | 842 |     temp_CaseScheduleNum=CaseScheduleNum;
 | 
|---|
 | 843 |     temp_NowCaseSchedule=NowCaseSchedule;
 | 
|---|
 | 844 |     temp_CaseTypeSize=CaseTypeSize;
 | 
|---|
 | 845 |     pCaseSchedule=(DWORD *)HeapAlloc(hHeap,0,1);
 | 
|---|
 | 846 |     CaseScheduleNum=0;
 | 
|---|
 | 847 |     NowCaseSchedule=0;
 | 
|---|
 | 848 | 
 | 
|---|
| [76] | 849 |     Type type1;
 | 
|---|
 | 850 |     if( !NumOpe(lpszParms,Type(), type1 ) ){
 | 
|---|
 | 851 |         return;
 | 
|---|
| [3] | 852 |     }
 | 
|---|
 | 853 | 
 | 
|---|
| [76] | 854 |     CaseTypeSize = type1.GetSize();
 | 
|---|
 | 855 |     if( CaseTypeSize < sizeof(long) ){
 | 
|---|
 | 856 |         CaseTypeSize=sizeof(long);
 | 
|---|
 | 857 |     }
 | 
|---|
 | 858 | 
 | 
|---|
| [3] | 859 |     for(i=cp,sw=0;;i++){
 | 
|---|
 | 860 |         if(basbuf[i]=='\0'){
 | 
|---|
 | 861 |             HeapDefaultFree(pCaseSchedule);
 | 
|---|
 | 862 |             pCaseSchedule=temp_pCaseSchedule;
 | 
|---|
 | 863 |             CaseScheduleNum=temp_CaseScheduleNum;
 | 
|---|
 | 864 |             NowCaseSchedule=temp_NowCaseSchedule;
 | 
|---|
 | 865 |             CaseTypeSize=temp_CaseTypeSize;
 | 
|---|
 | 866 |             SetError(22,"Select",cp);
 | 
|---|
 | 867 |             return;
 | 
|---|
 | 868 |         }
 | 
|---|
 | 869 |         if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE){
 | 
|---|
 | 870 |             for(i2=0;;i++){
 | 
|---|
 | 871 |                 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE) i2++;
 | 
|---|
 | 872 |                 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT){
 | 
|---|
 | 873 |                     i2--;
 | 
|---|
 | 874 |                     if(i2==0) break;
 | 
|---|
 | 875 |                 }
 | 
|---|
 | 876 |             }
 | 
|---|
 | 877 |             continue;
 | 
|---|
 | 878 |         }
 | 
|---|
 | 879 |         if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT){
 | 
|---|
 | 880 |             if(sw==0){
 | 
|---|
 | 881 |                 //add esp,CaseTypeSize
 | 
|---|
| [225] | 882 |                 compiler.codeGenerator.op_add_esp(CaseTypeSize);
 | 
|---|
| [3] | 883 |             }
 | 
|---|
 | 884 |             break;
 | 
|---|
 | 885 |         }
 | 
|---|
 | 886 |         if(basbuf[i]==1&&basbuf[i+1]==ESC_CASE){
 | 
|---|
 | 887 |             NowCaseCp=i;
 | 
|---|
 | 888 | 
 | 
|---|
 | 889 |             i++;
 | 
|---|
 | 890 |             while(1){
 | 
|---|
 | 891 |                 for(i++,i2=0;;i++,i2++){
 | 
|---|
 | 892 |                     if(basbuf[i]=='\"'){
 | 
|---|
 | 893 |                         i3=GetStringInQuotation(temporary+i2,basbuf+i);
 | 
|---|
 | 894 |                         i+=i3-1;
 | 
|---|
 | 895 |                         i2+=i3-1;
 | 
|---|
 | 896 |                         continue;
 | 
|---|
 | 897 |                     }
 | 
|---|
 | 898 |                     if(basbuf[i]=='('){
 | 
|---|
 | 899 |                         i3=GetStringInPare(temporary+i2,basbuf+i);
 | 
|---|
 | 900 |                         i+=i3-1;
 | 
|---|
 | 901 |                         i2+=i3-1;
 | 
|---|
 | 902 |                         continue;
 | 
|---|
 | 903 |                     }
 | 
|---|
 | 904 |                     if(basbuf[i]=='['){
 | 
|---|
 | 905 |                         i3=GetStringInBracket(temporary+i2,basbuf+i);
 | 
|---|
 | 906 |                         i+=i3-1;
 | 
|---|
 | 907 |                         i2+=i3-1;
 | 
|---|
 | 908 |                         continue;
 | 
|---|
 | 909 |                     }
 | 
|---|
 | 910 | 
 | 
|---|
 | 911 |                     if(IsCommandDelimitation(basbuf[i])){
 | 
|---|
 | 912 |                         temporary[i2]=0;
 | 
|---|
 | 913 |                         break;
 | 
|---|
 | 914 |                     }
 | 
|---|
 | 915 |                     if(basbuf[i]==','){
 | 
|---|
 | 916 |                         temporary[i2]=0;
 | 
|---|
 | 917 |                         break;
 | 
|---|
 | 918 |                     }
 | 
|---|
 | 919 | 
 | 
|---|
 | 920 |                     temporary[i2]=basbuf[i];
 | 
|---|
 | 921 |                 }
 | 
|---|
 | 922 | 
 | 
|---|
 | 923 |                 //エラー用
 | 
|---|
 | 924 |                 i2=cp;
 | 
|---|
 | 925 |                 cp=NowCaseCp;
 | 
|---|
 | 926 | 
 | 
|---|
| [76] | 927 |                 Type type2;
 | 
|---|
 | 928 |                 if( !NumOpe(temporary,type1,type2) ){
 | 
|---|
 | 929 |                     return;
 | 
|---|
 | 930 |                 }
 | 
|---|
| [3] | 931 | 
 | 
|---|
 | 932 |                 cp=i2;
 | 
|---|
 | 933 | 
 | 
|---|
| [76] | 934 |                 if(type1.IsObject()){
 | 
|---|
| [206] | 935 |                     std::vector<const UserProc *> subs;
 | 
|---|
| [135] | 936 |                     type1.GetClass().GetMethods().Enum( CALC_EQUAL, subs );
 | 
|---|
| [50] | 937 |                     if( subs.size() == 0 ){
 | 
|---|
| [3] | 938 |                         return;
 | 
|---|
 | 939 |                     }
 | 
|---|
 | 940 | 
 | 
|---|
| [75] | 941 |                     Parameters params;
 | 
|---|
| [76] | 942 |                     params.push_back( new Parameter( "", Type( type2 ) ) );
 | 
|---|
| [3] | 943 | 
 | 
|---|
 | 944 |                     //オーバーロードを解決
 | 
|---|
| [206] | 945 |                     const UserProc *pUserProc = OverloadSolution("==",subs, params, NULL);
 | 
|---|
| [3] | 946 | 
 | 
|---|
| [75] | 947 |                     delete params[0];
 | 
|---|
 | 948 | 
 | 
|---|
 | 949 |                     if(!pUserProc){
 | 
|---|
| [3] | 950 |                         //エラー
 | 
|---|
 | 951 |                         return;
 | 
|---|
 | 952 |                     }
 | 
|---|
 | 953 | 
 | 
|---|
 | 954 | 
 | 
|---|
 | 955 |                     //pop edx
 | 
|---|
| [225] | 956 |                     compiler.codeGenerator.op_pop(REG_EDX);
 | 
|---|
| [3] | 957 | 
 | 
|---|
 | 958 |                     //mov ecx,dword ptr[esp]
 | 
|---|
| [225] | 959 |                     compiler.codeGenerator.op_mov_RM(sizeof(long),REG_ECX,REG_ESP,0,MOD_BASE);
 | 
|---|
| [3] | 960 | 
 | 
|---|
 | 961 |                     //push edx
 | 
|---|
| [225] | 962 |                     compiler.codeGenerator.op_push(REG_EDX);
 | 
|---|
| [3] | 963 | 
 | 
|---|
 | 964 |                     //push ecx
 | 
|---|
| [225] | 965 |                     compiler.codeGenerator.op_push(REG_ECX);
 | 
|---|
| [3] | 966 | 
 | 
|---|
 | 967 |                     //call operator_proc    ※ ==演算子
 | 
|---|
| [225] | 968 |                     compiler.codeGenerator.op_call(pUserProc);
 | 
|---|
| [3] | 969 | 
 | 
|---|
 | 970 |                     //test eax,eax
 | 
|---|
| [225] | 971 |                     compiler.codeGenerator.op_test(REG_EAX,REG_EAX);
 | 
|---|
| [3] | 972 | 
 | 
|---|
 | 973 |                     //jne ...
 | 
|---|
 | 974 |                     OpBuffer[obp++]=(char)0x0F;
 | 
|---|
 | 975 |                     OpBuffer[obp++]=(char)0x85;
 | 
|---|
 | 976 |                     AddCaseSchedule();
 | 
|---|
 | 977 |                     obp+=sizeof(long);
 | 
|---|
 | 978 |                 }
 | 
|---|
| [76] | 979 |                 else if(type1.IsDouble()){
 | 
|---|
 | 980 |                     ChangeTypeToDouble(type2.GetBasicType());
 | 
|---|
| [3] | 981 | 
 | 
|---|
 | 982 |                     //fld qword ptr[esp]
 | 
|---|
| [225] | 983 |                     compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);
 | 
|---|
| [3] | 984 | 
 | 
|---|
 | 985 |                     //add esp,CaseTypeSize
 | 
|---|
| [225] | 986 |                     compiler.codeGenerator.op_add_esp(CaseTypeSize);
 | 
|---|
| [3] | 987 | 
 | 
|---|
 | 988 |                     //fld qword ptr[esp]
 | 
|---|
| [225] | 989 |                     compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);
 | 
|---|
| [3] | 990 | 
 | 
|---|
 | 991 |                     //fcompp
 | 
|---|
| [225] | 992 |                     compiler.codeGenerator.op_fcompp();
 | 
|---|
| [3] | 993 | 
 | 
|---|
 | 994 |                     //fnstsw ax
 | 
|---|
| [225] | 995 |                     compiler.codeGenerator.op_fnstsw_ax();
 | 
|---|
| [3] | 996 | 
 | 
|---|
 | 997 |                     //test ah,40
 | 
|---|
| [225] | 998 |                     compiler.codeGenerator.op_test_ah( (char)0x40 );
 | 
|---|
| [3] | 999 | 
 | 
|---|
 | 1000 |                     //jne ...
 | 
|---|
 | 1001 |                     OpBuffer[obp++]=(char)0x0F;
 | 
|---|
 | 1002 |                     OpBuffer[obp++]=(char)0x85;
 | 
|---|
 | 1003 |                     AddCaseSchedule();
 | 
|---|
 | 1004 |                     obp+=sizeof(long);
 | 
|---|
 | 1005 |                 }
 | 
|---|
| [76] | 1006 |                 else if(type1.IsSingle()){
 | 
|---|
 | 1007 |                     ChangeTypeToSingle(type2.GetBasicType());
 | 
|---|
| [3] | 1008 | 
 | 
|---|
 | 1009 |                     //fld dword ptr[esp]
 | 
|---|
| [225] | 1010 |                     compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);
 | 
|---|
| [3] | 1011 | 
 | 
|---|
 | 1012 |                     //add esp,CaseTypeSize
 | 
|---|
| [225] | 1013 |                     compiler.codeGenerator.op_add_esp(CaseTypeSize);
 | 
|---|
| [3] | 1014 | 
 | 
|---|
 | 1015 |                     //fld dword ptr[esp]
 | 
|---|
| [225] | 1016 |                     compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);
 | 
|---|
| [3] | 1017 | 
 | 
|---|
 | 1018 |                     //fcompp
 | 
|---|
| [225] | 1019 |                     compiler.codeGenerator.op_fcompp();
 | 
|---|
| [3] | 1020 | 
 | 
|---|
 | 1021 |                     //fnstsw ax
 | 
|---|
| [225] | 1022 |                     compiler.codeGenerator.op_fnstsw_ax();
 | 
|---|
| [3] | 1023 | 
 | 
|---|
 | 1024 |                     //test ah,40
 | 
|---|
| [225] | 1025 |                     compiler.codeGenerator.op_test_ah( (char)0x40 );
 | 
|---|
| [3] | 1026 | 
 | 
|---|
 | 1027 |                     //jne ...
 | 
|---|
 | 1028 |                     OpBuffer[obp++]=(char)0x0F;
 | 
|---|
 | 1029 |                     OpBuffer[obp++]=(char)0x85;
 | 
|---|
 | 1030 |                     AddCaseSchedule();
 | 
|---|
 | 1031 |                     obp+=sizeof(long);
 | 
|---|
 | 1032 |                 }
 | 
|---|
 | 1033 |                 else{
 | 
|---|
 | 1034 |                     //その他整数型
 | 
|---|
 | 1035 | 
 | 
|---|
 | 1036 |                     //pop ebx
 | 
|---|
| [225] | 1037 |                     compiler.codeGenerator.op_pop(REG_EBX);
 | 
|---|
| [3] | 1038 | 
 | 
|---|
 | 1039 |                     //mov eax,dword ptr[esp]
 | 
|---|
| [236] | 1040 |                     compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_ESP, 0, MOD_BASE );
 | 
|---|
| [3] | 1041 | 
 | 
|---|
 | 1042 |                     //cmp eax,ebx
 | 
|---|
| [227] | 1043 |                     compiler.codeGenerator.op_cmp_RR( REG_EAX, REG_EBX );
 | 
|---|
| [3] | 1044 | 
 | 
|---|
 | 1045 |                     //je ...
 | 
|---|
 | 1046 |                     OpBuffer[obp++]=(char)0x0F;
 | 
|---|
 | 1047 |                     OpBuffer[obp++]=(char)0x84;
 | 
|---|
 | 1048 |                     AddCaseSchedule();
 | 
|---|
 | 1049 |                     obp+=sizeof(long);
 | 
|---|
 | 1050 |                 }
 | 
|---|
 | 1051 | 
 | 
|---|
 | 1052 |                 if(basbuf[i]!=',') break;
 | 
|---|
 | 1053 |             }
 | 
|---|
 | 1054 |         }
 | 
|---|
 | 1055 |         if(basbuf[i]==1&&basbuf[i+1]==ESC_CASEELSE){
 | 
|---|
 | 1056 |             sw=1;
 | 
|---|
 | 1057 | 
 | 
|---|
 | 1058 |             //jmp ...
 | 
|---|
 | 1059 |             OpBuffer[obp++]=(char)0xE9;
 | 
|---|
 | 1060 |             AddCaseSchedule();
 | 
|---|
 | 1061 |             obp+=sizeof(long);
 | 
|---|
 | 1062 |         }
 | 
|---|
 | 1063 |     }
 | 
|---|
 | 1064 | 
 | 
|---|
 | 1065 |     //レキシカルスコープをレベルアップ
 | 
|---|
| [183] | 1066 |     GetLexicalScopes().Start( obp, SCOPE_TYPE_SELECT );
 | 
|---|
| [3] | 1067 | 
 | 
|---|
 | 1068 |     //Select Case内をコンパイル
 | 
|---|
 | 1069 |     CompileBuffer(ESC_ENDSELECT,0);
 | 
|---|
 | 1070 | 
 | 
|---|
 | 1071 |     //jmp EndSelect
 | 
|---|
 | 1072 |     OpBuffer[obp++]=(char)0xE9;
 | 
|---|
 | 1073 |     AddCaseSchedule();
 | 
|---|
 | 1074 |     obp+=sizeof(long);
 | 
|---|
 | 1075 | 
 | 
|---|
 | 1076 |     //最終スケジュール
 | 
|---|
 | 1077 |     for(i=NowCaseSchedule;i<CaseScheduleNum;i++){
 | 
|---|
 | 1078 |         *(long *)(OpBuffer+pCaseSchedule[i])=obp-(pCaseSchedule[i]+sizeof(long));
 | 
|---|
 | 1079 |     }
 | 
|---|
 | 1080 |     HeapDefaultFree(pCaseSchedule);
 | 
|---|
 | 1081 | 
 | 
|---|
 | 1082 |     //レキシカルスコープをレベルダウン
 | 
|---|
| [183] | 1083 |     GetLexicalScopes().End();
 | 
|---|
| [3] | 1084 | 
 | 
|---|
 | 1085 |     pCaseSchedule=temp_pCaseSchedule;
 | 
|---|
 | 1086 |     CaseScheduleNum=temp_CaseScheduleNum;
 | 
|---|
 | 1087 |     NowCaseSchedule=temp_NowCaseSchedule;
 | 
|---|
 | 1088 |     CaseTypeSize=temp_CaseTypeSize;
 | 
|---|
 | 1089 | }
 | 
|---|
 | 1090 | void OpcodeCase(char *Parameter){
 | 
|---|
 | 1091 |     extern DWORD *pCaseSchedule;
 | 
|---|
 | 1092 |     extern int NowCaseSchedule;
 | 
|---|
 | 1093 |     extern int CaseTypeSize;
 | 
|---|
 | 1094 |     int i;
 | 
|---|
 | 1095 | 
 | 
|---|
 | 1096 |     if(!pCaseSchedule){
 | 
|---|
 | 1097 |         SetError(30,"Case",cp);
 | 
|---|
 | 1098 |         return;
 | 
|---|
 | 1099 |     }
 | 
|---|
 | 1100 | 
 | 
|---|
 | 1101 |     //jmp EndSelect
 | 
|---|
 | 1102 |     OpBuffer[obp++]=(char)0xE9;
 | 
|---|
 | 1103 |     AddCaseSchedule();
 | 
|---|
 | 1104 |     obp+=sizeof(long);
 | 
|---|
 | 1105 | 
 | 
|---|
 | 1106 |     i=0;
 | 
|---|
 | 1107 |     while(1){
 | 
|---|
 | 1108 |         //Caseスケジュール
 | 
|---|
 | 1109 |         *(long *)(OpBuffer+pCaseSchedule[NowCaseSchedule])=obp-(pCaseSchedule[NowCaseSchedule]+sizeof(long));
 | 
|---|
 | 1110 |         NowCaseSchedule++;
 | 
|---|
 | 1111 | 
 | 
|---|
 | 1112 |         i=JumpOneParameter(Parameter,i);
 | 
|---|
 | 1113 |         if(Parameter[i]=='\0') break;
 | 
|---|
 | 1114 |     }
 | 
|---|
 | 1115 | 
 | 
|---|
 | 1116 |     //add esp,CaseTypeSize
 | 
|---|
| [225] | 1117 |     compiler.codeGenerator.op_add_esp(CaseTypeSize);
 | 
|---|
| [3] | 1118 | }
 | 
|---|
 | 1119 | 
 | 
|---|
 | 1120 | void OpcodeGosub(char *Parameter){
 | 
|---|
 | 1121 |     extern HANDLE hHeap;
 | 
|---|
 | 1122 |     int i,LineNum;
 | 
|---|
 | 1123 | 
 | 
|---|
 | 1124 |     if(Parameter[0]=='*'){
 | 
|---|
 | 1125 |         i=GetLabelAddress(Parameter+1,0);
 | 
|---|
 | 1126 | 
 | 
|---|
| [246] | 1127 |         if( i == -1 )
 | 
|---|
 | 1128 |         {
 | 
|---|
 | 1129 |             //jmp ...(schedule)
 | 
|---|
 | 1130 |             compiler.codeGenerator.op_jmp_goto_schedule( GotoLabelSchedule( (const std::string)(Parameter + 1), obp, cp ) );
 | 
|---|
| [3] | 1131 |         }
 | 
|---|
| [246] | 1132 |         else
 | 
|---|
 | 1133 |         {
 | 
|---|
 | 1134 |             //jmp ...
 | 
|---|
 | 1135 |             compiler.codeGenerator.op_jmp( i-obp, sizeof(long), false, true );
 | 
|---|
 | 1136 |         }
 | 
|---|
| [3] | 1137 |     }
 | 
|---|
 | 1138 |     else{
 | 
|---|
 | 1139 |         LineNum=atoi(Parameter);
 | 
|---|
 | 1140 |         i=GetLabelAddress(0,LineNum);
 | 
|---|
 | 1141 | 
 | 
|---|
| [246] | 1142 |         if( i == -1 )
 | 
|---|
 | 1143 |         {
 | 
|---|
 | 1144 |             //jmp ...(schedule)
 | 
|---|
 | 1145 |             compiler.codeGenerator.op_jmp_goto_schedule( GotoLabelSchedule( LineNum, obp, cp ) );
 | 
|---|
| [3] | 1146 |         }
 | 
|---|
| [246] | 1147 |         else
 | 
|---|
 | 1148 |         {
 | 
|---|
 | 1149 |             //jmp ...
 | 
|---|
 | 1150 |             compiler.codeGenerator.op_jmp( i-obp, sizeof(long), false, true );
 | 
|---|
 | 1151 |         }
 | 
|---|
| [3] | 1152 |     }
 | 
|---|
 | 1153 | }
 | 
|---|
 | 1154 | void OpcodeReturn(char *Parameter){
 | 
|---|
| [76] | 1155 |     if( UserProc::IsGlobalAreaCompiling() ){
 | 
|---|
| [3] | 1156 |         //Gosub~Returnとして扱う
 | 
|---|
 | 1157 | 
 | 
|---|
 | 1158 |         //ret
 | 
|---|
| [225] | 1159 |         compiler.codeGenerator.op_ret();
 | 
|---|
| [3] | 1160 |     }
 | 
|---|
 | 1161 |     else{
 | 
|---|
 | 1162 |         //戻り値をセット
 | 
|---|
 | 1163 |         if(Parameter[0]){
 | 
|---|
| [206] | 1164 |             const UserProc &proc = UserProc::CompilingUserProc();
 | 
|---|
| [76] | 1165 | 
 | 
|---|
| [75] | 1166 |             const char *temp = "_System_ReturnValue";
 | 
|---|
| [76] | 1167 |             if(proc.GetName()[0]==1&&proc.GetName()[1]==ESC_OPERATOR)
 | 
|---|
| [75] | 1168 |             {
 | 
|---|
 | 1169 |             }
 | 
|---|
| [76] | 1170 |             else{
 | 
|---|
 | 1171 |                 temp=proc.GetName().c_str();
 | 
|---|
 | 1172 |             }
 | 
|---|
| [3] | 1173 | 
 | 
|---|
| [75] | 1174 |             char temporary[VN_SIZE];
 | 
|---|
 | 1175 |             sprintf(temporary,"%s=%s",temp,Parameter);
 | 
|---|
 | 1176 |             OpcodeCalc(temporary);
 | 
|---|
| [3] | 1177 |         }
 | 
|---|
 | 1178 | 
 | 
|---|
 | 1179 |         //プロシージャを抜け出す(C言語のreturnと同様の処理を行う)
 | 
|---|
 | 1180 |         OpcodeExitSub();
 | 
|---|
 | 1181 |     }
 | 
|---|
 | 1182 | }
 | 
|---|
 | 1183 | 
 | 
|---|
 | 1184 | 
 | 
|---|
 | 1185 | ////////////
 | 
|---|
 | 1186 | // ポインタ
 | 
|---|
 | 1187 | 
 | 
|---|
 | 1188 | void OpcodeSetPtrData(char *Parameter,int type){
 | 
|---|
| [76] | 1189 |     int i;
 | 
|---|
| [3] | 1190 |     char temporary[VN_SIZE];
 | 
|---|
 | 1191 | 
 | 
|---|
 | 1192 |     if(Parameter[0]=='('){
 | 
|---|
 | 1193 |         i=JumpStringInPare(Parameter,1);
 | 
|---|
 | 1194 |         if(Parameter[i+1]=='\0'){
 | 
|---|
 | 1195 |             for(i=0;;i++){
 | 
|---|
 | 1196 |                 Parameter[i]=Parameter[i+1];
 | 
|---|
 | 1197 |                 if(Parameter[i]=='\0') break;
 | 
|---|
 | 1198 |             }
 | 
|---|
 | 1199 |             Parameter[i-1]=0;
 | 
|---|
 | 1200 |         }
 | 
|---|
 | 1201 |     }
 | 
|---|
 | 1202 | 
 | 
|---|
 | 1203 |     //第1パラメータを取得
 | 
|---|
 | 1204 |     i=GetOneParameter(Parameter,0,temporary);
 | 
|---|
 | 1205 |     if(!Parameter[i]){
 | 
|---|
 | 1206 |         SetError(1,NULL,cp);
 | 
|---|
 | 1207 |         return;
 | 
|---|
 | 1208 |     }
 | 
|---|
 | 1209 | 
 | 
|---|
| [76] | 1210 |     Type resultType;
 | 
|---|
 | 1211 |     if( !NumOpe(temporary,Type(),resultType) ){
 | 
|---|
 | 1212 |         return;
 | 
|---|
 | 1213 |     }
 | 
|---|
 | 1214 |     if(!resultType.IsWhole()){
 | 
|---|
 | 1215 |         SetError(11,Parameter,cp);
 | 
|---|
 | 1216 |         return;
 | 
|---|
 | 1217 |     }
 | 
|---|
| [3] | 1218 | 
 | 
|---|
| [76] | 1219 |     ChangeTypeToLong( resultType.GetBasicType() );
 | 
|---|
 | 1220 | 
 | 
|---|
| [3] | 1221 |     //第2パラメータを取得
 | 
|---|
 | 1222 |     i=GetOneParameter(Parameter,i,temporary);
 | 
|---|
 | 1223 |     if(Parameter[i]){
 | 
|---|
 | 1224 |         SetError(1,NULL,cp);
 | 
|---|
 | 1225 |         return;
 | 
|---|
 | 1226 |     }
 | 
|---|
 | 1227 | 
 | 
|---|
| [76] | 1228 |     if( !NumOpe(temporary,Type(),resultType) ){
 | 
|---|
 | 1229 |         return;
 | 
|---|
 | 1230 |     }
 | 
|---|
 | 1231 | 
 | 
|---|
| [3] | 1232 |     if(type==DEF_DOUBLE){
 | 
|---|
| [76] | 1233 |         ChangeTypeToDouble_ToFpuReg( resultType.GetBasicType() );
 | 
|---|
| [3] | 1234 | 
 | 
|---|
 | 1235 |         //pop eax
 | 
|---|
| [225] | 1236 |         compiler.codeGenerator.op_pop(REG_EAX);
 | 
|---|
| [3] | 1237 | 
 | 
|---|
 | 1238 |         //fstp qword ptr[eax]
 | 
|---|
| [236] | 1239 |         compiler.codeGenerator.PutOld(
 | 
|---|
 | 1240 |             (char)0xDD,
 | 
|---|
 | 1241 |             (char)0x18
 | 
|---|
 | 1242 |         );
 | 
|---|
| [3] | 1243 |     }
 | 
|---|
 | 1244 |     else if(type==DEF_SINGLE){
 | 
|---|
| [76] | 1245 |         ChangeTypeToSingle( resultType.GetBasicType() );
 | 
|---|
| [3] | 1246 | 
 | 
|---|
 | 1247 |         //pop ebx
 | 
|---|
| [225] | 1248 |         compiler.codeGenerator.op_pop(REG_EBX);
 | 
|---|
| [3] | 1249 | 
 | 
|---|
 | 1250 |         //pop eax
 | 
|---|
| [225] | 1251 |         compiler.codeGenerator.op_pop(REG_EAX);
 | 
|---|
| [3] | 1252 | 
 | 
|---|
 | 1253 |         //mov dword ptr[eax],ebx
 | 
|---|
| [225] | 1254 |         compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EBX, REG_EAX, 0, MOD_BASE );
 | 
|---|
| [3] | 1255 |     }
 | 
|---|
 | 1256 |     else if(type==DEF_QWORD){
 | 
|---|
| [76] | 1257 |         ChangeTypeToInt64( resultType.GetBasicType() );
 | 
|---|
| [3] | 1258 | 
 | 
|---|
 | 1259 |         //pop ecx
 | 
|---|
| [225] | 1260 |         compiler.codeGenerator.op_pop(REG_ECX);
 | 
|---|
| [3] | 1261 | 
 | 
|---|
 | 1262 |         //pop ebx
 | 
|---|
| [225] | 1263 |         compiler.codeGenerator.op_pop(REG_EBX);
 | 
|---|
| [3] | 1264 | 
 | 
|---|
 | 1265 |         //pop eax
 | 
|---|
| [225] | 1266 |         compiler.codeGenerator.op_pop(REG_EAX);
 | 
|---|
| [3] | 1267 | 
 | 
|---|
 | 1268 |         //mov dword ptr[eax],ecx
 | 
|---|
| [225] | 1269 |         compiler.codeGenerator.op_mov_MR( sizeof(long), REG_ECX, REG_EAX, 0, MOD_BASE );
 | 
|---|
| [3] | 1270 | 
 | 
|---|
 | 1271 |         //mov dword ptr[eax+sizeof(long)],ebx
 | 
|---|
| [225] | 1272 |         compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EBX, REG_EAX, 0x04, MOD_BASE_DISP8 );
 | 
|---|
| [3] | 1273 |     }
 | 
|---|
 | 1274 |     else if(type==DEF_DWORD){
 | 
|---|
| [76] | 1275 |         ChangeTypeToLong( resultType.GetBasicType() );
 | 
|---|
| [3] | 1276 | 
 | 
|---|
 | 1277 |         //pop ebx
 | 
|---|
| [225] | 1278 |         compiler.codeGenerator.op_pop(REG_EBX);
 | 
|---|
| [3] | 1279 | 
 | 
|---|
 | 1280 |         //pop eax
 | 
|---|
| [225] | 1281 |         compiler.codeGenerator.op_pop(REG_EAX);
 | 
|---|
| [3] | 1282 | 
 | 
|---|
 | 1283 |         //mov dword ptr[eax],ebx
 | 
|---|
| [225] | 1284 |         compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EBX, REG_EAX, 0, MOD_BASE );
 | 
|---|
| [3] | 1285 |     }
 | 
|---|
 | 1286 |     else if(type==DEF_WORD){
 | 
|---|
| [76] | 1287 |         ChangeTypeToLong( resultType.GetBasicType() );
 | 
|---|
| [3] | 1288 | 
 | 
|---|
 | 1289 |         //pop ebx
 | 
|---|
| [225] | 1290 |         compiler.codeGenerator.op_pop(REG_EBX);
 | 
|---|
| [3] | 1291 | 
 | 
|---|
 | 1292 |         //pop eax
 | 
|---|
| [225] | 1293 |         compiler.codeGenerator.op_pop(REG_EAX);
 | 
|---|
| [3] | 1294 | 
 | 
|---|
 | 1295 |         //mov word ptr[eax],bx
 | 
|---|
| [236] | 1296 |         compiler.codeGenerator.op_mov_MR( sizeof(short), REG_EBX, REG_EAX, 0, MOD_BASE );
 | 
|---|
| [3] | 1297 |     }
 | 
|---|
 | 1298 |     else if(type==DEF_BYTE){
 | 
|---|
| [76] | 1299 |         ChangeTypeToLong( resultType.GetBasicType() );
 | 
|---|
| [3] | 1300 | 
 | 
|---|
 | 1301 |         //pop ebx
 | 
|---|
| [225] | 1302 |         compiler.codeGenerator.op_pop(REG_EBX);
 | 
|---|
| [3] | 1303 | 
 | 
|---|
 | 1304 |         //pop eax
 | 
|---|
| [225] | 1305 |         compiler.codeGenerator.op_pop(REG_EAX);
 | 
|---|
| [3] | 1306 | 
 | 
|---|
 | 1307 |         //mov byte ptr[eax],bl
 | 
|---|
| [236] | 1308 |         compiler.codeGenerator.op_mov_MR( sizeof(char), REG_EBX, REG_EAX, 0, MOD_BASE );
 | 
|---|
| [3] | 1309 |     }
 | 
|---|
 | 1310 | }
 | 
|---|