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

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