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

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

静的リンクライブラリにより、複数のグローバル領域が存在することになったのでそれぞれを関数ベースに分けた

File size: 21.0 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,"");
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.GetObjectModule().dataTable.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.GetObjectModule().dataTable.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(
202 compiler.codeGenerator.GetNativeCodeSize(),
203 LexicalScope::SCOPE_TYPE_IF
204 );
205
206 int i2=CompileBuffer(ESC_ENDIF,0);
207
208 //レキシカルスコープをレベルダウン
209 compiler.codeGenerator.lexicalScopes.End();
210
211
212 if(i2==ESC_ELSE){
213 //jmp (endifまで)
214 const PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
215
216 compiler.codeGenerator.opfix_JmpPertialSchedule( pIfPertialSchedule );
217
218
219
220 /////////////////////////
221 // Else内をコード化
222 /////////////////////////
223
224 //レキシカルスコープをレベルアップ
225 compiler.codeGenerator.lexicalScopes.Start(
226 compiler.codeGenerator.GetNativeCodeSize(),
227 LexicalScope::SCOPE_TYPE_IF
228 );
229
230 CompileBuffer(ESC_ENDIF,0);
231
232 //レキシカルスコープをレベルダウン
233 compiler.codeGenerator.lexicalScopes.End();
234
235
236 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
237 }
238 else{
239 compiler.codeGenerator.opfix_JmpPertialSchedule( pIfPertialSchedule );
240 }
241}
242
243int GetLabelAddress(char *LabelName,int LineNum){
244 if(LabelName){
245 BOOST_FOREACH( const GotoLabel &label, compiler.codeGenerator.gotoLabels )
246 {
247 if( label.name.size() > 0 )
248 {
249 if( label.name == LabelName )
250 {
251 return label.address;
252 }
253 }
254 }
255 }
256 else{
257 BOOST_FOREACH( const GotoLabel &label, compiler.codeGenerator.gotoLabels )
258 {
259 if( label.name.size() == 0 )
260 {
261 if( label.line == LineNum )
262 {
263 return label.address;
264 }
265 }
266 }
267 }
268 return -1;
269}
270void OpcodeGoto(char *Parameter){
271 extern HANDLE hHeap;
272 int i,LineNum;
273
274 if(Parameter[0]=='*'){
275 i=GetLabelAddress(Parameter+1,0);
276
277 if( i == -1 )
278 {
279 //jmp ...(schedule)
280 compiler.codeGenerator.op_jmp_goto_schedule( (const std::string)(Parameter + 1), 0, cp );
281 }
282 else
283 {
284 //jmp ...
285 compiler.codeGenerator.op_jmp(
286 i-compiler.codeGenerator.GetNativeCodeSize(),
287 sizeof(long),
288 false,
289 true
290 );
291 }
292 }
293 else{
294 LineNum=atoi(Parameter);
295 i=GetLabelAddress(0,LineNum);
296
297 if( i == -1 )
298 {
299 //jmp ...(schedule)
300 compiler.codeGenerator.op_jmp_goto_schedule( "", LineNum, cp );
301 }
302 else
303 {
304 //jmp ...
305 compiler.codeGenerator.op_jmp(
306 i-compiler.codeGenerator.GetNativeCodeSize(),
307 sizeof(long),
308 false,
309 true
310 );
311 }
312 }
313}
314void OpcodeWhile(char *Parameter){
315 extern HANDLE hHeap;
316
317 //Continueアドレスのバックアップとセット
318 compiler.codeGenerator.ContinueAreaBegin();
319
320 if(!Parameter[0]) SetError(10,"While",cp);
321
322 //条件式を実行してフラグをセット
323 Judgment(Parameter);
324
325 //je (Wend まで)
326 const PertialSchedule *pWhilePertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
327
328 //レキシカルスコープをレベルアップ
329 compiler.codeGenerator.lexicalScopes.Start( compiler.codeGenerator.GetNativeCodeSize(), LexicalScope::SCOPE_TYPE_WHILE );
330
331 //While内をコンパイル
332 CompileBuffer(0,COM_WEND);
333
334 compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd();
335
336 //jmp ...
337 compiler.codeGenerator.op_jmp_continue();
338
339 //レキシカルスコープをレベルダウン
340 compiler.codeGenerator.lexicalScopes.End();
341
342 compiler.codeGenerator.opfix_JmpPertialSchedule( pWhilePertialSchedule );
343
344 //Continueアドレスを復元
345 compiler.codeGenerator.ContinueAreaEnd();
346}
347
348char szNextVariable[VN_SIZE];
349void OpcodeFor(char *Parameter){
350 extern HANDLE hHeap;
351 Type resultType;
352 int i,i2;
353 char temporary[VN_SIZE],variable[VN_SIZE],JudgeNum[VN_SIZE],StepNum[VN_SIZE];
354 bool isError = false;
355
356 //第1パラメータを取得
357 i=GetOneParameter(Parameter,0,temporary);
358 if(!Parameter[i]){
359 SetError(12,"For",cp);
360 isError = true;
361 goto ErrorStep;
362 }
363
364 for(i2=0;;i2++){
365 if(temporary[i2]=='='){
366 variable[i2]=0;
367
368 //カウンタ初期化
369 OpcodeCalc(temporary);
370 break;
371 }
372 if(temporary[i2]=='\0'){
373 SetError(12,"For",cp);
374 isError = true;
375 goto ErrorStep;
376 }
377 variable[i2]=temporary[i2];
378 }
379
380 //jmp ...
381 const PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
382
383 //Continueアドレスのバックアップとセット
384 compiler.codeGenerator.ContinueAreaBegin();
385
386 //第2パラメータを取得(to~)
387 i=GetOneParameter(Parameter,i,JudgeNum);
388
389 //第3パラメータを取得(step~)
390 if(Parameter[i]){
391 i=GetOneParameter(Parameter,i,StepNum);
392 if(Parameter[i]) SetError(12,"For",cp);
393 }
394 else lstrcpy(StepNum,"1");
395
396 //カウンタを増加させる
397 sprintf(temporary,"%s=(%s)+(%s)",variable,variable,StepNum);
398 OpcodeCalc(temporary);
399
400 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
401
402 //増加か減少かを区別する
403 sprintf(temporary,"(%s)>=0",StepNum);
404
405 int reg;
406 reg=REG_RAX;
407 if( !NumOpe(&reg,temporary,Type(),resultType) ){
408 return;
409 }
410
411 //cmp rax,0
412 compiler.codeGenerator.op_cmp_value(resultType.GetSize(),REG_RAX,0);
413
414 //je [カウンタ減少の場合の判定]
415 pTempPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
416
417 //判定(カウンタ増加の場合)
418 sprintf(temporary,"%s<=(%s)",variable,JudgeNum);
419
420 reg=REG_RAX;
421 NumOpe(&reg,temporary,Type(),Type());
422
423 //jmp [カウンタ減少の場合の判定を飛び越す]
424 const PertialSchedule *pTempPertialSchedule2 = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
425
426 //jeジャンプ先のオフセット値
427 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
428
429 //判定(カウンタ減少の場合)
430 sprintf(temporary,"%s>=(%s)",variable,JudgeNum);
431
432 reg=REG_RAX;
433 NumOpe(&reg,temporary,Type(),resultType);
434
435 //jmpジャンプ先のオフセット値
436 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule2 );
437
438 //cmp rax,0
439 compiler.codeGenerator.op_cmp_value(resultType.GetSize(),REG_RAX,0);
440
441ErrorStep:
442
443 //je ...
444 pTempPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
445
446 //レキシカルスコープをレベルアップ
447 compiler.codeGenerator.lexicalScopes.Start( compiler.codeGenerator.GetNativeCodeSize(), LexicalScope::SCOPE_TYPE_FOR );
448
449 //For内をコンパイル
450 CompileBuffer(0,COM_NEXT);
451
452 compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd();
453
454 if(szNextVariable[0]){
455 if(lstrcmp(szNextVariable,variable)!=0){
456 SetError(55,szNextVariable,cp);
457 }
458 }
459
460 //jmp ...
461 compiler.codeGenerator.op_jmp_continue();
462
463 //レキシカルスコープをレベルダウン
464 compiler.codeGenerator.lexicalScopes.End();
465
466 //jeジャンプ先のオフセット値
467 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
468
469 //Continueアドレスを復元
470 compiler.codeGenerator.ContinueAreaEnd();
471}
472
473void OpcodeDo(char *Parameter){
474 extern HANDLE hHeap;
475 int i,i2,i3;
476
477 if(Parameter[0]) SetError(10,"Do",cp);
478
479 //Continueアドレスのバックアップとセット
480 compiler.codeGenerator.ContinueAreaBegin();
481
482 //レキシカルスコープをレベルアップ
483 compiler.codeGenerator.lexicalScopes.Start( compiler.codeGenerator.GetNativeCodeSize(), LexicalScope::SCOPE_TYPE_DO );
484
485 //Do内をコンパイル
486 CompileBuffer(0,COM_LOOP);
487
488 compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd();
489
490 const PertialSchedule *pDoPertialSchedule = NULL;
491
492 extern char *basbuf;
493 char temporary[VN_SIZE];
494 for(i=cp-1;;i--){
495 if(IsCommandDelimitation(basbuf[i])){
496 i+=3;
497 if(!(basbuf[i]=='0'||basbuf[i]=='1')){
498 //無条件ループ
499 break;
500 }
501 i3=i;
502
503 for(i+=2,i2=0;;i++,i2++){
504 if(IsCommandDelimitation(basbuf[i])){
505 temporary[i2]=0;
506 break;
507 }
508 temporary[i2]=basbuf[i];
509 }
510
511 //条件式を実行してフラグをセット
512 Judgment(temporary);
513
514 if(basbuf[i3]=='0'){
515 //While
516
517 //je 5(ループ終了)
518 pDoPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(char), true );
519 }
520 else if(basbuf[i3]=='1'){
521 //Until
522
523 //jne 5(ループ終了)
524 pDoPertialSchedule = compiler.codeGenerator.op_jne( 0, sizeof(char), true );
525 }
526 break;
527 }
528 }
529
530 //jmp ...
531 compiler.codeGenerator.op_jmp_continue();
532
533 if( pDoPertialSchedule )
534 {
535 compiler.codeGenerator.opfix_JmpPertialSchedule( pDoPertialSchedule );
536 }
537
538 //jmp ...
539 const PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
540
541 //レキシカルスコープをレベルダウン
542 compiler.codeGenerator.lexicalScopes.End();
543
544 //jmpジャンプ先のオフセット値
545 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
546
547 //Continueアドレスを復元
548 compiler.codeGenerator.ContinueAreaEnd();
549}
550void OpcodeContinue(void){
551 //jmp ...(Continue addr)
552 compiler.codeGenerator.op_jmp_continue();
553}
554
555void OpcodeExitSub(void){
556 if( UserProc::IsGlobalAreaCompiling() ){
557 SetError(12,"Exit Sub/Function",cp);
558 return;
559 }
560
561 //未解放のローカルオブジェクトのデストラクタを呼び出す
562 compiler.codeGenerator.lexicalScopes.CallDestructorsOfReturn();
563
564 //jmp ...(End Sub/Function)
565 compiler.codeGenerator.op_jmp_exitsub();
566}
567
568//Caseスケジュール
569class SelectSchedule
570{
571public:
572 SelectSchedule( int typeSize )
573 : typeSize( typeSize )
574 , nowCaseSchedule( 0 )
575 {
576 }
577
578 PertialSchedules casePertialSchedules;
579 int typeSize;
580 int nowCaseSchedule;
581};
582std::vector<SelectSchedule> selectSchedules;
583
584void OpcodeSelect( const char *lpszParms ){
585 extern HANDLE hHeap;
586 extern char *basbuf;
587 int i,i2,i3,NowCaseCp;
588 char temporary[VN_SIZE];
589
590 int reg1=REG_RAX;
591 Type type1;
592 if( !NumOpe(&reg1,lpszParms,Type(), type1 ) ){
593 return;
594 }
595
596 selectSchedules.push_back( SelectSchedule( type1.GetSize() ) );
597
598 if( selectSchedules.back().typeSize < sizeof(long) ){
599 selectSchedules.back().typeSize = sizeof(long);
600 }
601
602 if(type1.IsDouble()){
603 //movsd qword ptr[rsp+offset],xmm_reg ※スタックフレームを利用
604 pobj_sf->push(reg1,sizeof(double));
605 }
606 else if(type1.IsSingle()){
607 //movss dword ptr[rsp+offset],xmm_reg ※スタックフレームを利用
608 pobj_sf->push(reg1,sizeof(float));
609 }
610 else{
611 ExtendTypeTo64(type1.GetBasicType(),reg1);
612
613 //mov qword ptr[rsp+offset],reg ※スタックフレームを利用
614 pobj_sf->push(reg1);
615 }
616
617 for(i=cp;;i++){
618 if(basbuf[i]=='\0'){
619 selectSchedules.pop_back();
620 SetError(22,"Select",cp);
621 return;
622 }
623 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE){
624 for(i2=0;;i++){
625 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE) i2++;
626 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT){
627 i2--;
628 if(i2==0) break;
629 }
630 }
631 continue;
632 }
633 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT) break;
634
635 if(basbuf[i]==1&&basbuf[i+1]==ESC_CASE){
636 NowCaseCp=i;
637
638 i++;
639 while(1){
640 for(i++,i2=0;;i++,i2++){
641 if(basbuf[i]=='\"'){
642 i3=GetStringInQuotation(temporary+i2,basbuf+i);
643 i+=i3-1;
644 i2+=i3-1;
645 continue;
646 }
647 if(basbuf[i]=='('){
648 i3=GetStringInPare(temporary+i2,basbuf+i);
649 i+=i3-1;
650 i2+=i3-1;
651 continue;
652 }
653 if(basbuf[i]=='['){
654 i3=GetStringInBracket(temporary+i2,basbuf+i);
655 i+=i3-1;
656 i2+=i3-1;
657 continue;
658 }
659
660 if(IsCommandDelimitation(basbuf[i])){
661 temporary[i2]=0;
662 break;
663 }
664 if(basbuf[i]==','){
665 temporary[i2]=0;
666 break;
667 }
668
669 temporary[i2]=basbuf[i];
670 }
671
672 //エラー用
673 i2=cp;
674 cp=NowCaseCp;
675
676 int reg2=REG_RDX;
677 Type type2;
678 if( !NumOpe(&reg2,temporary,type1,type2) ){
679 return;
680 }
681
682 cp=i2;
683
684 if(type1.IsObject()){
685 std::vector<const UserProc *> subs;
686 type1.GetClass().GetMethods().Enum( CALC_EQUAL, subs );
687 if( subs.size() == 0 ){
688 return;
689 }
690
691 Parameters params;
692 params.push_back( new Parameter( "", Type( type2 ) ) );
693
694 //オーバーロードを解決
695 const UserProc *pUserProc = OverloadSolution("==",subs, params, NULL);
696
697 delete params[0];
698
699 if(!pUserProc){
700 //エラー
701 return;
702 }
703
704
705 //実体オブジェクト
706 if(reg2!=REG_RDX){
707 //mov rdx,reg2
708 compiler.codeGenerator.op_mov_RR(REG_RDX,reg2);
709 }
710
711 //mov rcx,qword ptr[rsp+offset] ※スタックフレームから参照
712 pobj_sf->ref(REG_RCX);
713
714 //call operator_proc ※ ==演算子
715 compiler.codeGenerator.op_call(pUserProc);
716
717 //test rax,rax
718 compiler.codeGenerator.op_test(REG_RAX,REG_RAX);
719
720 //jne ...
721 selectSchedules.back().casePertialSchedules.push_back(
722 compiler.codeGenerator.op_jne( 0, sizeof(long), true )
723 );
724 }
725 else{
726 if(type1.IsDouble()){
727 int xmm_reg;
728 if(IsXmmReg(reg2)) xmm_reg=reg2;
729 else xmm_reg=REG_XMM5;
730 ChangeTypeToXmm_Double(type2.GetBasicType(),xmm_reg,reg2);
731
732 //movsd xmm4,qword ptr[rsp+offset] ※スタックフレームから参照
733 pobj_sf->ref(REG_XMM4,sizeof(double));
734
735 //comiss xmm_reg1,xmm_reg2
736 compiler.codeGenerator.op_comisd(xmm_reg,REG_XMM4);
737 }
738 else if(type1.IsSingle()){
739 int xmm_reg;
740 if(IsXmmReg(reg2)) xmm_reg=reg2;
741 else xmm_reg=REG_XMM5;
742 ChangeTypeToXmm_Single(type2.GetBasicType(),xmm_reg,reg2);
743
744 //movss xmm4,dword ptr[rsp+offset] ※スタックフレームから参照
745 pobj_sf->ref(REG_XMM4,sizeof(float));
746
747 //comiss xmm_reg1,xmm_reg2
748 compiler.codeGenerator.op_comiss(xmm_reg,REG_XMM4);
749 }
750 else{
751 //その他整数型
752
753 i2=NeutralizationType(type1.GetBasicType(),-1,type2.GetBasicType(),-1);
754
755 //mov r14,qword ptr[rsp+offset] ※スタックフレームから参照
756 pobj_sf->ref(REG_R14);
757
758 //cmp reg2,r14
759 compiler.codeGenerator.op_cmp_reg(Type(i2).GetSize(),reg2,REG_R14);
760 }
761
762 //je ...
763 selectSchedules.back().casePertialSchedules.push_back(
764 compiler.codeGenerator.op_je( 0, sizeof(long), true )
765 );
766 }
767
768 if(basbuf[i]!=',') break;
769 }
770 }
771 if(basbuf[i]==1&&basbuf[i+1]==ESC_CASEELSE){
772 //jmp ...
773 selectSchedules.back().casePertialSchedules.push_back(
774 compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
775 );
776 }
777 }
778
779 //スタックフレームを1スペースだけ解除
780 pobj_sf->pop(REG_NON);
781
782 //レキシカルスコープをレベルアップ
783 compiler.codeGenerator.lexicalScopes.Start( compiler.codeGenerator.GetNativeCodeSize(), LexicalScope::SCOPE_TYPE_SELECT );
784
785 //Select Case内をコンパイル
786 CompileBuffer(ESC_ENDSELECT,0);
787
788 //jmp EndSelect
789 selectSchedules.back().casePertialSchedules.push_back(
790 compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
791 );
792
793 //最終スケジュール
794 for(i=selectSchedules.back().nowCaseSchedule;i<(int)selectSchedules.back().casePertialSchedules.size();i++){
795 compiler.codeGenerator.opfix_JmpPertialSchedule( selectSchedules.back().casePertialSchedules[i] );
796 }
797
798 //レキシカルスコープをレベルダウン
799 compiler.codeGenerator.lexicalScopes.End();
800
801 selectSchedules.pop_back();
802}
803void OpcodeCase(char *Parameter){
804 int i;
805
806 if(selectSchedules.back().typeSize==-1){
807 SetError(30,"Case",cp);
808 return;
809 }
810
811 //jmp EndSelect
812 selectSchedules.back().casePertialSchedules.push_back(
813 compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
814 );
815
816 i=0;
817 while(1){
818 //Caseスケジュール
819 compiler.codeGenerator.opfix_JmpPertialSchedule( selectSchedules.back().casePertialSchedules[selectSchedules.back().nowCaseSchedule] );
820 selectSchedules.back().nowCaseSchedule++;
821
822 i=JumpOneParameter(Parameter,i);
823 if(Parameter[i]=='\0') break;
824 }
825}
826
827void OpcodeGosub(char *Parameter){
828 SetError(-1,"Gosub ~ Returnステートメントは64ビットコンパイラで利用することはできません。",cp);
829}
830void OpcodeReturn(char *Parameter){
831 if( UserProc::IsGlobalAreaCompiling() ){
832 SetError(62,NULL,cp);
833 }
834 else{
835 //戻り値をセット
836 if(Parameter[0]){
837 const UserProc &proc = UserProc::CompilingUserProc();
838
839 const char *temp = "_System_ReturnValue";
840 if(proc.GetName()[0]==1&&proc.GetName()[1]==ESC_OPERATOR)
841 {
842 }
843 else{
844 temp=proc.GetName().c_str();
845 }
846
847 char temporary[VN_SIZE];
848 sprintf(temporary,"%s=%s",temp,Parameter);
849 OpcodeCalc(temporary);
850 }
851
852 //プロシージャを抜け出す(C言語のreturnと同様の処理を行う)
853 OpcodeExitSub();
854 }
855}
856
857
858////////////
859// ポインタ
860////////////
861
862void OpcodeSetPtrData(char *Parameter,int type){
863 int i;
864 char temporary[VN_SIZE];
865
866 if(Parameter[0]=='('){
867 i=JumpStringInPare(Parameter,1);
868 if(Parameter[i+1]=='\0'){
869 for(i=0;;i++){
870 Parameter[i]=Parameter[i+1];
871 if(Parameter[i]=='\0') break;
872 }
873 Parameter[i-1]=0;
874 }
875 }
876
877 //第1パラメータを取得
878 i=GetOneParameter(Parameter,0,temporary);
879 if(!Parameter[i]){
880 SetError(1,NULL,cp);
881 return;
882 }
883
884 int reg_ptr=REG_RAX;
885 Type resultType;
886 if( !NumOpe(&reg_ptr,temporary,Type(),resultType) ){
887 return;
888 }
889 if(!resultType.IsWhole()){
890 SetError(11,Parameter,cp);
891 return;
892 }
893
894 //結果を格納しているレジスタをブロッキング
895 pobj_BlockReg->lock(reg_ptr);
896
897 //第2パラメータを取得
898 i=GetOneParameter(Parameter,i,temporary);
899 if(Parameter[i]){
900 SetError(1,NULL,cp);
901 return;
902 }
903
904 int temp_reg=REG_NON;
905 if( !NumOpe(&temp_reg,temporary,Type(),resultType) ){
906 return;
907 }
908
909 //レジスタのブロッキングを解除
910 pobj_BlockReg->clear();
911
912 if(type==DEF_DOUBLE){
913 ChangeTypeToXmm_Double(resultType.GetBasicType(),REG_XMM0,temp_reg);
914
915 //movsd qword ptr[reg_ptr],xmm0
916 compiler.codeGenerator.op_movsd_MR(REG_XMM0,reg_ptr,0,MOD_BASE);
917 }
918 else if(type==DEF_SINGLE){
919 ChangeTypeToXmm_Single(resultType.GetBasicType(),REG_XMM0,temp_reg);
920
921 //movss dword ptr[reg_ptr],xmm0
922 compiler.codeGenerator.op_movss_MR(REG_XMM0,reg_ptr,0,MOD_BASE);
923 }
924 else{
925 ChangeTypeToWhole(resultType,Type(type),REG_RCX,temp_reg);
926
927 //mov ptr[reg_ptr],rcx
928 compiler.codeGenerator.op_mov_MR(Type(type).GetSize(),REG_RCX,reg_ptr,0,MOD_BASE);
929 }
930}
Note: See TracBrowser for help on using the repository browser.