source: dev/BasicCompiler64/Compile_Statement.cpp@ 48

Last change on this file since 48 was 48, checked in by dai_9181, 17 years ago
File size: 30.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 SUBINFO *psi;
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 psi=GetSubHash(Command);
44
45 //GetSubHash内でエラー提示が行われた場合
46 if(psi==(SUBINFO *)-1) return;
47
48 if(psi==0){
49 char temporary[VN_SIZE];
50 lstrcpy(temporary,Command);
51
52 CharUpper(temporary);
53 psi=GetSubHash(temporary);
54
55 //GetSubHash内でエラー提示が行われた場合
56 if(psi==(SUBINFO *)-1) return;
57 }
58
59 if(psi){
60 if(psi->dwType!=SUBTYPE_MACRO) SetError(10,Command,cp);
61
62 Opcode_CallProc("",psi,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 *pInfo;
75 idProc=GetProc(buffer,&pInfo);
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 LONG_PTR lp;
94 i2=CallProc(idProc,pInfo,buffer,temp2,&lp);
95
96
97 /////////////////////
98 // 戻り値の処理
99 /////////////////////
100
101 if(i2==DEF_OBJECT){
102 CClass *pobj_Class;
103 pobj_Class=(CClass *)lp;
104
105 //mov r14,rax
106 op_mov_RR(REG_R14,REG_RAX);
107
108 FreeTempObject(REG_R14,pobj_Class);
109 }
110 return;
111 }
112
113
114 //////////////////////////
115 // その他は代入演算を行う
116 //////////////////////////
117 OpcodeCalc(Command);
118}
119
120void Judgment(char *buffer){
121 int reg=REG_RAX,type;
122 type=NumOpe(&reg,buffer,0,0,0);
123
124 int offset;
125
126 if(type==DEF_DOUBLE){
127 double dbl=0;
128 offset=AddDataTable((char *)&dbl,sizeof(double));
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(type==DEF_SINGLE){
141 float flt=0;
142 offset=AddDataTable((char *)&flt,sizeof(float));
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(GetTypeSize(type,-1),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 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,type;
406 reg=REG_RAX;
407 type=NumOpe(&reg,temporary,0,0,0);
408
409 //cmp rax,0
410 op_cmp_value(GetTypeSize(type,-1),REG_RAX,0);
411
412 //je [カウンタ減少の場合の判定]
413 OpBuffer[obp++]=(char)0x0F;
414 OpBuffer[obp++]=(char)0x84;
415 i2=obp;
416 obp+=sizeof(long);
417
418 //判定(カウンタ増加の場合)
419 sprintf(temporary,"%s<=(%s)",variable,JudgeNum);
420
421 reg=REG_RAX;
422 type=NumOpe(&reg,temporary,0,0,0);
423
424 //jmp [カウンタ減少の場合の判定を飛び越す]
425 OpBuffer[obp++]=(char)0xE9;
426 i3=obp;
427 obp+=sizeof(long);
428
429 *((long *)(OpBuffer+i2))=obp-(i2+sizeof(long)); //jeジャンプ先のオフセット値
430
431 //判定(カウンタ減少の場合)
432 sprintf(temporary,"%s>=(%s)",variable,JudgeNum);
433
434 reg=REG_RAX;
435 type=NumOpe(&reg,temporary,0,0,0);
436
437 *((long *)(OpBuffer+i3))=obp-(i3+sizeof(long)); //jmpジャンプ先のオフセット値
438
439 //cmp rax,0
440 op_cmp_value(GetTypeSize(type,-1),REG_RAX,0);
441
442ErrorStep:
443
444 //je ...
445 OpBuffer[obp++]=(char)0x0F;
446 OpBuffer[obp++]=(char)0x84;
447 int je_schedule=obp;
448 obp+=sizeof(long);
449 pobj_TempSchedule->lock(&je_schedule);
450
451 //レキシカルスコープをレベルアップ
452 obj_LexScopes.Start( obp, SCOPE_TYPE_FOR );
453
454 //For内をコンパイル
455 CompileBuffer(0,COM_NEXT);
456
457 obj_LexScopes.CallDestructorsOfScopeEnd();
458
459 if(szNextVariable[0]){
460 if(lstrcmp(szNextVariable,variable)!=0){
461 SetError(55,szNextVariable,cp);
462 }
463 }
464
465 //jmp ...
466 OpBuffer[obp++]=(char)0xE9;
467 *((long *)(OpBuffer+obp))=dwContinueAddress-(obp+sizeof(long));
468 obp+=sizeof(long);
469 if( isError == false ){
470 pobj_TempSchedule->unlock();
471 pobj_TempSchedule->unlock();
472 }
473
474 //レキシカルスコープをレベルダウン
475 obj_LexScopes.End();
476
477 *((long *)(OpBuffer+je_schedule))=obp-(je_schedule+sizeof(long)); //jeジャンプ先のオフセット値
478 pobj_TempSchedule->unlock();
479
480 //Continueアドレスを復元
481 dwContinueAddress=dwTempContinue;
482}
483
484void OpcodeDo(char *Parameter){
485 extern HANDLE hHeap;
486 int i,i2,i3;
487
488 if(Parameter[0]) SetError(10,"Do",cp);
489
490 //Continueアドレスのバックアップとセット
491 extern DWORD dwContinueAddress;
492 DWORD dwTempContinue;
493 dwTempContinue=dwContinueAddress;
494 dwContinueAddress=obp;
495 pobj_TempSchedule->lock((int *)&dwTempContinue);
496 pobj_TempSchedule->lock((int *)&dwContinueAddress);
497
498 //レキシカルスコープをレベルアップ
499 obj_LexScopes.Start( obp, SCOPE_TYPE_DO );
500
501 //Do内をコンパイル
502 CompileBuffer(0,COM_LOOP);
503
504 obj_LexScopes.CallDestructorsOfScopeEnd();
505
506 extern char *basbuf;
507 char temporary[VN_SIZE];
508 for(i=cp-1;;i--){
509 if(IsCommandDelimitation(basbuf[i])){
510 i+=3;
511 if(!(basbuf[i]=='0'||basbuf[i]=='1')){
512 //無条件ループ
513 break;
514 }
515 i3=i;
516
517 for(i+=2,i2=0;;i++,i2++){
518 if(IsCommandDelimitation(basbuf[i])){
519 temporary[i2]=0;
520 break;
521 }
522 temporary[i2]=basbuf[i];
523 }
524
525 //条件式を実行してフラグをセット
526 Judgment(temporary);
527
528 if(basbuf[i3]=='0'){
529 //While
530
531 //je 5(ループ終了)
532 OpBuffer[obp++]=(char)0x74;
533 OpBuffer[obp++]=(char)0x05;
534 }
535 else if(basbuf[i3]=='1'){
536 //Until
537
538 //jne 5(ループ終了)
539 OpBuffer[obp++]=(char)0x75;
540 OpBuffer[obp++]=(char)0x05;
541 }
542 break;
543 }
544 }
545
546 //jmp ...
547 OpBuffer[obp++]=(char)0xE9;
548 *((long *)(OpBuffer+obp))=dwContinueAddress-(obp+sizeof(long));
549 obp+=sizeof(long);
550 pobj_TempSchedule->unlock();
551 pobj_TempSchedule->unlock();
552
553 //jmp ...
554 OpBuffer[obp++]=(char)0xE9;
555 int je_schedule=obp;
556 obp+=sizeof(long);
557 pobj_TempSchedule->lock(&je_schedule);
558
559 //レキシカルスコープをレベルダウン
560 obj_LexScopes.End();
561
562 *((long *)(OpBuffer+je_schedule))=obp-(je_schedule+sizeof(long)); //jmpジャンプ先のオフセット値
563 pobj_TempSchedule->unlock();
564
565 //Continueアドレスを復元
566 dwContinueAddress=dwTempContinue;
567}
568void OpcodeContinue(void){
569 extern DWORD dwContinueAddress;
570
571 if(dwContinueAddress==-1){
572 SetError(12,"Continue",cp);
573 return;
574 }
575
576 //jmp ...(Continue addr)
577 OpBuffer[obp++]=(char)0xE9;
578
579 *((long *)(OpBuffer+obp))=dwContinueAddress-(obp+sizeof(long));
580 obp+=sizeof(long);
581}
582
583void OpcodeExitSub(void){
584 extern DWORD *pExitSubSchedule;
585 extern int ExitSubScheduleNum;
586 extern HANDLE hHeap;
587
588 extern BOOL bCompilingGlobal;
589 if(bCompilingGlobal){
590 SetError(12,"Exit Sub/Function",cp);
591 return;
592 }
593
594 //未解放のローカルオブジェクトのデストラクタを呼び出す
595 obj_LexScopes.CallDestructorsOfReturn();
596
597 //jmp ...(End Sub/Function)
598 OpBuffer[obp++]=(char)0xE9;
599
600 pExitSubSchedule=(DWORD *)HeapReAlloc(hHeap,0,pExitSubSchedule,(ExitSubScheduleNum+1)*sizeof(DWORD));
601 pExitSubSchedule[ExitSubScheduleNum]=obp;
602 ExitSubScheduleNum++;
603
604 obp+=sizeof(long);
605}
606
607void AddCaseSchedule(void){
608 extern DWORD *pCaseSchedule;
609 extern int CaseScheduleNum;
610 extern HANDLE hHeap;
611
612 pCaseSchedule=(DWORD *)HeapReAlloc(hHeap,0,pCaseSchedule,(CaseScheduleNum+1)*sizeof(DWORD));
613 pCaseSchedule[CaseScheduleNum]=obp;
614 CaseScheduleNum++;
615}
616void OpcodeSelect(char *Parameter){
617 extern DWORD *pCaseSchedule;
618 extern int CaseScheduleNum;
619 extern int NowCaseSchedule;
620 extern HANDLE hHeap;
621 extern char *basbuf;
622 int i,i2,i3,NowCaseCp;
623 char temporary[VN_SIZE];
624
625 DWORD *temp_pCaseSchedule;
626 int temp_CaseScheduleNum;
627 int temp_NowCaseSchedule;
628
629 temp_pCaseSchedule=pCaseSchedule;
630 temp_CaseScheduleNum=CaseScheduleNum;
631 temp_NowCaseSchedule=NowCaseSchedule;
632 pCaseSchedule=(DWORD *)HeapAlloc(hHeap,0,1);
633 CaseScheduleNum=0;
634 NowCaseSchedule=0;
635
636 int reg1=REG_RAX,type1;
637 LONG_PTR lpIndex;
638 type1=NumOpe(&reg1,Parameter,0,0,&lpIndex);
639
640 if(type1==DEF_DOUBLE){
641 //movsd qword ptr[rsp+offset],xmm_reg ※スタックフレームを利用
642 pobj_sf->push(reg1,sizeof(double));
643 }
644 else if(type1==DEF_SINGLE){
645 //movss dword ptr[rsp+offset],xmm_reg ※スタックフレームを利用
646 pobj_sf->push(reg1,sizeof(float));
647 }
648 else{
649 ExtendTypeTo64(type1,reg1);
650
651 //mov qword ptr[rsp+offset],reg ※スタックフレームを利用
652 pobj_sf->push(reg1);
653 }
654
655 for(i=cp;;i++){
656 if(basbuf[i]=='\0'){
657 HeapDefaultFree(pCaseSchedule);
658 pCaseSchedule=temp_pCaseSchedule;
659 CaseScheduleNum=temp_CaseScheduleNum;
660 NowCaseSchedule=temp_NowCaseSchedule;
661 SetError(22,"Select",cp);
662 return;
663 }
664 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE){
665 for(i2=0;;i++){
666 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE) i2++;
667 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT){
668 i2--;
669 if(i2==0) break;
670 }
671 }
672 continue;
673 }
674 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT) break;
675
676 if(basbuf[i]==1&&basbuf[i+1]==ESC_CASE){
677 NowCaseCp=i;
678
679 i++;
680 while(1){
681 for(i++,i2=0;;i++,i2++){
682 if(basbuf[i]=='\"'){
683 i3=GetStringInQuotation(temporary+i2,basbuf+i);
684 i+=i3-1;
685 i2+=i3-1;
686 continue;
687 }
688 if(basbuf[i]=='('){
689 i3=GetStringInPare(temporary+i2,basbuf+i);
690 i+=i3-1;
691 i2+=i3-1;
692 continue;
693 }
694 if(basbuf[i]=='['){
695 i3=GetStringInBracket(temporary+i2,basbuf+i);
696 i+=i3-1;
697 i2+=i3-1;
698 continue;
699 }
700
701 if(IsCommandDelimitation(basbuf[i])){
702 temporary[i2]=0;
703 break;
704 }
705 if(basbuf[i]==','){
706 temporary[i2]=0;
707 break;
708 }
709
710 temporary[i2]=basbuf[i];
711 }
712
713 //エラー用
714 i2=cp;
715 cp=NowCaseCp;
716
717 int reg2=REG_RDX,type2;
718 LONG_PTR lpIndex2;
719 type2=NumOpe(&reg2,temporary,type1,lpIndex,&lpIndex2);
720
721 cp=i2;
722
723 if(type1==DEF_OBJECT){
724 CClass *pobj_c;
725 pobj_c=(CClass *)lpIndex;
726
727 SUBINFO **ppsi;
728 int num;
729 ppsi=pobj_c->GetOperatorSubInfo(CALC_EQUAL,num);
730 if(num==0){
731 HeapDefaultFree(ppsi);
732
733 return;
734 }
735
736 PARAMETER_INFO *ppi = (PARAMETER_INFO *)HeapAlloc(hHeap,0,sizeof(PARAMETER_INFO)*3);
737 int iParmNum=0;
738 ppi[iParmNum].bArray=0;
739 ppi[iParmNum].bByVal=0;
740 ppi[iParmNum].name=0;
741 ppi[iParmNum].type=type2;
742 ppi[iParmNum].u.index=lpIndex2;
743 ppi[iParmNum].SubScripts[0]=-1;
744 iParmNum++;
745
746 //オーバーロードを解決
747 SUBINFO *psi;
748 psi=OverloadSolution("==",ppsi,num,ppi,iParmNum,NULL);
749 HeapDefaultFree(ppsi);
750 HeapDefaultFree(ppi);
751
752 if(!psi){
753 //エラー
754 return;
755 }
756
757
758 //実体オブジェクト
759 if(reg2!=REG_RDX){
760 //mov rdx,reg2
761 op_mov_RR(REG_RDX,reg2);
762 }
763
764 //mov rcx,qword ptr[rsp+offset] ※スタックフレームから参照
765 pobj_sf->ref(REG_RCX);
766
767 //call operator_proc ※ ==演算子
768 op_call(psi);
769
770 //test rax,rax
771 op_test(REG_RAX,REG_RAX);
772
773 //jne ...
774 OpBuffer[obp++]=(char)0x0F;
775 OpBuffer[obp++]=(char)0x85;
776 }
777 else{
778 if(type1==DEF_DOUBLE){
779 int xmm_reg;
780 if(IsXmmReg(reg2)) xmm_reg=reg2;
781 else xmm_reg=REG_XMM5;
782 ChangeTypeToXmm_Double(type2,xmm_reg,reg2);
783
784 //movsd xmm4,qword ptr[rsp+offset] ※スタックフレームから参照
785 pobj_sf->ref(REG_XMM4,sizeof(double));
786
787 //comiss xmm_reg1,xmm_reg2
788 op_comisd(xmm_reg,REG_XMM4);
789 }
790 else if(type1==DEF_SINGLE){
791 int xmm_reg;
792 if(IsXmmReg(reg2)) xmm_reg=reg2;
793 else xmm_reg=REG_XMM5;
794 ChangeTypeToXmm_Single(type2,xmm_reg,reg2);
795
796 //movss xmm4,dword ptr[rsp+offset] ※スタックフレームから参照
797 pobj_sf->ref(REG_XMM4,sizeof(float));
798
799 //comiss xmm_reg1,xmm_reg2
800 op_comiss(xmm_reg,REG_XMM4);
801 }
802 else{
803 //その他整数型
804
805 i2=NeutralizationType(type1,-1,type2,-1);
806
807 //mov r14,qword ptr[rsp+offset] ※スタックフレームから参照
808 pobj_sf->ref(REG_R14);
809
810 //cmp reg2,r14
811 op_cmp_reg(GetTypeSize(i2,-1),reg2,REG_R14);
812 }
813
814 //je ...
815 OpBuffer[obp++]=(char)0x0F;
816 OpBuffer[obp++]=(char)0x84;
817 }
818 AddCaseSchedule();
819 obp+=sizeof(long);
820
821 if(basbuf[i]!=',') break;
822 }
823 }
824 if(basbuf[i]==1&&basbuf[i+1]==ESC_CASEELSE){
825 //jmp ...
826 OpBuffer[obp++]=(char)0xE9;
827 AddCaseSchedule();
828 obp+=sizeof(long);
829 }
830 }
831
832 //スタックフレームを1スペースだけ解除
833 pobj_sf->pop(REG_NON);
834
835 //レキシカルスコープをレベルアップ
836 obj_LexScopes.Start( obp, SCOPE_TYPE_SELECT );
837
838 //Select Case内をコンパイル
839 CompileBuffer(ESC_ENDSELECT,0);
840
841 //jmp EndSelect
842 OpBuffer[obp++]=(char)0xE9;
843 AddCaseSchedule();
844 obp+=sizeof(long);
845
846 //最終スケジュール
847 for(i=NowCaseSchedule;i<CaseScheduleNum;i++){
848 *(long *)(OpBuffer+pCaseSchedule[i])=obp-(pCaseSchedule[i]+sizeof(long));
849 }
850 HeapDefaultFree(pCaseSchedule);
851
852 //レキシカルスコープをレベルダウン
853 obj_LexScopes.End();
854
855 pCaseSchedule=temp_pCaseSchedule;
856 CaseScheduleNum=temp_CaseScheduleNum;
857 NowCaseSchedule=temp_NowCaseSchedule;
858}
859void OpcodeCase(char *Parameter){
860 extern DWORD *pCaseSchedule;
861 extern int NowCaseSchedule;
862 int i;
863
864 if(!pCaseSchedule){
865 SetError(30,"Case",cp);
866 return;
867 }
868
869 //jmp EndSelect
870 OpBuffer[obp++]=(char)0xE9;
871 AddCaseSchedule();
872 obp+=sizeof(long);
873
874 i=0;
875 while(1){
876 //Caseスケジュール
877 *(long *)(OpBuffer+pCaseSchedule[NowCaseSchedule])=obp-(pCaseSchedule[NowCaseSchedule]+sizeof(long));
878 NowCaseSchedule++;
879
880 i=JumpOneParameter(Parameter,i);
881 if(Parameter[i]=='\0') break;
882 }
883}
884
885void OpcodeGosub(char *Parameter){
886 extern HANDLE hHeap;
887 extern GOTOLABELSCHEDULE *pGotoLabelSchedule;
888 extern int GotoLabelScheduleNum;
889 int i,LineNum;
890
891 //call _System_GetEip
892 extern SUBINFO *pSub_System_GetEip;
893 op_call(pSub_System_GetEip);
894
895 //add rax,offset(Gosubステートメントの最終ポイント)
896 int schedule=obp,schedule2;
897 op_add64_value(REG_RAX,0);
898 schedule2=obp-sizeof(long);
899
900 //※戻り先用のrip
901 //mov qword ptr[rsp+offset],rax ※スタックフレームを利用
902 pobj_sf->push(REG_RAX);
903
904
905 if(Parameter[0]=='*'){
906 i=GetLabelAddress(Parameter+1,0);
907
908 //jmp ...
909 OpBuffer[obp++]=(char)0xE9;
910 if(i==-1){
911 pGotoLabelSchedule=(GOTOLABELSCHEDULE *)HeapReAlloc(hHeap,0,pGotoLabelSchedule,(GotoLabelScheduleNum+1)*sizeof(GOTOLABELSCHEDULE));
912 pGotoLabelSchedule[GotoLabelScheduleNum].pName=(char *)HeapAlloc(hHeap,0,lstrlen(Parameter+1)+1);
913 lstrcpy(pGotoLabelSchedule[GotoLabelScheduleNum].pName,Parameter+1);
914 pGotoLabelSchedule[GotoLabelScheduleNum].pos=obp;
915 pGotoLabelSchedule[GotoLabelScheduleNum].now_cp=cp;
916 GotoLabelScheduleNum++;
917 }
918 *((long *)(OpBuffer+obp))=i-(obp+sizeof(long));
919 obp+=sizeof(long);
920 }
921 else{
922 LineNum=atoi(Parameter);
923 i=GetLabelAddress(0,LineNum);
924
925 //jmp ...
926 OpBuffer[obp++]=(char)0xE9;
927 if(i==-1){
928 pGotoLabelSchedule=(GOTOLABELSCHEDULE *)HeapReAlloc(hHeap,0,pGotoLabelSchedule,(GotoLabelScheduleNum+1)*sizeof(GOTOLABELSCHEDULE));
929 pGotoLabelSchedule[GotoLabelScheduleNum].pName=0;
930 pGotoLabelSchedule[GotoLabelScheduleNum].line=LineNum;
931 pGotoLabelSchedule[GotoLabelScheduleNum].pos=obp;
932 pGotoLabelSchedule[GotoLabelScheduleNum].now_cp=cp;
933 GotoLabelScheduleNum++;
934 }
935 *((long *)(OpBuffer+obp))=i-(obp+sizeof(long));
936 obp+=sizeof(long);
937 }
938
939 *((long *)(OpBuffer+schedule2))=obp-schedule;
940
941 //※スタックフレームを元に戻す
942 pobj_sf->pop(REG_NON);
943
944 SetError(-1,"Gosub ~ Returnステートメントは64ビットコンパイラで利用することはできません。",cp);
945}
946void OpcodeReturn(char *Parameter){
947 extern BOOL bCompilingGlobal;
948 if(bCompilingGlobal){
949 SetError(62,NULL,cp);
950 }
951 else{
952 //戻り値をセット
953 if(Parameter[0]){
954 extern SUBINFO *pCompilingSubInfo;
955 char *temp;
956 if(pCompilingSubInfo->name[0]==1&&pCompilingSubInfo->name[1]==ESC_OPERATOR)
957 temp="_System_ReturnValue";
958 else temp=pCompilingSubInfo->name;
959
960 if( pCompilingSubInfo->isReturnRef ){
961 //参照型
962 SetRefVariable( temp, Parameter );
963 }
964 else{
965 //値型
966 char temporary[VN_SIZE];
967 sprintf(temporary,"%s=%s",temp,Parameter);
968 OpcodeCalc(temporary);
969 }
970 }
971
972 //プロシージャを抜け出す(C言語のreturnと同様の処理を行う)
973 OpcodeExitSub();
974 }
975}
976
977void Opcode_Input(char *Parameter){
978 extern int cp;
979 int i2,i3,i4,i5,type;
980 BOOL bFile;
981 char temporary[VN_SIZE],temp2[VN_SIZE],buffer[VN_SIZE];
982
983 KillStringSpaces(Parameter);
984
985 if(Parameter[0]=='#'){
986 bFile=1;
987 for(i2=0,i3=1;;i2++,i3++){
988 buffer[i2]=Parameter[i3];
989 if(Parameter[i3]==','||Parameter[i3]=='\0') break;
990 }
991 buffer[i2+1]=0;
992 i2=i3+1;
993 }
994 else{
995 bFile=0;
996 i2=0;
997 buffer[0]=0;
998
999 //表示用文字列パラメータをセット
1000 if(Parameter[0]=='\"'){
1001 buffer[0]='\"';
1002 for(i2=1;;i2++){
1003 if(Parameter[i2]=='\"'){
1004 buffer[i2]=0;
1005 break;
1006 }
1007 buffer[i2]=Parameter[i2];
1008 }
1009 if(Parameter[i2+1]==';') lstrcpy(buffer+i2,"? \"");
1010 else if(Parameter[i2+1]==',') lstrcpy(buffer+i2,"\"");
1011 else SetError(10,"Input",cp);
1012 i2+=2;
1013 }
1014 else if((Parameter[0]=='e'||Parameter[0]=='E')&&
1015 (Parameter[1]=='x'||Parameter[1]=='X')&&
1016 Parameter[2]=='\"'){
1017 memcpy(buffer,Parameter,3);
1018 for(i2=3;;i2++){
1019 if(Parameter[i2]=='\"'){
1020 buffer[i2]=0;
1021 break;
1022 }
1023 buffer[i2]=Parameter[i2];
1024 }
1025 if(Parameter[i2+1]==';') lstrcpy(buffer+i2,"? \"");
1026 else if(Parameter[i2+1]==',') lstrcpy(buffer+i2,"\"");
1027 else SetError(10,"Input",cp);
1028 i2+=2;
1029 }
1030 else{
1031 lstrcpy(buffer,"\"? \"");
1032 i2=0;
1033 }
1034 }
1035
1036 //変数ポインタ、変数のタイプをセット
1037 i4=0;
1038 while(1){
1039 for(i3=0;;i2++,i3++){
1040 if(Parameter[i2]=='('){
1041 i5=GetStringInPare(temporary+i3,Parameter+i2);
1042 i2+=i5-1;
1043 i3+=i5-1;
1044 }
1045 if(Parameter[i2]=='['){
1046 i5=GetStringInBracket(temporary+i3,Parameter+i2);
1047 i2+=i5-1;
1048 i3+=i5-1;
1049 }
1050 if(Parameter[i2]==','){
1051 temporary[i3]=0;
1052 i2++;
1053 break;
1054 }
1055 temporary[i3]=Parameter[i2];
1056 if(Parameter[i2]=='\0') break;
1057 }
1058 if(temporary[0]=='\0'){
1059 SetError(10,"Input",cp);
1060 return;
1061 }
1062
1063 LONG_PTR lpIndex;
1064 type = GetVarType(temporary, &lpIndex, 1);
1065
1066 sprintf(temp2,"_System_InputDataPtr[%d]=VarPtr(%s)",i4,temporary);
1067 OpcodeCalc(temp2);
1068
1069 if(type==DEF_LONG) type=DEF_DWORD;
1070 else if(type==DEF_INTEGER) type=DEF_WORD;
1071 else if(type==DEF_OBJECT){
1072 CClass *pobj_Class=(CClass *)lpIndex;
1073 if(lstrcmp(pobj_Class->name,"String")==0) type=DEF_STRING;
1074 }
1075 sprintf(temp2,"_System_InputDataType[%d]=%d",i4,type);
1076 OpcodeCalc(temp2);
1077
1078 i4++;
1079 if(Parameter[i2]=='\0') break;
1080 }
1081 sprintf(temp2,"_System_InputDataPtr[%d]=0",i4);
1082 OpcodeCalc(temp2);
1083
1084 SUBINFO *psi;
1085 if(bFile) psi=GetSubHash("INPUT_FromFile");
1086 else psi=GetSubHash("INPUT_FromPrompt");
1087 if(!psi){
1088 SetError(3,"Input",cp);
1089 return;
1090 }
1091 Opcode_CallProc(buffer,psi,0,"",0);
1092}
1093void Opcode_PrintUsing(char *Parameter,char *buffer,BOOL bFile){
1094 extern int cp;
1095 int i2,i3,i4,i5;
1096 char temporary[VN_SIZE],temp2[8192];
1097 BOOL bReturnLine;
1098
1099 i2=lstrlen(Parameter);
1100 if(Parameter[i2-1]==';'){
1101 bReturnLine=0;
1102 Parameter[i2-1]=0;
1103 }
1104 else bReturnLine=1;
1105
1106 i3=lstrlen(buffer);
1107 for(i2=0;;i2++,i3++){
1108 if(Parameter[i2]==';'){
1109 buffer[i3]=0;
1110 break;
1111 }
1112 buffer[i3]=Parameter[i2];
1113 if(Parameter[i2]=='\0') break;
1114 }
1115 if(Parameter[i2]==';') i2++;
1116
1117 if(bReturnLine) lstrcat(buffer,"+Ex\"\\r\\n\"");
1118
1119 //データポインタ、データのタイプをセット
1120 i4=0;
1121 while(1){
1122 for(i3=0;;i2++,i3++){
1123 if(Parameter[i2]=='\"'){
1124 temporary[i3]=Parameter[i2];
1125 for(i2++,i3++;;i2++,i3++){
1126 temporary[i3]=Parameter[i2];
1127 if(Parameter[i2]=='\"') break;
1128 }
1129 continue;
1130 }
1131 if(Parameter[i2]=='('){
1132 i5=GetStringInPare(temporary+i3,Parameter+i2);
1133 i2+=i5-1;
1134 i3+=i5-1;
1135 continue;
1136 }
1137 if(Parameter[i2]=='['){
1138 i5=GetStringInBracket(temporary+i3,Parameter+i2);
1139 i2+=i5-1;
1140 i3+=i5-1;
1141 continue;
1142 }
1143 if(Parameter[i2]==','){
1144 temporary[i3]=0;
1145 i2++;
1146 break;
1147 }
1148 temporary[i3]=Parameter[i2];
1149 if(Parameter[i2]=='\0') break;
1150 }
1151 if(temporary[0]=='\0'){
1152 SetError(10,"Print",cp);
1153 return;
1154 }
1155
1156 int iResult;
1157 iResult=IsStrCalculation(temporary);
1158
1159 if(iResult==1){
1160 //文字列
1161 sprintf(temp2,"_System_UsingStrData[%d]=%s",i4,temporary);
1162 OpcodeCalc(temp2);
1163
1164 sprintf(temp2,"_System_UsingDataType[%d]=%d",i4,DEF_STRING);
1165 OpcodeCalc(temp2);
1166 }
1167 else if(iResult==0){
1168 //数値
1169 sprintf(temp2,"_System_UsingDblData[%d]=%s",i4,temporary);
1170 OpcodeCalc(temp2);
1171
1172 sprintf(temp2,"_System_UsingDataType[%d]=%d",i4,DEF_DOUBLE);
1173 OpcodeCalc(temp2);
1174 }
1175 //else if(iResult==-1) エラー
1176
1177 i4++;
1178 if(Parameter[i2]=='\0') break;
1179 }
1180 sprintf(temp2,"_System_UsingDataType[%d]=-1",i4);
1181 OpcodeCalc(temp2);
1182
1183 SUBINFO *psi;
1184 if(bFile) psi=GetSubHash("PRINTUSING_ToFile");
1185 else psi=GetSubHash("PRINTUSING_ToPrompt");
1186 if(!psi){
1187 SetError(3,"Print",cp);
1188 return;
1189 }
1190 Opcode_CallProc(buffer,psi,0,"",0);
1191}
1192void Opcode_Print(char *Parameter,BOOL bWrite){
1193 int i2,i3,i4,sw;
1194 char temporary[VN_SIZE],buffer[VN_SIZE];
1195 BOOL bFile;
1196
1197 KillStringSpaces(Parameter);
1198
1199 if(Parameter[0]=='#'){
1200 bFile=1;
1201 for(i2=0,i3=1;;i2++,i3++){
1202 buffer[i2]=Parameter[i3];
1203 if(Parameter[i3]==','||Parameter[i3]=='\0') break;
1204 }
1205 buffer[i2+1]=0;
1206 if(Parameter[i3]==',') i3++;
1207 i2=i3;
1208 }
1209 else{
1210 bFile=0;
1211 i2=0;
1212 buffer[0]=0;
1213 }
1214 if(Parameter[i2]==1&&Parameter[i2+1]==ESC_USING){
1215 Opcode_PrintUsing(Parameter+i2+2,buffer,bFile);
1216 return;
1217 }
1218
1219 lstrcat(buffer,"_System_DummyStr+");
1220
1221 sw=1;
1222 while(1){
1223 for(i3=0;;i2++,i3++){
1224 if(Parameter[i2]=='\"'){
1225 temporary[i3]=Parameter[i2];
1226 for(i2++,i3++;;i2++,i3++){
1227 temporary[i3]=Parameter[i2];
1228 if(Parameter[i2]=='\"') break;
1229 }
1230 continue;
1231 }
1232 if(Parameter[i2]=='('){
1233 i4=GetStringInPare(temporary+i3,Parameter+i2);
1234 i2+=i4-1;
1235 i3+=i4-1;
1236 continue;
1237 }
1238 if(Parameter[i2]=='['){
1239 i4=GetStringInBracket(temporary+i3,Parameter+i2);
1240 i2+=i4-1;
1241 i3+=i4-1;
1242 continue;
1243 }
1244 if(Parameter[i2]==','||Parameter[i2]==';'){
1245 temporary[i3]=0;
1246 break;
1247 }
1248 temporary[i3]=Parameter[i2];
1249 if(Parameter[i2]=='\0') break;
1250 }
1251
1252 if(temporary[0]=='\0') lstrcat(buffer,"\"\"");
1253 else{
1254 int iResult;
1255 iResult=IsStrCalculation(temporary);
1256 if(iResult==-1){
1257 //エラー
1258 lstrcat(buffer,"\"\"");
1259 }
1260 else if(iResult){
1261 //文字列
1262 lstrcat(buffer,temporary);
1263 }
1264 else{
1265 //数値
1266 sprintf(buffer+lstrlen(buffer),"Str$(%s)",temporary);
1267 }
1268 }
1269
1270 if(Parameter[i2]==','){
1271 if(bWrite) lstrcat(buffer,"+\",\"+");
1272 else lstrcat(buffer,"+\"\t\"+");
1273 }
1274 else if(Parameter[i2]==';'){
1275 if(Parameter[i2+1]=='\0'){
1276 sw=0;
1277 break;
1278 }
1279 if(bWrite) lstrcat(buffer,"+\",\"+");
1280 else lstrcat(buffer,"+\" \"+");
1281 }
1282 else if(Parameter[i2]=='\0') break;
1283
1284 i2++;
1285 }
1286
1287 if(sw) lstrcat(buffer,"+Ex\"\\r\\n\"");
1288
1289 SUBINFO *psi;
1290 if(bFile) psi=GetSubHash("PRINT_ToFile");
1291 else psi=GetSubHash("PRINT_ToPrompt");
1292 if(!psi){
1293 SetError(3,"Print",cp);
1294 return;
1295 }
1296 Opcode_CallProc(buffer,psi,0,"",0);
1297}
1298
1299
1300
1301
1302////////////
1303// ポインタ
1304////////////
1305
1306void OpcodeSetPtrData(char *Parameter,int type){
1307 int i,i2;
1308 char temporary[VN_SIZE];
1309
1310 if(Parameter[0]=='('){
1311 i=JumpStringInPare(Parameter,1);
1312 if(Parameter[i+1]=='\0'){
1313 for(i=0;;i++){
1314 Parameter[i]=Parameter[i+1];
1315 if(Parameter[i]=='\0') break;
1316 }
1317 Parameter[i-1]=0;
1318 }
1319 }
1320
1321 //第1パラメータを取得
1322 i=GetOneParameter(Parameter,0,temporary);
1323 if(!Parameter[i]){
1324 SetError(1,NULL,cp);
1325 return;
1326 }
1327
1328 int reg_ptr=REG_RAX;
1329 i2=NumOpe(&reg_ptr,temporary,0,0,0);
1330 if(!IsWholeNumberType(i2)){
1331 SetError(11,Parameter,cp);
1332 return;
1333 }
1334
1335 //結果を格納しているレジスタをブロッキング
1336 pobj_BlockReg->lock(reg_ptr);
1337
1338 //第2パラメータを取得
1339 i=GetOneParameter(Parameter,i,temporary);
1340 if(Parameter[i]){
1341 SetError(1,NULL,cp);
1342 return;
1343 }
1344
1345 int temp_reg=REG_NON;
1346 i2=NumOpe(&temp_reg,temporary,0,0,0);
1347
1348 //レジスタのブロッキングを解除
1349 pobj_BlockReg->clear();
1350
1351 if(type==DEF_DOUBLE){
1352 ChangeTypeToXmm_Double(i2,REG_XMM0,temp_reg);
1353
1354 //movsd qword ptr[reg_ptr],xmm0
1355 op_movsd_MR(REG_XMM0,reg_ptr,0,MOD_BASE);
1356 }
1357 else if(type==DEF_SINGLE){
1358 ChangeTypeToXmm_Single(i2,REG_XMM0,temp_reg);
1359
1360 //movss dword ptr[reg_ptr],xmm0
1361 op_movss_MR(REG_XMM0,reg_ptr,0,MOD_BASE);
1362 }
1363 else{
1364 ChangeTypeToWhole(i2,type,REG_RCX,temp_reg);
1365
1366 //mov ptr[reg_ptr],rcx
1367 op_mov_MR(GetTypeSize(type,-1),REG_RCX,reg_ptr,0,MOD_BASE);
1368 }
1369}
Note: See TracBrowser for help on using the repository browser.