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

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