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

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