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

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

Foreachの一時オブジェクトの初期値をNothingにした

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