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

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