source: dev/BasicCompiler64/Compile_Statement.cpp@ 135

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

Method/Memberのリファクタリング

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