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

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