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

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

Exit Subスケジュールをリファクタリングした

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