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

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

UserProc::SetParamsAndReturnTypeメソッドをリファクタリング
LexicalAnalysis.hのインクルードを除去した

File size: 32.7 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, false, 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 extern HANDLE hHeap;
926 extern char *basbuf;
927 int i,i2,i3,sw,NowCaseCp;
928 char temporary[VN_SIZE];
929
930 Type type1;
931 if( !NumOpe(lpszParms,Type(), type1 ) ){
932 return;
933 }
934
935 selectSchedules.push_back( SelectSchedule( type1.GetSize() ) );
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, NULL);
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 compiler.codeGenerator.lexicalScopes.Start( compiler.codeGenerator.GetNativeCodeSize(), LexicalScope::SCOPE_TYPE_SELECT );
1141
1142 //Select Case内をコンパイル
1143 CompileBuffer(ESC_ENDSELECT,0);
1144
1145 //jmp EndSelect
1146 selectSchedules.back().casePertialSchedules.push_back(
1147 compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
1148 );
1149
1150 //最終スケジュール
1151 for(i=selectSchedules.back().nowCaseSchedule;i<(int)selectSchedules.back().casePertialSchedules.size();i++){
1152 compiler.codeGenerator.opfix_JmpPertialSchedule( selectSchedules.back().casePertialSchedules[i] );
1153 }
1154
1155 //レキシカルスコープをレベルダウン
1156 compiler.codeGenerator.lexicalScopes.End();
1157
1158 selectSchedules.pop_back();
1159}
1160void OpcodeCase(char *Parameter){
1161 int i;
1162
1163 if(selectSchedules.back().typeSize==-1){
1164 SetError(30,"Case",cp);
1165 return;
1166 }
1167
1168 //jmp EndSelect
1169 selectSchedules.back().casePertialSchedules.push_back(
1170 compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
1171 );
1172
1173 i=0;
1174 while(1){
1175 //Caseスケジュール
1176 compiler.codeGenerator.opfix_JmpPertialSchedule( selectSchedules.back().casePertialSchedules[selectSchedules.back().nowCaseSchedule] );
1177 selectSchedules.back().nowCaseSchedule++;
1178
1179 i=JumpOneParameter(Parameter,i);
1180 if(Parameter[i]=='\0') break;
1181 }
1182
1183 //add esp,CaseTypeSize
1184 compiler.codeGenerator.op_add_esp(selectSchedules.back().typeSize);
1185}
1186
1187void OpcodeGosub(char *Parameter){
1188 extern HANDLE hHeap;
1189 int i,LineNum;
1190
1191 if(Parameter[0]=='*'){
1192 i=GetLabelAddress(Parameter+1,0);
1193
1194 if( i == -1 )
1195 {
1196 //jmp ...(schedule)
1197 compiler.codeGenerator.op_jmp_goto_schedule( (const std::string)(Parameter + 1), 0, cp );
1198 }
1199 else
1200 {
1201 //jmp ...
1202 compiler.codeGenerator.op_jmp(
1203 i-compiler.codeGenerator.GetNativeCodeSize(),
1204 sizeof(long),
1205 false,
1206 true
1207 );
1208 }
1209 }
1210 else{
1211 LineNum=atoi(Parameter);
1212 i=GetLabelAddress(0,LineNum);
1213
1214 if( i == -1 )
1215 {
1216 //jmp ...(schedule)
1217 compiler.codeGenerator.op_jmp_goto_schedule( "", LineNum, cp );
1218 }
1219 else
1220 {
1221 //jmp ...
1222 compiler.codeGenerator.op_jmp(
1223 i-compiler.codeGenerator.GetNativeCodeSize(),
1224 sizeof(long),
1225 false,
1226 true
1227 );
1228 }
1229 }
1230}
1231void OpcodeReturn(char *Parameter){
1232 if( UserProc::IsGlobalAreaCompiling() ){
1233 //Gosub~Returnとして扱う
1234
1235 //ret
1236 compiler.codeGenerator.op_ret();
1237 }
1238 else{
1239 //戻り値をセット
1240 if(Parameter[0]){
1241 const UserProc &proc = UserProc::CompilingUserProc();
1242
1243 const char *temp = "_System_ReturnValue";
1244 if(proc.GetName()[0]==1&&proc.GetName()[1]==ESC_OPERATOR)
1245 {
1246 }
1247 else{
1248 temp=proc.GetName().c_str();
1249 }
1250
1251 char temporary[VN_SIZE];
1252 sprintf(temporary,"%s=%s",temp,Parameter);
1253 OpcodeCalc(temporary);
1254 }
1255
1256 //プロシージャを抜け出す(C言語のreturnと同様の処理を行う)
1257 OpcodeExitSub();
1258 }
1259}
1260
1261
1262////////////
1263// ポインタ
1264
1265void OpcodeSetPtrData(char *Parameter,int type){
1266 int i;
1267 char temporary[VN_SIZE];
1268
1269 if(Parameter[0]=='('){
1270 i=JumpStringInPare(Parameter,1);
1271 if(Parameter[i+1]=='\0'){
1272 for(i=0;;i++){
1273 Parameter[i]=Parameter[i+1];
1274 if(Parameter[i]=='\0') break;
1275 }
1276 Parameter[i-1]=0;
1277 }
1278 }
1279
1280 //第1パラメータを取得
1281 i=GetOneParameter(Parameter,0,temporary);
1282 if(!Parameter[i]){
1283 SetError(1,NULL,cp);
1284 return;
1285 }
1286
1287 Type resultType;
1288 if( !NumOpe(temporary,Type(),resultType) ){
1289 return;
1290 }
1291 if(!resultType.IsWhole()){
1292 SetError(11,Parameter,cp);
1293 return;
1294 }
1295
1296 ChangeTypeToLong( resultType.GetBasicType() );
1297
1298 //第2パラメータを取得
1299 i=GetOneParameter(Parameter,i,temporary);
1300 if(Parameter[i]){
1301 SetError(1,NULL,cp);
1302 return;
1303 }
1304
1305 if( !NumOpe(temporary,Type(),resultType) ){
1306 return;
1307 }
1308
1309 if(type==DEF_DOUBLE){
1310 ChangeTypeToDouble_ToFpuReg( resultType.GetBasicType() );
1311
1312 //pop eax
1313 compiler.codeGenerator.op_pop(REG_EAX);
1314
1315 //fstp qword ptr[eax]
1316 compiler.codeGenerator.PutOld(
1317 (char)0xDD,
1318 (char)0x18
1319 );
1320 }
1321 else if(type==DEF_SINGLE){
1322 ChangeTypeToSingle( resultType.GetBasicType() );
1323
1324 //pop ebx
1325 compiler.codeGenerator.op_pop(REG_EBX);
1326
1327 //pop eax
1328 compiler.codeGenerator.op_pop(REG_EAX);
1329
1330 //mov dword ptr[eax],ebx
1331 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EBX, REG_EAX, 0, MOD_BASE );
1332 }
1333 else if(type==DEF_QWORD){
1334 ChangeTypeToInt64( resultType.GetBasicType() );
1335
1336 //pop ecx
1337 compiler.codeGenerator.op_pop(REG_ECX);
1338
1339 //pop ebx
1340 compiler.codeGenerator.op_pop(REG_EBX);
1341
1342 //pop eax
1343 compiler.codeGenerator.op_pop(REG_EAX);
1344
1345 //mov dword ptr[eax],ecx
1346 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_ECX, REG_EAX, 0, MOD_BASE );
1347
1348 //mov dword ptr[eax+sizeof(long)],ebx
1349 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EBX, REG_EAX, 0x04, MOD_BASE_DISP8 );
1350 }
1351 else if(type==DEF_DWORD){
1352 ChangeTypeToLong( resultType.GetBasicType() );
1353
1354 //pop ebx
1355 compiler.codeGenerator.op_pop(REG_EBX);
1356
1357 //pop eax
1358 compiler.codeGenerator.op_pop(REG_EAX);
1359
1360 //mov dword ptr[eax],ebx
1361 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EBX, REG_EAX, 0, MOD_BASE );
1362 }
1363 else if(type==DEF_WORD){
1364 ChangeTypeToLong( resultType.GetBasicType() );
1365
1366 //pop ebx
1367 compiler.codeGenerator.op_pop(REG_EBX);
1368
1369 //pop eax
1370 compiler.codeGenerator.op_pop(REG_EAX);
1371
1372 //mov word ptr[eax],bx
1373 compiler.codeGenerator.op_mov_MR( sizeof(short), REG_EBX, REG_EAX, 0, MOD_BASE );
1374 }
1375 else if(type==DEF_BYTE){
1376 ChangeTypeToLong( resultType.GetBasicType() );
1377
1378 //pop ebx
1379 compiler.codeGenerator.op_pop(REG_EBX);
1380
1381 //pop eax
1382 compiler.codeGenerator.op_pop(REG_EAX);
1383
1384 //mov byte ptr[eax],bl
1385 compiler.codeGenerator.op_mov_MR( sizeof(char), REG_EBX, REG_EAX, 0, MOD_BASE );
1386 }
1387}
Note: See TracBrowser for help on using the repository browser.