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

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