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

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