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

Last change on this file since 254 was 254, checked in by dai_9181, 17 years ago
File size: 30.1 KB
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 if( UserProc::IsGlobalAreaCompiling() ){
795 SetError(12,"Exit Sub/Function",cp);
796 return;
797 }
798
799 //未解放のローカルオブジェクトのデストラクタを呼び出す
800 compiler.codeGenerator.lexicalScopes.CallDestructorsOfReturn();
801
802 //jmp ...(End Sub/Function)
803 compiler.codeGenerator.op_jmp_exitsub();
804}
805
806//Caseスケジュール
807class SelectSchedule
808{
809public:
810 SelectSchedule( int typeSize )
811 : typeSize( typeSize )
812 , nowCaseSchedule( 0 )
813 {
814 }
815
816 PertialSchedules casePertialSchedules;
817 int typeSize;
818 int nowCaseSchedule;
819};
820std::vector<SelectSchedule> selectSchedules;
821
822void OpcodeSelect(const char *lpszParms){
823 extern HANDLE hHeap;
824 extern char *basbuf;
825 int i,i2,i3,sw,NowCaseCp;
826 char temporary[VN_SIZE];
827
828 Type type1;
829 if( !NumOpe(lpszParms,Type(), type1 ) ){
830 return;
831 }
832
833 selectSchedules.push_back( SelectSchedule( type1.GetSize() ) );
834
835 if( selectSchedules.back().typeSize < sizeof(long) ){
836 selectSchedules.back().typeSize = sizeof(long);
837 }
838
839 for(i=cp,sw=0;;i++){
840 if(basbuf[i]=='\0'){
841 selectSchedules.pop_back();
842 SetError(22,"Select",cp);
843 return;
844 }
845 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE){
846 for(i2=0;;i++){
847 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE) i2++;
848 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT){
849 i2--;
850 if(i2==0) break;
851 }
852 }
853 continue;
854 }
855 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT){
856 if(sw==0){
857 //add esp,CaseTypeSize
858 compiler.codeGenerator.op_add_esp( selectSchedules.back().typeSize );
859 }
860 break;
861 }
862 if(basbuf[i]==1&&basbuf[i+1]==ESC_CASE){
863 NowCaseCp=i;
864
865 i++;
866 while(1){
867 for(i++,i2=0;;i++,i2++){
868 if(basbuf[i]=='\"'){
869 i3=GetStringInQuotation(temporary+i2,basbuf+i);
870 i+=i3-1;
871 i2+=i3-1;
872 continue;
873 }
874 if(basbuf[i]=='('){
875 i3=GetStringInPare(temporary+i2,basbuf+i);
876 i+=i3-1;
877 i2+=i3-1;
878 continue;
879 }
880 if(basbuf[i]=='['){
881 i3=GetStringInBracket(temporary+i2,basbuf+i);
882 i+=i3-1;
883 i2+=i3-1;
884 continue;
885 }
886
887 if(IsCommandDelimitation(basbuf[i])){
888 temporary[i2]=0;
889 break;
890 }
891 if(basbuf[i]==','){
892 temporary[i2]=0;
893 break;
894 }
895
896 temporary[i2]=basbuf[i];
897 }
898
899 //エラー用
900 i2=cp;
901 cp=NowCaseCp;
902
903 Type type2;
904 if( !NumOpe(temporary,type1,type2) ){
905 return;
906 }
907
908 cp=i2;
909
910 if(type1.IsObject()){
911 std::vector<const UserProc *> subs;
912 type1.GetClass().GetMethods().Enum( CALC_EQUAL, subs );
913 if( subs.size() == 0 ){
914 return;
915 }
916
917 Parameters params;
918 params.push_back( new Parameter( "", Type( type2 ) ) );
919
920 //オーバーロードを解決
921 const UserProc *pUserProc = OverloadSolution("==",subs, params, NULL);
922
923 delete params[0];
924
925 if(!pUserProc){
926 //エラー
927 return;
928 }
929
930
931 //pop edx
932 compiler.codeGenerator.op_pop(REG_EDX);
933
934 //mov ecx,dword ptr[esp]
935 compiler.codeGenerator.op_mov_RM(sizeof(long),REG_ECX,REG_ESP,0,MOD_BASE);
936
937 //push edx
938 compiler.codeGenerator.op_push(REG_EDX);
939
940 //push ecx
941 compiler.codeGenerator.op_push(REG_ECX);
942
943 //call operator_proc ※ ==演算子
944 compiler.codeGenerator.op_call(pUserProc);
945
946 //test eax,eax
947 compiler.codeGenerator.op_test(REG_EAX,REG_EAX);
948
949 //jne ...
950 selectSchedules.back().casePertialSchedules.push_back(
951 compiler.codeGenerator.op_jne( 0, sizeof(long), true )
952 );
953 }
954 else if(type1.IsDouble()){
955 ChangeTypeToDouble(type2.GetBasicType());
956
957 //fld qword ptr[esp]
958 compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);
959
960 //add esp,CaseTypeSize
961 compiler.codeGenerator.op_add_esp(selectSchedules.back().typeSize);
962
963 //fld qword ptr[esp]
964 compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);
965
966 //fcompp
967 compiler.codeGenerator.op_fcompp();
968
969 //fnstsw ax
970 compiler.codeGenerator.op_fnstsw_ax();
971
972 //test ah,40
973 compiler.codeGenerator.op_test_ah( (char)0x40 );
974
975 //jne ...
976 selectSchedules.back().casePertialSchedules.push_back(
977 compiler.codeGenerator.op_jne( 0, sizeof(long), true )
978 );
979 }
980 else if(type1.IsSingle()){
981 ChangeTypeToSingle(type2.GetBasicType());
982
983 //fld dword ptr[esp]
984 compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);
985
986 //add esp,CaseTypeSize
987 compiler.codeGenerator.op_add_esp(selectSchedules.back().typeSize);
988
989 //fld dword ptr[esp]
990 compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);
991
992 //fcompp
993 compiler.codeGenerator.op_fcompp();
994
995 //fnstsw ax
996 compiler.codeGenerator.op_fnstsw_ax();
997
998 //test ah,40
999 compiler.codeGenerator.op_test_ah( (char)0x40 );
1000
1001 //jne ...
1002 selectSchedules.back().casePertialSchedules.push_back(
1003 compiler.codeGenerator.op_jne( 0, sizeof(long), true )
1004 );
1005 }
1006 else{
1007 //その他整数型
1008
1009 //pop ebx
1010 compiler.codeGenerator.op_pop(REG_EBX);
1011
1012 //mov eax,dword ptr[esp]
1013 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_ESP, 0, MOD_BASE );
1014
1015 //cmp eax,ebx
1016 compiler.codeGenerator.op_cmp_RR( REG_EAX, REG_EBX );
1017
1018 //je ...
1019 selectSchedules.back().casePertialSchedules.push_back(
1020 compiler.codeGenerator.op_je( 0, sizeof(long), true )
1021 );
1022 }
1023
1024 if(basbuf[i]!=',') break;
1025 }
1026 }
1027 if(basbuf[i]==1&&basbuf[i+1]==ESC_CASEELSE){
1028 sw=1;
1029
1030 //jmp ...
1031 selectSchedules.back().casePertialSchedules.push_back(
1032 compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
1033 );
1034 }
1035 }
1036
1037 //レキシカルスコープをレベルアップ
1038 extern int obp;
1039 compiler.codeGenerator.lexicalScopes.Start( obp, LexicalScope::SCOPE_TYPE_SELECT );
1040
1041 //Select Case内をコンパイル
1042 CompileBuffer(ESC_ENDSELECT,0);
1043
1044 //jmp EndSelect
1045 selectSchedules.back().casePertialSchedules.push_back(
1046 compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
1047 );
1048
1049 //最終スケジュール
1050 for(i=selectSchedules.back().nowCaseSchedule;i<(int)selectSchedules.back().casePertialSchedules.size();i++){
1051 compiler.codeGenerator.opfix_JmpPertialSchedule( selectSchedules.back().casePertialSchedules[i] );
1052 }
1053
1054 //レキシカルスコープをレベルダウン
1055 compiler.codeGenerator.lexicalScopes.End();
1056
1057 selectSchedules.pop_back();
1058}
1059void OpcodeCase(char *Parameter){
1060 int i;
1061
1062 if(selectSchedules.back().typeSize==-1){
1063 SetError(30,"Case",cp);
1064 return;
1065 }
1066
1067 //jmp EndSelect
1068 selectSchedules.back().casePertialSchedules.push_back(
1069 compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
1070 );
1071
1072 i=0;
1073 while(1){
1074 //Caseスケジュール
1075 compiler.codeGenerator.opfix_JmpPertialSchedule( selectSchedules.back().casePertialSchedules[selectSchedules.back().nowCaseSchedule] );
1076 selectSchedules.back().nowCaseSchedule++;
1077
1078 i=JumpOneParameter(Parameter,i);
1079 if(Parameter[i]=='\0') break;
1080 }
1081
1082 //add esp,CaseTypeSize
1083 compiler.codeGenerator.op_add_esp(selectSchedules.back().typeSize);
1084}
1085
1086void OpcodeGosub(char *Parameter){
1087 extern HANDLE hHeap;
1088 extern int obp;
1089 int i,LineNum;
1090
1091 if(Parameter[0]=='*'){
1092 i=GetLabelAddress(Parameter+1,0);
1093
1094 if( i == -1 )
1095 {
1096 //jmp ...(schedule)
1097 compiler.codeGenerator.op_jmp_goto_schedule( (const std::string)(Parameter + 1), 0, cp );
1098 }
1099 else
1100 {
1101 //jmp ...
1102 compiler.codeGenerator.op_jmp( i-obp, sizeof(long), false, true );
1103 }
1104 }
1105 else{
1106 LineNum=atoi(Parameter);
1107 i=GetLabelAddress(0,LineNum);
1108
1109 if( i == -1 )
1110 {
1111 //jmp ...(schedule)
1112 compiler.codeGenerator.op_jmp_goto_schedule( "", LineNum, cp );
1113 }
1114 else
1115 {
1116 //jmp ...
1117 compiler.codeGenerator.op_jmp( i-obp, sizeof(long), false, true );
1118 }
1119 }
1120}
1121void OpcodeReturn(char *Parameter){
1122 if( UserProc::IsGlobalAreaCompiling() ){
1123 //Gosub~Returnとして扱う
1124
1125 //ret
1126 compiler.codeGenerator.op_ret();
1127 }
1128 else{
1129 //戻り値をセット
1130 if(Parameter[0]){
1131 const UserProc &proc = UserProc::CompilingUserProc();
1132
1133 const char *temp = "_System_ReturnValue";
1134 if(proc.GetName()[0]==1&&proc.GetName()[1]==ESC_OPERATOR)
1135 {
1136 }
1137 else{
1138 temp=proc.GetName().c_str();
1139 }
1140
1141 char temporary[VN_SIZE];
1142 sprintf(temporary,"%s=%s",temp,Parameter);
1143 OpcodeCalc(temporary);
1144 }
1145
1146 //プロシージャを抜け出す(C言語のreturnと同様の処理を行う)
1147 OpcodeExitSub();
1148 }
1149}
1150
1151
1152////////////
1153// ポインタ
1154
1155void OpcodeSetPtrData(char *Parameter,int type){
1156 int i;
1157 char temporary[VN_SIZE];
1158
1159 if(Parameter[0]=='('){
1160 i=JumpStringInPare(Parameter,1);
1161 if(Parameter[i+1]=='\0'){
1162 for(i=0;;i++){
1163 Parameter[i]=Parameter[i+1];
1164 if(Parameter[i]=='\0') break;
1165 }
1166 Parameter[i-1]=0;
1167 }
1168 }
1169
1170 //第1パラメータを取得
1171 i=GetOneParameter(Parameter,0,temporary);
1172 if(!Parameter[i]){
1173 SetError(1,NULL,cp);
1174 return;
1175 }
1176
1177 Type resultType;
1178 if( !NumOpe(temporary,Type(),resultType) ){
1179 return;
1180 }
1181 if(!resultType.IsWhole()){
1182 SetError(11,Parameter,cp);
1183 return;
1184 }
1185
1186 ChangeTypeToLong( resultType.GetBasicType() );
1187
1188 //第2パラメータを取得
1189 i=GetOneParameter(Parameter,i,temporary);
1190 if(Parameter[i]){
1191 SetError(1,NULL,cp);
1192 return;
1193 }
1194
1195 if( !NumOpe(temporary,Type(),resultType) ){
1196 return;
1197 }
1198
1199 if(type==DEF_DOUBLE){
1200 ChangeTypeToDouble_ToFpuReg( resultType.GetBasicType() );
1201
1202 //pop eax
1203 compiler.codeGenerator.op_pop(REG_EAX);
1204
1205 //fstp qword ptr[eax]
1206 compiler.codeGenerator.PutOld(
1207 (char)0xDD,
1208 (char)0x18
1209 );
1210 }
1211 else if(type==DEF_SINGLE){
1212 ChangeTypeToSingle( resultType.GetBasicType() );
1213
1214 //pop ebx
1215 compiler.codeGenerator.op_pop(REG_EBX);
1216
1217 //pop eax
1218 compiler.codeGenerator.op_pop(REG_EAX);
1219
1220 //mov dword ptr[eax],ebx
1221 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EBX, REG_EAX, 0, MOD_BASE );
1222 }
1223 else if(type==DEF_QWORD){
1224 ChangeTypeToInt64( resultType.GetBasicType() );
1225
1226 //pop ecx
1227 compiler.codeGenerator.op_pop(REG_ECX);
1228
1229 //pop ebx
1230 compiler.codeGenerator.op_pop(REG_EBX);
1231
1232 //pop eax
1233 compiler.codeGenerator.op_pop(REG_EAX);
1234
1235 //mov dword ptr[eax],ecx
1236 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_ECX, REG_EAX, 0, MOD_BASE );
1237
1238 //mov dword ptr[eax+sizeof(long)],ebx
1239 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EBX, REG_EAX, 0x04, MOD_BASE_DISP8 );
1240 }
1241 else if(type==DEF_DWORD){
1242 ChangeTypeToLong( resultType.GetBasicType() );
1243
1244 //pop ebx
1245 compiler.codeGenerator.op_pop(REG_EBX);
1246
1247 //pop eax
1248 compiler.codeGenerator.op_pop(REG_EAX);
1249
1250 //mov dword ptr[eax],ebx
1251 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EBX, REG_EAX, 0, MOD_BASE );
1252 }
1253 else if(type==DEF_WORD){
1254 ChangeTypeToLong( resultType.GetBasicType() );
1255
1256 //pop ebx
1257 compiler.codeGenerator.op_pop(REG_EBX);
1258
1259 //pop eax
1260 compiler.codeGenerator.op_pop(REG_EAX);
1261
1262 //mov word ptr[eax],bx
1263 compiler.codeGenerator.op_mov_MR( sizeof(short), REG_EBX, REG_EAX, 0, MOD_BASE );
1264 }
1265 else if(type==DEF_BYTE){
1266 ChangeTypeToLong( resultType.GetBasicType() );
1267
1268 //pop ebx
1269 compiler.codeGenerator.op_pop(REG_EBX);
1270
1271 //pop eax
1272 compiler.codeGenerator.op_pop(REG_EAX);
1273
1274 //mov byte ptr[eax],bl
1275 compiler.codeGenerator.op_mov_MR( sizeof(char), REG_EBX, REG_EAX, 0, MOD_BASE );
1276 }
1277}
Note: See TracBrowser for help on using the repository browser.