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

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

コード全体のリファクタリングを実施

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