source: dev/BasicCompiler64/Compile_Statement.cpp@ 76

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

TYPEINFO→Typeへのリファクタリングを実施。32bitが未完成。

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