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

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