source: dev/BasicCompiler64/Compile_Statement.cpp@ 88

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

House→Smoothie
Sourceクラスを用意した。

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