source: dev/trunk/abdev/BasicCompiler64/Compile_Statement.cpp@ 254

Last change on this file since 254 was 254, checked in by dai_9181, 17 years ago
File size: 20.7 KB
Line 
1#include "stdafx.h"
2
3#include <jenga/include/smoothie/LexicalAnalysis.h>
4
5#include <Compiler.h>
6
7#include "../BasicCompiler_Common/common.h"
8#include "Opcode.h"
9
10void OpcodeOthers(const char *Command){
11 int i,i2;
12
13 char leftTerm[8192];
14 int lastParePos = 0;
15 for(i=0;;i++){
16 if(Command[i]=='\"'){
17 //ダブルクォートは不正なのでエラー扱い
18 leftTerm[i]=0;
19 SetError(3,leftTerm,cp);
20 return;
21 }
22
23 if(Command[i]=='('){
24 lastParePos = i;
25 i2=GetStringInPare(leftTerm+i,Command+i);
26 i+=i2-1;
27 continue;
28 }
29 if(Command[i]=='['){
30 i2=GetStringInBracket(leftTerm+i,Command+i);
31 i+=i2-1;
32 continue;
33 }
34 if(Command[i]=='\0'){
35 leftTerm[i] = 0;
36 break;
37 }
38
39 if( IsNumCalcMark( Command, i ) ){
40 leftTerm[i] = 0;
41 break;
42 }
43
44 leftTerm[i]=Command[i];
45 }
46 if(!(
47 IsVariableTopChar(leftTerm[0])||
48 leftTerm[0]=='.'||
49 (leftTerm[0]==1&&leftTerm[1]==ESC_PSMEM)
50 )){
51 SetError(1,NULL,cp);
52 return;
53 }
54
55
56 if(Command[i]=='\0' && lastParePos == 0){
57 //////////////////////////////
58 // パラメータ無しのマクロ検索
59 //////////////////////////////
60
61 const UserProc *pUserProc=GetSubHash(Command);
62
63 //GetSubHash内でエラー提示が行われた場合
64 if(pUserProc==(UserProc *)-1) return;
65
66 if(pUserProc==0){
67 char temporary[VN_SIZE];
68 lstrcpy(temporary,Command);
69
70 CharUpper(temporary);
71 pUserProc=GetSubHash(temporary);
72
73 //GetSubHash内でエラー提示が行われた場合
74 if(pUserProc==(UserProc *)-1) return;
75 }
76
77 if(pUserProc){
78 if( !pUserProc->IsMacro() ){
79 SetError(10,Command,cp);
80 }
81
82 Opcode_CallProc("",pUserProc,0,"",0);
83
84 return;
85 }
86 }
87 else if(IsNumCalcMark(Command,i)){
88 //代入演算
89 OpcodeCalc(Command);
90 return;
91 }
92
93 if( pobj_reg ){
94 SetError();
95 }
96 pobj_reg=new CRegister(REG_RAX);
97
98 Type resultType;
99 bool isLiteral;
100 BOOL bUseHeap;
101 bool result = TermOpe( leftTerm, Type(), resultType, isLiteral, &bUseHeap, false, NULL, true );
102
103 delete pobj_reg;
104 pobj_reg = NULL;
105
106 if( result ){
107
108 /////////////////////
109 // 戻り値の処理
110 /////////////////////
111
112 if( resultType.IsStruct() ){
113 //mov r14,rax
114 compiler.codeGenerator.op_mov_RR(REG_R14,REG_RAX);
115
116 FreeTempObject(REG_R14,&resultType.GetClass());
117 }
118
119 //成功
120 return;
121 }
122
123 // 失敗
124 SetError(1, NULL,cp);
125}
126
127void Judgment(char *buffer){
128 int reg=REG_RAX;
129 Type resultType;
130 if( !NumOpe(&reg,buffer,Type(),resultType) ){
131 return;
132 }
133
134 int offset;
135
136 if(resultType.IsDouble()){
137 double dbl=0;
138 offset=compiler.GetDataTable().Add( dbl );
139
140 //comisd xmm0,qword ptr[data table offset]
141 compiler.codeGenerator.PutOld(
142 (char)0x66,
143 (char)0x0F,
144 (char)0x2F,
145 (char)0x04,
146 (char)0x25
147 );
148 compiler.codeGenerator.PutOld(
149 (long)offset,
150 Schedule::DataTable
151 );
152 }
153 else if(resultType.IsSingle()){
154 float flt=0;
155 offset=compiler.GetDataTable().Add( flt );
156
157 //comiss xmm0,dword ptr[data table offset]
158 compiler.codeGenerator.PutOld(
159 (char)0x0F,
160 (char)0x2F,
161 (char)0x04,
162 (char)0x25
163 );
164 compiler.codeGenerator.PutOld(
165 (long)offset,
166 Schedule::DataTable
167 );
168 }
169 else{
170 //整数型
171
172 //cmp rax,0
173 compiler.codeGenerator.op_cmp_value(resultType.GetSize(),REG_RAX,0);
174 }
175}
176
177void OpcodeIf(char *Parameter){
178 for(int i=0;;i++){
179 if(Parameter[i]=='\0'){
180 SetError(21,NULL,cp);
181 return;
182 }
183 if(Parameter[i]==1&&Parameter[i+1]==ESC_THEN){
184 Parameter[i]=0;
185 break;
186 }
187 }
188
189 //条件式を実行してフラグをセット
190 Judgment(Parameter);
191
192 //je (endif、または else まで条件ジャンプ)
193 const PertialSchedule *pIfPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
194
195
196 /////////////////////////
197 // If内をコード化
198 /////////////////////////
199
200 //レキシカルスコープをレベルアップ
201 compiler.codeGenerator.lexicalScopes.Start( obp, LexicalScope::SCOPE_TYPE_IF );
202
203 int i2=CompileBuffer(ESC_ENDIF,0);
204
205 //レキシカルスコープをレベルダウン
206 compiler.codeGenerator.lexicalScopes.End();
207
208
209 if(i2==ESC_ELSE){
210 //jmp (endifまで)
211 const PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
212
213 compiler.codeGenerator.opfix_JmpPertialSchedule( pIfPertialSchedule );
214
215
216
217 /////////////////////////
218 // Else内をコード化
219 /////////////////////////
220
221 //レキシカルスコープをレベルアップ
222 compiler.codeGenerator.lexicalScopes.Start( obp, LexicalScope::SCOPE_TYPE_IF );
223
224 CompileBuffer(ESC_ENDIF,0);
225
226 //レキシカルスコープをレベルダウン
227 compiler.codeGenerator.lexicalScopes.End();
228
229
230 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
231 }
232 else{
233 compiler.codeGenerator.opfix_JmpPertialSchedule( pIfPertialSchedule );
234 }
235}
236
237int GetLabelAddress(char *LabelName,int LineNum){
238 extern int MaxLabelNum;
239 extern LABEL *pLabelNames;
240 int i;
241
242 if(LabelName){
243 for(i=0;i<MaxLabelNum;i++){
244 if(pLabelNames[i].pName){
245 if(lstrcmp(LabelName,pLabelNames[i].pName)==0) return pLabelNames[i].address;
246 }
247 }
248 }
249 else{
250 for(i=0;i<MaxLabelNum;i++){
251 if(pLabelNames[i].pName==0){
252 if(LineNum==pLabelNames[i].line) return pLabelNames[i].address;
253 }
254 }
255 }
256 return -1;
257}
258void OpcodeGoto(char *Parameter){
259 extern HANDLE hHeap;
260 int i,LineNum;
261
262 if(Parameter[0]=='*'){
263 i=GetLabelAddress(Parameter+1,0);
264
265 if( i == -1 )
266 {
267 //jmp ...(schedule)
268 extern int obp;
269 compiler.codeGenerator.op_jmp_goto_schedule( (const std::string)(Parameter + 1), 0, cp );
270 }
271 else
272 {
273 //jmp ...
274 extern int obp;
275 compiler.codeGenerator.op_jmp( i-obp, sizeof(long), false, true );
276 }
277 }
278 else{
279 LineNum=atoi(Parameter);
280 i=GetLabelAddress(0,LineNum);
281
282 if( i == -1 )
283 {
284 //jmp ...(schedule)
285 extern int obp;
286 compiler.codeGenerator.op_jmp_goto_schedule( "", LineNum, cp );
287 }
288 else
289 {
290 //jmp ...
291 extern int obp;
292 compiler.codeGenerator.op_jmp( i-obp, sizeof(long), false, true );
293 }
294 }
295}
296void OpcodeWhile(char *Parameter){
297 extern HANDLE hHeap;
298
299 //Continueアドレスのバックアップとセット
300 compiler.codeGenerator.ContinueAreaBegin();
301
302 if(!Parameter[0]) SetError(10,"While",cp);
303
304 //条件式を実行してフラグをセット
305 Judgment(Parameter);
306
307 //je (Wend まで)
308 const PertialSchedule *pWhilePertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
309
310 //レキシカルスコープをレベルアップ
311 compiler.codeGenerator.lexicalScopes.Start( obp, LexicalScope::SCOPE_TYPE_WHILE );
312
313 //While内をコンパイル
314 CompileBuffer(0,COM_WEND);
315
316 compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd();
317
318 //jmp ...
319 compiler.codeGenerator.op_jmp_continue();
320
321 //レキシカルスコープをレベルダウン
322 compiler.codeGenerator.lexicalScopes.End();
323
324 compiler.codeGenerator.opfix_JmpPertialSchedule( pWhilePertialSchedule );
325
326 //Continueアドレスを復元
327 compiler.codeGenerator.ContinueAreaEnd();
328}
329
330char szNextVariable[VN_SIZE];
331void OpcodeFor(char *Parameter){
332 extern HANDLE hHeap;
333 Type resultType;
334 int i,i2;
335 char temporary[VN_SIZE],variable[VN_SIZE],JudgeNum[VN_SIZE],StepNum[VN_SIZE];
336 bool isError = false;
337
338 //第1パラメータを取得
339 i=GetOneParameter(Parameter,0,temporary);
340 if(!Parameter[i]){
341 SetError(12,"For",cp);
342 isError = true;
343 goto ErrorStep;
344 }
345
346 for(i2=0;;i2++){
347 if(temporary[i2]=='='){
348 variable[i2]=0;
349
350 //カウンタ初期化
351 OpcodeCalc(temporary);
352 break;
353 }
354 if(temporary[i2]=='\0'){
355 SetError(12,"For",cp);
356 isError = true;
357 goto ErrorStep;
358 }
359 variable[i2]=temporary[i2];
360 }
361
362 //jmp ...
363 const PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
364
365 //Continueアドレスのバックアップとセット
366 compiler.codeGenerator.ContinueAreaBegin();
367
368 //第2パラメータを取得(to~)
369 i=GetOneParameter(Parameter,i,JudgeNum);
370
371 //第3パラメータを取得(step~)
372 if(Parameter[i]){
373 i=GetOneParameter(Parameter,i,StepNum);
374 if(Parameter[i]) SetError(12,"For",cp);
375 }
376 else lstrcpy(StepNum,"1");
377
378 //カウンタを増加させる
379 sprintf(temporary,"%s=(%s)+(%s)",variable,variable,StepNum);
380 OpcodeCalc(temporary);
381
382 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
383
384 //増加か減少かを区別する
385 sprintf(temporary,"(%s)>=0",StepNum);
386
387 int reg;
388 reg=REG_RAX;
389 if( !NumOpe(&reg,temporary,Type(),resultType) ){
390 return;
391 }
392
393 //cmp rax,0
394 compiler.codeGenerator.op_cmp_value(resultType.GetSize(),REG_RAX,0);
395
396 //je [カウンタ減少の場合の判定]
397 pTempPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
398
399 //判定(カウンタ増加の場合)
400 sprintf(temporary,"%s<=(%s)",variable,JudgeNum);
401
402 reg=REG_RAX;
403 NumOpe(&reg,temporary,Type(),Type());
404
405 //jmp [カウンタ減少の場合の判定を飛び越す]
406 const PertialSchedule *pTempPertialSchedule2 = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
407
408 //jeジャンプ先のオフセット値
409 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
410
411 //判定(カウンタ減少の場合)
412 sprintf(temporary,"%s>=(%s)",variable,JudgeNum);
413
414 reg=REG_RAX;
415 NumOpe(&reg,temporary,Type(),resultType);
416
417 //jmpジャンプ先のオフセット値
418 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule2 );
419
420 //cmp rax,0
421 compiler.codeGenerator.op_cmp_value(resultType.GetSize(),REG_RAX,0);
422
423ErrorStep:
424
425 //je ...
426 pTempPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
427
428 //レキシカルスコープをレベルアップ
429 compiler.codeGenerator.lexicalScopes.Start( obp, LexicalScope::SCOPE_TYPE_FOR );
430
431 //For内をコンパイル
432 CompileBuffer(0,COM_NEXT);
433
434 compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd();
435
436 if(szNextVariable[0]){
437 if(lstrcmp(szNextVariable,variable)!=0){
438 SetError(55,szNextVariable,cp);
439 }
440 }
441
442 //jmp ...
443 compiler.codeGenerator.op_jmp_continue();
444
445 //レキシカルスコープをレベルダウン
446 compiler.codeGenerator.lexicalScopes.End();
447
448 //jeジャンプ先のオフセット値
449 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
450
451 //Continueアドレスを復元
452 compiler.codeGenerator.ContinueAreaEnd();
453}
454
455void OpcodeDo(char *Parameter){
456 extern HANDLE hHeap;
457 int i,i2,i3;
458
459 if(Parameter[0]) SetError(10,"Do",cp);
460
461 //Continueアドレスのバックアップとセット
462 compiler.codeGenerator.ContinueAreaBegin();
463
464 //レキシカルスコープをレベルアップ
465 compiler.codeGenerator.lexicalScopes.Start( obp, LexicalScope::SCOPE_TYPE_DO );
466
467 //Do内をコンパイル
468 CompileBuffer(0,COM_LOOP);
469
470 compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd();
471
472 const PertialSchedule *pDoPertialSchedule = NULL;
473
474 extern char *basbuf;
475 char temporary[VN_SIZE];
476 for(i=cp-1;;i--){
477 if(IsCommandDelimitation(basbuf[i])){
478 i+=3;
479 if(!(basbuf[i]=='0'||basbuf[i]=='1')){
480 //無条件ループ
481 break;
482 }
483 i3=i;
484
485 for(i+=2,i2=0;;i++,i2++){
486 if(IsCommandDelimitation(basbuf[i])){
487 temporary[i2]=0;
488 break;
489 }
490 temporary[i2]=basbuf[i];
491 }
492
493 //条件式を実行してフラグをセット
494 Judgment(temporary);
495
496 if(basbuf[i3]=='0'){
497 //While
498
499 //je 5(ループ終了)
500 pDoPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(char), true );
501 }
502 else if(basbuf[i3]=='1'){
503 //Until
504
505 //jne 5(ループ終了)
506 pDoPertialSchedule = compiler.codeGenerator.op_jne( 0, sizeof(char), true );
507 }
508 break;
509 }
510 }
511
512 //jmp ...
513 compiler.codeGenerator.op_jmp_continue();
514
515 if( pDoPertialSchedule )
516 {
517 compiler.codeGenerator.opfix_JmpPertialSchedule( pDoPertialSchedule );
518 }
519
520 //jmp ...
521 const PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
522
523 //レキシカルスコープをレベルダウン
524 compiler.codeGenerator.lexicalScopes.End();
525
526 //jmpジャンプ先のオフセット値
527 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
528
529 //Continueアドレスを復元
530 compiler.codeGenerator.ContinueAreaEnd();
531}
532void OpcodeContinue(void){
533 //jmp ...(Continue addr)
534 compiler.codeGenerator.op_jmp_continue();
535}
536
537void OpcodeExitSub(void){
538 if( UserProc::IsGlobalAreaCompiling() ){
539 SetError(12,"Exit Sub/Function",cp);
540 return;
541 }
542
543 //未解放のローカルオブジェクトのデストラクタを呼び出す
544 compiler.codeGenerator.lexicalScopes.CallDestructorsOfReturn();
545
546 //jmp ...(End Sub/Function)
547 compiler.codeGenerator.op_jmp_exitsub();
548}
549
550//Caseスケジュール
551class SelectSchedule
552{
553public:
554 SelectSchedule( int typeSize )
555 : typeSize( typeSize )
556 , nowCaseSchedule( 0 )
557 {
558 }
559
560 PertialSchedules casePertialSchedules;
561 int typeSize;
562 int nowCaseSchedule;
563};
564std::vector<SelectSchedule> selectSchedules;
565
566void OpcodeSelect( const char *lpszParms ){
567 extern HANDLE hHeap;
568 extern char *basbuf;
569 int i,i2,i3,NowCaseCp;
570 char temporary[VN_SIZE];
571
572 int reg1=REG_RAX;
573 Type type1;
574 if( !NumOpe(&reg1,lpszParms,Type(), type1 ) ){
575 return;
576 }
577
578 selectSchedules.push_back( SelectSchedule( type1.GetSize() ) );
579
580 if( selectSchedules.back().typeSize < sizeof(long) ){
581 selectSchedules.back().typeSize = sizeof(long);
582 }
583
584 if(type1.IsDouble()){
585 //movsd qword ptr[rsp+offset],xmm_reg ※スタックフレームを利用
586 pobj_sf->push(reg1,sizeof(double));
587 }
588 else if(type1.IsSingle()){
589 //movss dword ptr[rsp+offset],xmm_reg ※スタックフレームを利用
590 pobj_sf->push(reg1,sizeof(float));
591 }
592 else{
593 ExtendTypeTo64(type1.GetBasicType(),reg1);
594
595 //mov qword ptr[rsp+offset],reg ※スタックフレームを利用
596 pobj_sf->push(reg1);
597 }
598
599 for(i=cp;;i++){
600 if(basbuf[i]=='\0'){
601 selectSchedules.pop_back();
602 SetError(22,"Select",cp);
603 return;
604 }
605 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE){
606 for(i2=0;;i++){
607 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE) i2++;
608 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT){
609 i2--;
610 if(i2==0) break;
611 }
612 }
613 continue;
614 }
615 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT) break;
616
617 if(basbuf[i]==1&&basbuf[i+1]==ESC_CASE){
618 NowCaseCp=i;
619
620 i++;
621 while(1){
622 for(i++,i2=0;;i++,i2++){
623 if(basbuf[i]=='\"'){
624 i3=GetStringInQuotation(temporary+i2,basbuf+i);
625 i+=i3-1;
626 i2+=i3-1;
627 continue;
628 }
629 if(basbuf[i]=='('){
630 i3=GetStringInPare(temporary+i2,basbuf+i);
631 i+=i3-1;
632 i2+=i3-1;
633 continue;
634 }
635 if(basbuf[i]=='['){
636 i3=GetStringInBracket(temporary+i2,basbuf+i);
637 i+=i3-1;
638 i2+=i3-1;
639 continue;
640 }
641
642 if(IsCommandDelimitation(basbuf[i])){
643 temporary[i2]=0;
644 break;
645 }
646 if(basbuf[i]==','){
647 temporary[i2]=0;
648 break;
649 }
650
651 temporary[i2]=basbuf[i];
652 }
653
654 //エラー用
655 i2=cp;
656 cp=NowCaseCp;
657
658 int reg2=REG_RDX;
659 Type type2;
660 if( !NumOpe(&reg2,temporary,type1,type2) ){
661 return;
662 }
663
664 cp=i2;
665
666 if(type1.IsObject()){
667 std::vector<const UserProc *> subs;
668 type1.GetClass().GetMethods().Enum( CALC_EQUAL, subs );
669 if( subs.size() == 0 ){
670 return;
671 }
672
673 Parameters params;
674 params.push_back( new Parameter( "", Type( type2 ) ) );
675
676 //オーバーロードを解決
677 const UserProc *pUserProc = OverloadSolution("==",subs, params, NULL);
678
679 delete params[0];
680
681 if(!pUserProc){
682 //エラー
683 return;
684 }
685
686
687 //実体オブジェクト
688 if(reg2!=REG_RDX){
689 //mov rdx,reg2
690 compiler.codeGenerator.op_mov_RR(REG_RDX,reg2);
691 }
692
693 //mov rcx,qword ptr[rsp+offset] ※スタックフレームから参照
694 pobj_sf->ref(REG_RCX);
695
696 //call operator_proc ※ ==演算子
697 compiler.codeGenerator.op_call(pUserProc);
698
699 //test rax,rax
700 compiler.codeGenerator.op_test(REG_RAX,REG_RAX);
701
702 //jne ...
703 selectSchedules.back().casePertialSchedules.push_back(
704 compiler.codeGenerator.op_jne( 0, sizeof(long), true )
705 );
706 }
707 else{
708 if(type1.IsDouble()){
709 int xmm_reg;
710 if(IsXmmReg(reg2)) xmm_reg=reg2;
711 else xmm_reg=REG_XMM5;
712 ChangeTypeToXmm_Double(type2.GetBasicType(),xmm_reg,reg2);
713
714 //movsd xmm4,qword ptr[rsp+offset] ※スタックフレームから参照
715 pobj_sf->ref(REG_XMM4,sizeof(double));
716
717 //comiss xmm_reg1,xmm_reg2
718 compiler.codeGenerator.op_comisd(xmm_reg,REG_XMM4);
719 }
720 else if(type1.IsSingle()){
721 int xmm_reg;
722 if(IsXmmReg(reg2)) xmm_reg=reg2;
723 else xmm_reg=REG_XMM5;
724 ChangeTypeToXmm_Single(type2.GetBasicType(),xmm_reg,reg2);
725
726 //movss xmm4,dword ptr[rsp+offset] ※スタックフレームから参照
727 pobj_sf->ref(REG_XMM4,sizeof(float));
728
729 //comiss xmm_reg1,xmm_reg2
730 compiler.codeGenerator.op_comiss(xmm_reg,REG_XMM4);
731 }
732 else{
733 //その他整数型
734
735 i2=NeutralizationType(type1.GetBasicType(),-1,type2.GetBasicType(),-1);
736
737 //mov r14,qword ptr[rsp+offset] ※スタックフレームから参照
738 pobj_sf->ref(REG_R14);
739
740 //cmp reg2,r14
741 compiler.codeGenerator.op_cmp_reg(GetTypeSize(i2,-1),reg2,REG_R14);
742 }
743
744 //je ...
745 selectSchedules.back().casePertialSchedules.push_back(
746 compiler.codeGenerator.op_je( 0, sizeof(long), true )
747 );
748 }
749
750 if(basbuf[i]!=',') break;
751 }
752 }
753 if(basbuf[i]==1&&basbuf[i+1]==ESC_CASEELSE){
754 //jmp ...
755 selectSchedules.back().casePertialSchedules.push_back(
756 compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
757 );
758 }
759 }
760
761 //スタックフレームを1スペースだけ解除
762 pobj_sf->pop(REG_NON);
763
764 //レキシカルスコープをレベルアップ
765 compiler.codeGenerator.lexicalScopes.Start( obp, LexicalScope::SCOPE_TYPE_SELECT );
766
767 //Select Case内をコンパイル
768 CompileBuffer(ESC_ENDSELECT,0);
769
770 //jmp EndSelect
771 selectSchedules.back().casePertialSchedules.push_back(
772 compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
773 );
774
775 //最終スケジュール
776 for(i=selectSchedules.back().nowCaseSchedule;i<(int)selectSchedules.back().casePertialSchedules.size();i++){
777 compiler.codeGenerator.opfix_JmpPertialSchedule( selectSchedules.back().casePertialSchedules[i] );
778 }
779
780 //レキシカルスコープをレベルダウン
781 compiler.codeGenerator.lexicalScopes.End();
782
783 selectSchedules.pop_back();
784}
785void OpcodeCase(char *Parameter){
786 int i;
787
788 if(selectSchedules.back().typeSize==-1){
789 SetError(30,"Case",cp);
790 return;
791 }
792
793 //jmp EndSelect
794 selectSchedules.back().casePertialSchedules.push_back(
795 compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
796 );
797
798 i=0;
799 while(1){
800 //Caseスケジュール
801 compiler.codeGenerator.opfix_JmpPertialSchedule( selectSchedules.back().casePertialSchedules[selectSchedules.back().nowCaseSchedule] );
802 selectSchedules.back().nowCaseSchedule++;
803
804 i=JumpOneParameter(Parameter,i);
805 if(Parameter[i]=='\0') break;
806 }
807}
808
809void OpcodeGosub(char *Parameter){
810 SetError(-1,"Gosub ~ Returnステートメントは64ビットコンパイラで利用することはできません。",cp);
811}
812void OpcodeReturn(char *Parameter){
813 if( UserProc::IsGlobalAreaCompiling() ){
814 SetError(62,NULL,cp);
815 }
816 else{
817 //戻り値をセット
818 if(Parameter[0]){
819 const UserProc &proc = UserProc::CompilingUserProc();
820
821 const char *temp = "_System_ReturnValue";
822 if(proc.GetName()[0]==1&&proc.GetName()[1]==ESC_OPERATOR)
823 {
824 }
825 else{
826 temp=proc.GetName().c_str();
827 }
828
829 char temporary[VN_SIZE];
830 sprintf(temporary,"%s=%s",temp,Parameter);
831 OpcodeCalc(temporary);
832 }
833
834 //プロシージャを抜け出す(C言語のreturnと同様の処理を行う)
835 OpcodeExitSub();
836 }
837}
838
839
840////////////
841// ポインタ
842////////////
843
844void OpcodeSetPtrData(char *Parameter,int type){
845 int i;
846 char temporary[VN_SIZE];
847
848 if(Parameter[0]=='('){
849 i=JumpStringInPare(Parameter,1);
850 if(Parameter[i+1]=='\0'){
851 for(i=0;;i++){
852 Parameter[i]=Parameter[i+1];
853 if(Parameter[i]=='\0') break;
854 }
855 Parameter[i-1]=0;
856 }
857 }
858
859 //第1パラメータを取得
860 i=GetOneParameter(Parameter,0,temporary);
861 if(!Parameter[i]){
862 SetError(1,NULL,cp);
863 return;
864 }
865
866 int reg_ptr=REG_RAX;
867 Type resultType;
868 if( !NumOpe(&reg_ptr,temporary,Type(),resultType) ){
869 return;
870 }
871 if(!resultType.IsWhole()){
872 SetError(11,Parameter,cp);
873 return;
874 }
875
876 //結果を格納しているレジスタをブロッキング
877 pobj_BlockReg->lock(reg_ptr);
878
879 //第2パラメータを取得
880 i=GetOneParameter(Parameter,i,temporary);
881 if(Parameter[i]){
882 SetError(1,NULL,cp);
883 return;
884 }
885
886 int temp_reg=REG_NON;
887 if( !NumOpe(&temp_reg,temporary,Type(),resultType) ){
888 return;
889 }
890
891 //レジスタのブロッキングを解除
892 pobj_BlockReg->clear();
893
894 if(type==DEF_DOUBLE){
895 ChangeTypeToXmm_Double(resultType.GetBasicType(),REG_XMM0,temp_reg);
896
897 //movsd qword ptr[reg_ptr],xmm0
898 compiler.codeGenerator.op_movsd_MR(REG_XMM0,reg_ptr,0,MOD_BASE);
899 }
900 else if(type==DEF_SINGLE){
901 ChangeTypeToXmm_Single(resultType.GetBasicType(),REG_XMM0,temp_reg);
902
903 //movss dword ptr[reg_ptr],xmm0
904 compiler.codeGenerator.op_movss_MR(REG_XMM0,reg_ptr,0,MOD_BASE);
905 }
906 else{
907 ChangeTypeToWhole(resultType.GetBasicType(),type,REG_RCX,temp_reg);
908
909 //mov ptr[reg_ptr],rcx
910 compiler.codeGenerator.op_mov_MR(GetTypeSize(type,-1),REG_RCX,reg_ptr,0,MOD_BASE);
911 }
912}
Note: See TracBrowser for help on using the repository browser.