source: dev/BasicCompiler64/Compile_Statement.cpp@ 97

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

関数の戻り値オブジェクトのメンバ・メソッドを一時オブジェクトを介さずに参照できるようにした。

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