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

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