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

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

・ジェネリックな型をパラメータに持つメソッドのオーバーロード解決に対応した。
・型パラメータの制約クラス指定に対応した。

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, Type( DEF_BOOLEAN ), type1 );
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.