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

Last change on this file since 435 was 435, checked in by dai_9181, 16 years ago

関数の戻り値の構造体など、一時メモリに保持された構造体のメンバに直接アクセスした場合、その一時メモリの解放が正常に行われないバグを修正(まずは32bit版のみ)

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