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

Last change on this file since 326 was 326, checked in by dai_9181, 17 years ago

メソッドの重複チェックで戻り値も判定するよにうにした

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