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

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