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

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

Labelクラスをリファクタリング

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