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

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

vtblの構造を変更。vtblMasterListをはさんでvtblを表現した。
その他メンバ名変更。
ClassPrototypeクラスを追加。

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