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

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

Foreachにて自動的に一時オブジェクトを生成できるようにした

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