source: dev/trunk/abdev/BasicCompiler32/Compile_Statement.cpp@ 254

Last change on this file since 254 was 254, checked in by dai_9181, 17 years ago
File size: 30.1 KB
RevLine 
[206]1#include "stdafx.h"
2
[183]3#include <jenga/include/smoothie/LexicalAnalysis.h>
4
[248]5#include <LexicalScope.h>
[183]6#include <Compiler.h>
7
[3]8#include "../BasicCompiler_Common/common.h"
9#include "Opcode.h"
10
[129]11void 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
127void 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
[248]142 const 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
[248]209 const 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
[248]215 const 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 //レキシカルスコープをレベルアップ
[253]242 extern int obp;
[248]243 compiler.codeGenerator.lexicalScopes.Start( obp, LexicalScope::SCOPE_TYPE_IF );
[3]244
245 i2=CompileBuffer(ESC_ENDIF,0);
246
247 //レキシカルスコープをレベルダウン
[248]248 compiler.codeGenerator.lexicalScopes.End();
[3]249
250
[241]251 if( pIfPertialSchedule == NULL ) return;
[3]252
253 if(i2==ESC_ELSE){
254 //jmp (endifまで)
[248]255 const PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
[3]256
[241]257 compiler.codeGenerator.opfix_JmpPertialSchedule( pIfPertialSchedule );
[3]258
259
260 /////////////////////////
261 // Else内をコード化
262 /////////////////////////
263
264 //レキシカルスコープをレベルアップ
[248]265 compiler.codeGenerator.lexicalScopes.Start( obp, LexicalScope::SCOPE_TYPE_IF );
[3]266
267 CompileBuffer(ESC_ENDIF,0);
268
269 //レキシカルスコープをレベルダウン
[248]270 compiler.codeGenerator.lexicalScopes.End();
[3]271
272
[241]273 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
[3]274 }
275 else{
[241]276 compiler.codeGenerator.opfix_JmpPertialSchedule( pIfPertialSchedule );
[3]277 }
278}
279
280int GetLabelAddress(char *LabelName,int LineNum){
281 extern int MaxLabelNum;
282 extern LABEL *pLabelNames;
283 int i;
284
285 if(LabelName){
286 for(i=0;i<MaxLabelNum;i++){
287 if(pLabelNames[i].pName){
288 if(lstrcmp(LabelName,pLabelNames[i].pName)==0) return pLabelNames[i].address;
289 }
290 }
291 }
292 else{
293 for(i=0;i<MaxLabelNum;i++){
294 if(pLabelNames[i].pName==0){
295 if(LineNum==pLabelNames[i].line) return pLabelNames[i].address;
296 }
297 }
298 }
299 return -1;
300}
301void OpcodeGoto(char *Parameter){
302 extern HANDLE hHeap;
303 int i,LineNum;
304
305 if(Parameter[0]=='*'){
306 i=GetLabelAddress(Parameter+1,0);
307
[246]308 if( i == -1 )
309 {
310 //jmp ...(schedule)
[253]311 extern int obp;
312 compiler.codeGenerator.op_jmp_goto_schedule( (const std::string)(Parameter + 1), 0, cp );
[3]313 }
[246]314 else
315 {
316 //jmp ...
[253]317 extern int obp;
[246]318 compiler.codeGenerator.op_jmp( i-obp, sizeof(long), false, true );
319 }
[3]320 }
321 else{
322 LineNum=atoi(Parameter);
323 i=GetLabelAddress(0,LineNum);
324
[246]325 if( i == -1 )
326 {
327 //jmp ...(schedule)
[253]328 extern int obp;
329 compiler.codeGenerator.op_jmp_goto_schedule( "", LineNum, cp );
[3]330 }
[246]331 else
332 {
333 //jmp ...
[253]334 extern int obp;
[246]335 compiler.codeGenerator.op_jmp( i-obp, sizeof(long), false, true );
336 }
[3]337 }
338}
339void OpcodeWhile(char *Parameter){
340 extern HANDLE hHeap;
341
342 //Continueアドレスのバックアップとセット
[241]343 compiler.codeGenerator.ContinueAreaBegin();
[3]344
345 if(!Parameter[0]) SetError(10,"While",cp);
346
[248]347 const PertialSchedule *pWhilePertialSchedule = NULL;
[76]348 Type tempType;
349 if( !NumOpe(Parameter,Type(),tempType) ){
350 //ダミー
351 }
352 else if( tempType.IsDouble() ){
[3]353 //fld qword ptr[esp]
[225]354 compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);
[3]355
356 //push 0
[225]357 compiler.codeGenerator.op_push_V(0);
[3]358
359 //fild dword ptr[esp]
[225]360 compiler.codeGenerator.op_fld_ptr_esp(DEF_LONG);
[3]361
362 //add esp,sizeof(double)+sizeof(long)
[225]363 compiler.codeGenerator.op_add_esp(sizeof(double)+sizeof(long));
[3]364
365 //fcompp
[225]366 compiler.codeGenerator.op_fcompp();
[3]367
368 //fnstsw ax
[225]369 compiler.codeGenerator.op_fnstsw_ax();
[3]370
371 //test ah,40
[225]372 compiler.codeGenerator.op_test_ah( (char)0x40 );
[3]373
374 //jne (Wend まで)
[241]375 pWhilePertialSchedule = compiler.codeGenerator.op_jne( 0, sizeof(long), true );
[3]376 }
[76]377 else if( tempType.IsSingle() ){
[3]378 //fld dword ptr[esp]
[225]379 compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);
[3]380
381 //push 0
[225]382 compiler.codeGenerator.op_push_V(0);
[3]383
384 //fild dword ptr[esp]
[225]385 compiler.codeGenerator.op_fld_ptr_esp(DEF_LONG);
[3]386
387 //add esp,sizeof(float)+sizeof(long)
[225]388 compiler.codeGenerator.op_add_esp(sizeof(float)+sizeof(long));
[3]389
390 //fcompp
[225]391 compiler.codeGenerator.op_fcompp();
[3]392
393 //fnstsw ax
[225]394 compiler.codeGenerator.op_fnstsw_ax();
[3]395
[241]396 //test ah,40h
[225]397 compiler.codeGenerator.op_test_ah( (char)0x40 );
[3]398
399 //jne (Wend まで)
[241]400 pWhilePertialSchedule = compiler.codeGenerator.op_jne( 0, sizeof(long), true );
[3]401 }
[76]402 else if( tempType.Is64() ){
[3]403 //64ビット型
404
405 //pop eax
[225]406 compiler.codeGenerator.op_pop(REG_EAX);
[3]407
408 //pop ebx
[225]409 compiler.codeGenerator.op_pop(REG_EBX);
[3]410
411 //cmp eax,0
[236]412 compiler.codeGenerator.op_cmp_value( sizeof(long), REG_EAX, 0 );
[3]413
414 //jne
[248]415 const PertialSchedule *pTempPertialSchedule1 = compiler.codeGenerator.op_jne( 0, sizeof(char), true );
[3]416
417 //cmp ebx,0
[236]418 compiler.codeGenerator.op_cmp_value( sizeof(long), REG_EBX, 0 );
[3]419
420 //jne
[248]421 const PertialSchedule *pTempPertialSchedule2 = compiler.codeGenerator.op_jne( 0, sizeof(char), true );
[3]422
[241]423 //jmp (Wendまでジャンプ)
424 pWhilePertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
[3]425
[241]426 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule1 );
427 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule2 );
[3]428 }
429 else{
430 //その他整数型
431
432 //pop eax
[225]433 compiler.codeGenerator.op_pop(REG_EAX);
[3]434
435 //cmp eax,0
[236]436 compiler.codeGenerator.op_cmp_value( sizeof(long), REG_EAX, 0 );
[3]437
438 //je (Wend まで)
[241]439 pWhilePertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
[3]440 }
441
442 //レキシカルスコープをレベルアップ
[253]443 extern int obp;
[248]444 compiler.codeGenerator.lexicalScopes.Start( obp, LexicalScope::SCOPE_TYPE_WHILE );
[3]445
446 //While内をコンパイル
447 CompileBuffer(0,COM_WEND);
448
[248]449 compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd();
[3]450
451 //jmp ...
[241]452 compiler.codeGenerator.op_jmp_continue();
[3]453
454 //レキシカルスコープをレベルダウン
[248]455 compiler.codeGenerator.lexicalScopes.End();
[3]456
[241]457 if( pWhilePertialSchedule )
458 {
459 compiler.codeGenerator.opfix_JmpPertialSchedule( pWhilePertialSchedule );
460 }
[3]461
[241]462 compiler.codeGenerator.ContinueAreaEnd();
[3]463}
464
465char szNextVariable[VN_SIZE];
466void OpcodeFor(char *Parameter){
467 extern HANDLE hHeap;
[241]468 int i,i2;
[3]469 char temporary[VN_SIZE],variable[VN_SIZE],JudgeNum[VN_SIZE],StepNum[VN_SIZE];
470
471 //第1パラメータを取得
472 i=GetOneParameter(Parameter,0,temporary);
473 if(!Parameter[i]){
474 SetError(12,"For",cp);
475 goto ErrorStep;
476 }
477
478 for(i2=0;;i2++){
479 if(temporary[i2]=='='){
480 variable[i2]=0;
481
482 //カウンタ初期化
483 OpcodeCalc(temporary);
484 break;
485 }
486 if(temporary[i2]=='\0'){
487 SetError(12,"For",cp);
488 goto ErrorStep;
489 }
490 variable[i2]=temporary[i2];
491 }
492
493 //jmp ...
[248]494 const PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
[3]495
496 //Continueアドレスのバックアップとセット
[241]497 compiler.codeGenerator.ContinueAreaBegin();
[3]498
499 //第2パラメータを取得(to~)
500 i=GetOneParameter(Parameter,i,JudgeNum);
501
502 //第3パラメータを取得(step~)
503 if(Parameter[i]){
504 i=GetOneParameter(Parameter,i,StepNum);
505 if(Parameter[i]) SetError(12,"For",cp);
506 }
507 else lstrcpy(StepNum,"1");
508
509 //カウンタを増加させる
510 sprintf(temporary,"%s=(%s)+(%s)",variable,variable,StepNum);
511 OpcodeCalc(temporary);
512
[241]513 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
[3]514
515 //増加か減少かを区別する
516 sprintf(temporary,"(%s)>=0",StepNum);
[76]517 NumOpe(temporary,Type(),Type());
[3]518
519 //pop eax
[225]520 compiler.codeGenerator.op_pop(REG_EAX);
[3]521
522 //cmp eax,0
[236]523 compiler.codeGenerator.op_cmp_value( sizeof(long), REG_EAX, 0 );
[3]524
525 //je [カウンタ減少の場合の判定]
[241]526 pTempPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
[3]527
528 //判定(カウンタ増加の場合)
529 sprintf(temporary,"%s<=(%s)",variable,JudgeNum);
[76]530 NumOpe(temporary,Type(),Type());
[3]531
532 //pop eax
[225]533 compiler.codeGenerator.op_pop(REG_EAX);
[3]534
535 //jmp [カウンタ減少の場合の判定を飛び越す]
[248]536 const PertialSchedule *pTempPertialSchedule2 = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
[3]537
[241]538 //jeジャンプ先のオフセット値
539 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
[3]540
541 //判定(カウンタ減少の場合)
542 sprintf(temporary,"%s>=(%s)",variable,JudgeNum);
[76]543 NumOpe(temporary,Type(),Type());
[3]544
545 //pop eax
[225]546 compiler.codeGenerator.op_pop(REG_EAX);
[3]547
[241]548 //jmpジャンプ先のオフセット値
549 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule2 );
[3]550
551 //cmp eax,0
[236]552 compiler.codeGenerator.op_cmp_value( sizeof(long), REG_EAX, 0 );
[3]553
554ErrorStep:
555
556 //je ...
[241]557 pTempPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
[3]558
559 //レキシカルスコープをレベルアップ
[253]560 extern int obp;
[248]561 compiler.codeGenerator.lexicalScopes.Start( obp, LexicalScope::SCOPE_TYPE_FOR );
[3]562
563 //For内をコンパイル
564 CompileBuffer(0,COM_NEXT);
565
[248]566 compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd();
[3]567
568 if(szNextVariable[0]){
569 if(lstrcmp(szNextVariable,variable)!=0){
570 SetError(55,szNextVariable,cp);
571 }
572 }
573
574 //jmp ...
[241]575 compiler.codeGenerator.op_jmp_continue();
[3]576
577 //レキシカルスコープをレベルダウン
[248]578 compiler.codeGenerator.lexicalScopes.End();
[3]579
[241]580 //jeジャンプ先のオフセット値
581 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
[3]582
583 //Continueアドレスを復元
[241]584 compiler.codeGenerator.ContinueAreaEnd();
[3]585}
586
587void OpcodeDo(char *Parameter){
588 extern HANDLE hHeap;
[247]589 int i,i2,i3;
[3]590
591 if(Parameter[0]) SetError(10,"Do",cp);
592
593 //Continueアドレスのバックアップとセット
[241]594 compiler.codeGenerator.ContinueAreaBegin();
[3]595
596 //レキシカルスコープをレベルアップ
[253]597 extern int obp;
[248]598 compiler.codeGenerator.lexicalScopes.Start( obp, LexicalScope::SCOPE_TYPE_DO );
[3]599
600 //Do内をコンパイル
601 CompileBuffer(0,COM_LOOP);
602
[248]603 compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd();
[3]604
[248]605 const PertialSchedule *pDoPertialSchedule = NULL;
[241]606
[3]607 extern char *basbuf;
608 char temporary[VN_SIZE];
609 for(i=cp-1;;i--){
610 if(IsCommandDelimitation(basbuf[i])){
611 i+=3;
612 if(!(basbuf[i]=='0'||basbuf[i]=='1')){
613 //無条件ループ
614 break;
615 }
616 i3=i;
617
618 for(i+=2,i2=0;;i++,i2++){
619 if(IsCommandDelimitation(basbuf[i])){
620 temporary[i2]=0;
621 break;
622 }
623 temporary[i2]=basbuf[i];
624 }
625
[76]626 Type tempType;
627 NumOpe(temporary,Type(),tempType);
[3]628
[76]629 if( tempType.IsDouble() ){
[3]630 //fld qword ptr[esp]
[225]631 compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);
[3]632
633 //push 0
[225]634 compiler.codeGenerator.op_push_V(0);
[3]635
636 //fild dword ptr[esp]
[225]637 compiler.codeGenerator.op_fld_ptr_esp(DEF_LONG);
[3]638
639 //add esp,sizeof(double)+sizeof(long)
[225]640 compiler.codeGenerator.op_add_esp(sizeof(double)+sizeof(long));
[3]641
642 //fcompp
[225]643 compiler.codeGenerator.op_fcompp();
[3]644
645 //fnstsw ax
[225]646 compiler.codeGenerator.op_fnstsw_ax();
[3]647
648 //test ah,40
[225]649 compiler.codeGenerator.op_test_ah( (char)0x40 );
[3]650
651 if(basbuf[i3]=='0'){
652 //While
653
654 //jne 5(ループ終了)
[241]655 pDoPertialSchedule = compiler.codeGenerator.op_jne( 0, sizeof(char), true );
[3]656 }
657 else if(basbuf[i3]=='1'){
658 //Until
659
660 //je 5(ループ終了)
[241]661 pDoPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(char), true );
[3]662 }
663 }
[76]664 else if( tempType.IsSingle() ){
[3]665 //fld dword ptr[esp]
[225]666 compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);
[3]667
668 //push 0
[225]669 compiler.codeGenerator.op_push_V(0);
[3]670
671 //fild dword ptr[esp]
[225]672 compiler.codeGenerator.op_fld_ptr_esp(DEF_LONG);
[3]673
674 //add esp,sizeof(float)+sizeof(long)
[225]675 compiler.codeGenerator.op_add_esp(sizeof(float)+sizeof(long));
[3]676
677 //fcompp
[225]678 compiler.codeGenerator.op_fcompp();
[3]679
680 //fnstsw ax
[225]681 compiler.codeGenerator.op_fnstsw_ax();
[3]682
683 //test ah,40
[225]684 compiler.codeGenerator.op_test_ah( (char)0x40 );
[3]685
686 if(basbuf[i3]=='0'){
687 //While
688
689 //jne 5(ループ終了)
[241]690 pDoPertialSchedule = compiler.codeGenerator.op_jne( 0, sizeof(char), true );
[3]691 }
692 else if(basbuf[i3]=='1'){
693 //Until
694
695 //je 5(ループ終了)
[241]696 pDoPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(char), true );
[3]697 }
698 }
[76]699 else if( tempType.Is64() ){
[3]700 //64ビット型
701
702 //pop eax
[225]703 compiler.codeGenerator.op_pop(REG_EAX);
[3]704
705 //pop ebx
[225]706 compiler.codeGenerator.op_pop(REG_EBX);
[3]707
708 //cmp eax,0
[236]709 compiler.codeGenerator.op_cmp_value( sizeof(long), REG_EAX, 0 );
[3]710
711 //jne
[248]712 const PertialSchedule *pTempPertialSchedule1 = compiler.codeGenerator.op_jne( 0, sizeof(char), true );
[3]713
714 //cmp ebx,0
[236]715 compiler.codeGenerator.op_cmp_value( sizeof(long), REG_EBX, 0 );
[3]716
717 //jne
[248]718 const PertialSchedule *pTempPertialSchedule2 = compiler.codeGenerator.op_jne( 0, sizeof(char), true );
[3]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
[247]726 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule1 );
727 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule2 );
[3]728 }
729 else if(basbuf[i3]=='1'){
730 //Until
731
732 //jmp 2(ループを続ける)
[248]733 const PertialSchedule *pTempPertialSchedule3 = compiler.codeGenerator.op_jmp( 0, sizeof(char), true );
[3]734
[247]735 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule1 );
736 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule2 );
[3]737
738 //jmp 5(ループ終了)
[241]739 pDoPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(char), true );
[247]740
741 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule3 );
[3]742 }
743 }
744 else{
745 //pop eax
[225]746 compiler.codeGenerator.op_pop(REG_EAX);
[3]747
748 //cmp eax,0
[236]749 compiler.codeGenerator.op_cmp_value( sizeof(long), REG_EAX, 0 );
[3]750
751 if(basbuf[i3]=='0'){
752 //While
753
754 //je 5(ループ終了)
[241]755 pDoPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(char), true );
[3]756 }
757 else if(basbuf[i3]=='1'){
758 //Until
759
760 //jne 5(ループ終了)
[241]761 pDoPertialSchedule = compiler.codeGenerator.op_jne( 0, sizeof(char), true );
[3]762 }
763 }
764 break;
765 }
766 }
767
768 //jmp ...
[241]769 compiler.codeGenerator.op_jmp_continue();
[3]770
[241]771 if( pDoPertialSchedule )
772 {
773 compiler.codeGenerator.opfix_JmpPertialSchedule( pDoPertialSchedule );
774 }
775
[3]776 //jmp ...
[248]777 const PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
[3]778
779 //レキシカルスコープをレベルダウン
[248]780 compiler.codeGenerator.lexicalScopes.End();
[3]781
[243]782 //jmpジャンプ先のオフセット値
783 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
[3]784
785 //Continueアドレスを復元
[241]786 compiler.codeGenerator.ContinueAreaEnd();
[3]787}
788void OpcodeContinue(void){
789 //jmp ...(Continue addr)
[241]790 compiler.codeGenerator.op_jmp_continue();
[3]791}
792
793void OpcodeExitSub(void){
[76]794 if( UserProc::IsGlobalAreaCompiling() ){
[3]795 SetError(12,"Exit Sub/Function",cp);
796 return;
797 }
798
[34]799 //未解放のローカルオブジェクトのデストラクタを呼び出す
[248]800 compiler.codeGenerator.lexicalScopes.CallDestructorsOfReturn();
[34]801
[3]802 //jmp ...(End Sub/Function)
[247]803 compiler.codeGenerator.op_jmp_exitsub();
[3]804}
805
[250]806//Caseスケジュール
807class SelectSchedule
808{
809public:
810 SelectSchedule( int typeSize )
811 : typeSize( typeSize )
812 , nowCaseSchedule( 0 )
813 {
814 }
[3]815
[250]816 PertialSchedules casePertialSchedules;
817 int typeSize;
818 int nowCaseSchedule;
819};
820std::vector<SelectSchedule> selectSchedules;
[3]821
[76]822void OpcodeSelect(const char *lpszParms){
[3]823 extern HANDLE hHeap;
824 extern char *basbuf;
[76]825 int i,i2,i3,sw,NowCaseCp;
[3]826 char temporary[VN_SIZE];
[250]827
[76]828 Type type1;
829 if( !NumOpe(lpszParms,Type(), type1 ) ){
830 return;
[3]831 }
832
[250]833 selectSchedules.push_back( SelectSchedule( type1.GetSize() ) );
834
835 if( selectSchedules.back().typeSize < sizeof(long) ){
836 selectSchedules.back().typeSize = sizeof(long);
[76]837 }
838
[3]839 for(i=cp,sw=0;;i++){
840 if(basbuf[i]=='\0'){
[250]841 selectSchedules.pop_back();
[3]842 SetError(22,"Select",cp);
843 return;
844 }
845 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE){
846 for(i2=0;;i++){
847 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE) i2++;
848 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT){
849 i2--;
850 if(i2==0) break;
851 }
852 }
853 continue;
854 }
855 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT){
856 if(sw==0){
857 //add esp,CaseTypeSize
[250]858 compiler.codeGenerator.op_add_esp( selectSchedules.back().typeSize );
[3]859 }
860 break;
861 }
862 if(basbuf[i]==1&&basbuf[i+1]==ESC_CASE){
863 NowCaseCp=i;
864
865 i++;
866 while(1){
867 for(i++,i2=0;;i++,i2++){
868 if(basbuf[i]=='\"'){
869 i3=GetStringInQuotation(temporary+i2,basbuf+i);
870 i+=i3-1;
871 i2+=i3-1;
872 continue;
873 }
874 if(basbuf[i]=='('){
875 i3=GetStringInPare(temporary+i2,basbuf+i);
876 i+=i3-1;
877 i2+=i3-1;
878 continue;
879 }
880 if(basbuf[i]=='['){
881 i3=GetStringInBracket(temporary+i2,basbuf+i);
882 i+=i3-1;
883 i2+=i3-1;
884 continue;
885 }
886
887 if(IsCommandDelimitation(basbuf[i])){
888 temporary[i2]=0;
889 break;
890 }
891 if(basbuf[i]==','){
892 temporary[i2]=0;
893 break;
894 }
895
896 temporary[i2]=basbuf[i];
897 }
898
899 //エラー用
900 i2=cp;
901 cp=NowCaseCp;
902
[76]903 Type type2;
904 if( !NumOpe(temporary,type1,type2) ){
905 return;
906 }
[3]907
908 cp=i2;
909
[76]910 if(type1.IsObject()){
[206]911 std::vector<const UserProc *> subs;
[135]912 type1.GetClass().GetMethods().Enum( CALC_EQUAL, subs );
[50]913 if( subs.size() == 0 ){
[3]914 return;
915 }
916
[75]917 Parameters params;
[76]918 params.push_back( new Parameter( "", Type( type2 ) ) );
[3]919
920 //オーバーロードを解決
[206]921 const UserProc *pUserProc = OverloadSolution("==",subs, params, NULL);
[3]922
[75]923 delete params[0];
924
925 if(!pUserProc){
[3]926 //エラー
927 return;
928 }
929
930
931 //pop edx
[225]932 compiler.codeGenerator.op_pop(REG_EDX);
[3]933
934 //mov ecx,dword ptr[esp]
[225]935 compiler.codeGenerator.op_mov_RM(sizeof(long),REG_ECX,REG_ESP,0,MOD_BASE);
[3]936
937 //push edx
[225]938 compiler.codeGenerator.op_push(REG_EDX);
[3]939
940 //push ecx
[225]941 compiler.codeGenerator.op_push(REG_ECX);
[3]942
943 //call operator_proc ※ ==演算子
[225]944 compiler.codeGenerator.op_call(pUserProc);
[3]945
946 //test eax,eax
[225]947 compiler.codeGenerator.op_test(REG_EAX,REG_EAX);
[3]948
949 //jne ...
[250]950 selectSchedules.back().casePertialSchedules.push_back(
951 compiler.codeGenerator.op_jne( 0, sizeof(long), true )
952 );
[3]953 }
[76]954 else if(type1.IsDouble()){
955 ChangeTypeToDouble(type2.GetBasicType());
[3]956
957 //fld qword ptr[esp]
[225]958 compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);
[3]959
960 //add esp,CaseTypeSize
[250]961 compiler.codeGenerator.op_add_esp(selectSchedules.back().typeSize);
[3]962
963 //fld qword ptr[esp]
[225]964 compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);
[3]965
966 //fcompp
[225]967 compiler.codeGenerator.op_fcompp();
[3]968
969 //fnstsw ax
[225]970 compiler.codeGenerator.op_fnstsw_ax();
[3]971
972 //test ah,40
[225]973 compiler.codeGenerator.op_test_ah( (char)0x40 );
[3]974
975 //jne ...
[250]976 selectSchedules.back().casePertialSchedules.push_back(
977 compiler.codeGenerator.op_jne( 0, sizeof(long), true )
978 );
[3]979 }
[76]980 else if(type1.IsSingle()){
981 ChangeTypeToSingle(type2.GetBasicType());
[3]982
983 //fld dword ptr[esp]
[225]984 compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);
[3]985
986 //add esp,CaseTypeSize
[250]987 compiler.codeGenerator.op_add_esp(selectSchedules.back().typeSize);
[3]988
989 //fld dword ptr[esp]
[225]990 compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);
[3]991
992 //fcompp
[225]993 compiler.codeGenerator.op_fcompp();
[3]994
995 //fnstsw ax
[225]996 compiler.codeGenerator.op_fnstsw_ax();
[3]997
998 //test ah,40
[225]999 compiler.codeGenerator.op_test_ah( (char)0x40 );
[3]1000
1001 //jne ...
[250]1002 selectSchedules.back().casePertialSchedules.push_back(
1003 compiler.codeGenerator.op_jne( 0, sizeof(long), true )
1004 );
[3]1005 }
1006 else{
1007 //その他整数型
1008
1009 //pop ebx
[225]1010 compiler.codeGenerator.op_pop(REG_EBX);
[3]1011
1012 //mov eax,dword ptr[esp]
[236]1013 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_ESP, 0, MOD_BASE );
[3]1014
1015 //cmp eax,ebx
[227]1016 compiler.codeGenerator.op_cmp_RR( REG_EAX, REG_EBX );
[3]1017
1018 //je ...
[250]1019 selectSchedules.back().casePertialSchedules.push_back(
1020 compiler.codeGenerator.op_je( 0, sizeof(long), true )
1021 );
[3]1022 }
1023
1024 if(basbuf[i]!=',') break;
1025 }
1026 }
1027 if(basbuf[i]==1&&basbuf[i+1]==ESC_CASEELSE){
1028 sw=1;
1029
1030 //jmp ...
[250]1031 selectSchedules.back().casePertialSchedules.push_back(
1032 compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
1033 );
[3]1034 }
1035 }
1036
1037 //レキシカルスコープをレベルアップ
[253]1038 extern int obp;
[248]1039 compiler.codeGenerator.lexicalScopes.Start( obp, LexicalScope::SCOPE_TYPE_SELECT );
[3]1040
1041 //Select Case内をコンパイル
1042 CompileBuffer(ESC_ENDSELECT,0);
1043
1044 //jmp EndSelect
[250]1045 selectSchedules.back().casePertialSchedules.push_back(
1046 compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
1047 );
[3]1048
1049 //最終スケジュール
[250]1050 for(i=selectSchedules.back().nowCaseSchedule;i<(int)selectSchedules.back().casePertialSchedules.size();i++){
1051 compiler.codeGenerator.opfix_JmpPertialSchedule( selectSchedules.back().casePertialSchedules[i] );
[3]1052 }
1053
1054 //レキシカルスコープをレベルダウン
[248]1055 compiler.codeGenerator.lexicalScopes.End();
[3]1056
[250]1057 selectSchedules.pop_back();
[3]1058}
1059void OpcodeCase(char *Parameter){
1060 int i;
1061
[250]1062 if(selectSchedules.back().typeSize==-1){
[3]1063 SetError(30,"Case",cp);
1064 return;
1065 }
1066
1067 //jmp EndSelect
[250]1068 selectSchedules.back().casePertialSchedules.push_back(
1069 compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
1070 );
[3]1071
1072 i=0;
1073 while(1){
1074 //Caseスケジュール
[250]1075 compiler.codeGenerator.opfix_JmpPertialSchedule( selectSchedules.back().casePertialSchedules[selectSchedules.back().nowCaseSchedule] );
1076 selectSchedules.back().nowCaseSchedule++;
[3]1077
1078 i=JumpOneParameter(Parameter,i);
1079 if(Parameter[i]=='\0') break;
1080 }
1081
1082 //add esp,CaseTypeSize
[250]1083 compiler.codeGenerator.op_add_esp(selectSchedules.back().typeSize);
[3]1084}
1085
1086void OpcodeGosub(char *Parameter){
1087 extern HANDLE hHeap;
[253]1088 extern int obp;
[3]1089 int i,LineNum;
1090
1091 if(Parameter[0]=='*'){
1092 i=GetLabelAddress(Parameter+1,0);
1093
[246]1094 if( i == -1 )
1095 {
1096 //jmp ...(schedule)
[253]1097 compiler.codeGenerator.op_jmp_goto_schedule( (const std::string)(Parameter + 1), 0, cp );
[3]1098 }
[246]1099 else
1100 {
1101 //jmp ...
1102 compiler.codeGenerator.op_jmp( i-obp, sizeof(long), false, true );
1103 }
[3]1104 }
1105 else{
1106 LineNum=atoi(Parameter);
1107 i=GetLabelAddress(0,LineNum);
1108
[246]1109 if( i == -1 )
1110 {
1111 //jmp ...(schedule)
[253]1112 compiler.codeGenerator.op_jmp_goto_schedule( "", LineNum, cp );
[3]1113 }
[246]1114 else
1115 {
1116 //jmp ...
1117 compiler.codeGenerator.op_jmp( i-obp, sizeof(long), false, true );
1118 }
[3]1119 }
1120}
1121void OpcodeReturn(char *Parameter){
[76]1122 if( UserProc::IsGlobalAreaCompiling() ){
[3]1123 //Gosub~Returnとして扱う
1124
1125 //ret
[225]1126 compiler.codeGenerator.op_ret();
[3]1127 }
1128 else{
1129 //戻り値をセット
1130 if(Parameter[0]){
[206]1131 const UserProc &proc = UserProc::CompilingUserProc();
[76]1132
[75]1133 const char *temp = "_System_ReturnValue";
[76]1134 if(proc.GetName()[0]==1&&proc.GetName()[1]==ESC_OPERATOR)
[75]1135 {
1136 }
[76]1137 else{
1138 temp=proc.GetName().c_str();
1139 }
[3]1140
[75]1141 char temporary[VN_SIZE];
1142 sprintf(temporary,"%s=%s",temp,Parameter);
1143 OpcodeCalc(temporary);
[3]1144 }
1145
1146 //プロシージャを抜け出す(C言語のreturnと同様の処理を行う)
1147 OpcodeExitSub();
1148 }
1149}
1150
1151
1152////////////
1153// ポインタ
1154
1155void OpcodeSetPtrData(char *Parameter,int type){
[76]1156 int i;
[3]1157 char temporary[VN_SIZE];
1158
1159 if(Parameter[0]=='('){
1160 i=JumpStringInPare(Parameter,1);
1161 if(Parameter[i+1]=='\0'){
1162 for(i=0;;i++){
1163 Parameter[i]=Parameter[i+1];
1164 if(Parameter[i]=='\0') break;
1165 }
1166 Parameter[i-1]=0;
1167 }
1168 }
1169
1170 //第1パラメータを取得
1171 i=GetOneParameter(Parameter,0,temporary);
1172 if(!Parameter[i]){
1173 SetError(1,NULL,cp);
1174 return;
1175 }
1176
[76]1177 Type resultType;
1178 if( !NumOpe(temporary,Type(),resultType) ){
1179 return;
1180 }
1181 if(!resultType.IsWhole()){
1182 SetError(11,Parameter,cp);
1183 return;
1184 }
[3]1185
[76]1186 ChangeTypeToLong( resultType.GetBasicType() );
1187
[3]1188 //第2パラメータを取得
1189 i=GetOneParameter(Parameter,i,temporary);
1190 if(Parameter[i]){
1191 SetError(1,NULL,cp);
1192 return;
1193 }
1194
[76]1195 if( !NumOpe(temporary,Type(),resultType) ){
1196 return;
1197 }
1198
[3]1199 if(type==DEF_DOUBLE){
[76]1200 ChangeTypeToDouble_ToFpuReg( resultType.GetBasicType() );
[3]1201
1202 //pop eax
[225]1203 compiler.codeGenerator.op_pop(REG_EAX);
[3]1204
1205 //fstp qword ptr[eax]
[236]1206 compiler.codeGenerator.PutOld(
1207 (char)0xDD,
1208 (char)0x18
1209 );
[3]1210 }
1211 else if(type==DEF_SINGLE){
[76]1212 ChangeTypeToSingle( resultType.GetBasicType() );
[3]1213
1214 //pop ebx
[225]1215 compiler.codeGenerator.op_pop(REG_EBX);
[3]1216
1217 //pop eax
[225]1218 compiler.codeGenerator.op_pop(REG_EAX);
[3]1219
1220 //mov dword ptr[eax],ebx
[225]1221 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EBX, REG_EAX, 0, MOD_BASE );
[3]1222 }
1223 else if(type==DEF_QWORD){
[76]1224 ChangeTypeToInt64( resultType.GetBasicType() );
[3]1225
1226 //pop ecx
[225]1227 compiler.codeGenerator.op_pop(REG_ECX);
[3]1228
1229 //pop ebx
[225]1230 compiler.codeGenerator.op_pop(REG_EBX);
[3]1231
1232 //pop eax
[225]1233 compiler.codeGenerator.op_pop(REG_EAX);
[3]1234
1235 //mov dword ptr[eax],ecx
[225]1236 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_ECX, REG_EAX, 0, MOD_BASE );
[3]1237
1238 //mov dword ptr[eax+sizeof(long)],ebx
[225]1239 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EBX, REG_EAX, 0x04, MOD_BASE_DISP8 );
[3]1240 }
1241 else if(type==DEF_DWORD){
[76]1242 ChangeTypeToLong( resultType.GetBasicType() );
[3]1243
1244 //pop ebx
[225]1245 compiler.codeGenerator.op_pop(REG_EBX);
[3]1246
1247 //pop eax
[225]1248 compiler.codeGenerator.op_pop(REG_EAX);
[3]1249
1250 //mov dword ptr[eax],ebx
[225]1251 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EBX, REG_EAX, 0, MOD_BASE );
[3]1252 }
1253 else if(type==DEF_WORD){
[76]1254 ChangeTypeToLong( resultType.GetBasicType() );
[3]1255
1256 //pop ebx
[225]1257 compiler.codeGenerator.op_pop(REG_EBX);
[3]1258
1259 //pop eax
[225]1260 compiler.codeGenerator.op_pop(REG_EAX);
[3]1261
1262 //mov word ptr[eax],bx
[236]1263 compiler.codeGenerator.op_mov_MR( sizeof(short), REG_EBX, REG_EAX, 0, MOD_BASE );
[3]1264 }
1265 else if(type==DEF_BYTE){
[76]1266 ChangeTypeToLong( resultType.GetBasicType() );
[3]1267
1268 //pop ebx
[225]1269 compiler.codeGenerator.op_pop(REG_EBX);
[3]1270
1271 //pop eax
[225]1272 compiler.codeGenerator.op_pop(REG_EAX);
[3]1273
1274 //mov byte ptr[eax],bl
[236]1275 compiler.codeGenerator.op_mov_MR( sizeof(char), REG_EBX, REG_EAX, 0, MOD_BASE );
[3]1276 }
1277}
Note: See TracBrowser for help on using the repository browser.