source: dev/BasicCompiler64/Compile_Statement.cpp@ 73

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

Parameterクラスを適用。32bit側は動くようになったので、64bitのほうを調整する。

File size: 30.5 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_STRUCT){
102 //mov r14,rax
103 op_mov_RR(REG_R14,REG_RAX);
104
105 FreeTempObject(REG_R14,(CClass *)lp);
106 }
107 return;
108 }
109
110
111 //////////////////////////
112 // その他は代入演算を行う
113 //////////////////////////
114 OpcodeCalc(Command);
115}
116
117void Judgment(char *buffer){
118 int reg=REG_RAX,type;
119 type=NumOpe(&reg,buffer,0,0,0);
120
121 int offset;
122
123 if(type==DEF_DOUBLE){
124 double dbl=0;
125 offset=dataTable.Add( dbl );
126
127 //comisd xmm0,qword ptr[data table offset]
128 OpBuffer[obp++]=(char)0x66;
129 OpBuffer[obp++]=(char)0x0F;
130 OpBuffer[obp++]=(char)0x2F;
131 OpBuffer[obp++]=(char)0x04;
132 OpBuffer[obp++]=(char)0x25;
133 *((long *)(OpBuffer+obp))=offset;
134 pobj_DataTableSchedule->add();
135 obp+=sizeof(long);
136 }
137 else if(type==DEF_SINGLE){
138 float flt=0;
139 offset=dataTable.Add( flt );
140
141 //comiss xmm0,dword ptr[data table offset]
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 }
150 else{
151 //整数型
152
153 //cmp rax,0
154 op_cmp_value(GetTypeSize(type,-1),REG_RAX,0);
155 }
156}
157
158void OpcodeIf(char *Parameter){
159 int i,i2,i3;
160
161 for(i=0;;i++){
162 if(Parameter[i]=='\0'){
163 SetError(21,NULL,cp);
164 return;
165 }
166 if(Parameter[i]==1&&Parameter[i+1]==ESC_THEN){
167 Parameter[i]=0;
168 break;
169 }
170 }
171
172 //条件式を実行してフラグをセット
173 Judgment(Parameter);
174
175 //je (endif、または else まで条件ジャンプ)
176 OpBuffer[obp++]=(char)0x0F;
177 OpBuffer[obp++]=(char)0x84;
178 obp+=sizeof(long);
179
180 //jeの番地
181 i3=obp;
182
183
184 /////////////////////////
185 // If内をコード化
186 /////////////////////////
187
188 //レキシカルスコープをレベルアップ
189 obj_LexScopes.Start( obp, SCOPE_TYPE_IF );
190
191 i2=CompileBuffer(ESC_ENDIF,0);
192
193 //レキシカルスコープをレベルダウン
194 obj_LexScopes.End();
195
196
197 extern char *basbuf;
198 if(i2==ESC_ELSE){
199 //jmp (endifまで)
200 OpBuffer[obp++]=(char)0xE9;
201 obp+=sizeof(long);
202
203 *((long *)(OpBuffer+i3-sizeof(long)))=obp-i3; //ifからelseへのジャンプ先のオフセット値
204
205 i3=obp;
206
207
208 /////////////////////////
209 // Else内をコード化
210 /////////////////////////
211
212 //レキシカルスコープをレベルアップ
213 obj_LexScopes.Start( obp, SCOPE_TYPE_IF );
214
215 CompileBuffer(ESC_ENDIF,0);
216
217 //レキシカルスコープをレベルダウン
218 obj_LexScopes.End();
219
220
221 *((long *)(OpBuffer+i3-sizeof(long)))=obp-i3; //jmpジャンプ先のオフセット値
222 }
223 else{
224 *((long *)(OpBuffer+i3-sizeof(long)))=obp-i3; //jeジャンプ先のオフセット値
225 }
226}
227
228int GetLabelAddress(char *LabelName,int LineNum){
229 extern int MaxLabelNum;
230 extern LABEL *pLabelNames;
231 int i;
232
233 if(LabelName){
234 for(i=0;i<MaxLabelNum;i++){
235 if(pLabelNames[i].pName){
236 if(lstrcmp(LabelName,pLabelNames[i].pName)==0) return pLabelNames[i].address;
237 }
238 }
239 }
240 else{
241 for(i=0;i<MaxLabelNum;i++){
242 if(pLabelNames[i].pName==0){
243 if(LineNum==pLabelNames[i].line) return pLabelNames[i].address;
244 }
245 }
246 }
247 return -1;
248}
249void OpcodeGoto(char *Parameter){
250 extern HANDLE hHeap;
251 extern GOTOLABELSCHEDULE *pGotoLabelSchedule;
252 extern int GotoLabelScheduleNum;
253 int i,LineNum;
254
255 if(Parameter[0]=='*'){
256 i=GetLabelAddress(Parameter+1,0);
257
258 //jmp ...
259 OpBuffer[obp++]=(char)0xE9;
260 if(i==-1){
261 pGotoLabelSchedule=(GOTOLABELSCHEDULE *)HeapReAlloc(hHeap,0,pGotoLabelSchedule,(GotoLabelScheduleNum+1)*sizeof(GOTOLABELSCHEDULE));
262 pGotoLabelSchedule[GotoLabelScheduleNum].pName=(char *)HeapAlloc(hHeap,0,lstrlen(Parameter+1)+1);
263 lstrcpy(pGotoLabelSchedule[GotoLabelScheduleNum].pName,Parameter+1);
264 pGotoLabelSchedule[GotoLabelScheduleNum].pos=obp;
265 pGotoLabelSchedule[GotoLabelScheduleNum].now_cp=cp;
266 GotoLabelScheduleNum++;
267 }
268 *((long *)(OpBuffer+obp))=i-(obp+sizeof(long));
269 obp+=sizeof(long);
270 }
271 else{
272 LineNum=atoi(Parameter);
273 i=GetLabelAddress(0,LineNum);
274
275 //jmp ...
276 OpBuffer[obp++]=(char)0xE9;
277 if(i==-1){
278 pGotoLabelSchedule=(GOTOLABELSCHEDULE *)HeapReAlloc(hHeap,0,pGotoLabelSchedule,(GotoLabelScheduleNum+1)*sizeof(GOTOLABELSCHEDULE));
279 pGotoLabelSchedule[GotoLabelScheduleNum].pName=0;
280 pGotoLabelSchedule[GotoLabelScheduleNum].line=LineNum;
281 pGotoLabelSchedule[GotoLabelScheduleNum].pos=obp;
282 pGotoLabelSchedule[GotoLabelScheduleNum].now_cp=cp;
283 GotoLabelScheduleNum++;
284 }
285 *((long *)(OpBuffer+obp))=i-(obp+sizeof(long));
286 obp+=sizeof(long);
287 }
288}
289void OpcodeWhile(char *Parameter){
290 extern HANDLE hHeap;
291
292 //Continueアドレスのバックアップとセット
293 extern DWORD dwContinueAddress;
294 DWORD dwTempContinue;
295 dwTempContinue=dwContinueAddress;
296 dwContinueAddress=obp;
297 pobj_TempSchedule->lock((int *)&dwTempContinue);
298 pobj_TempSchedule->lock((int *)&dwContinueAddress);
299
300 if(!Parameter[0]) SetError(10,"While",cp);
301
302 //条件式を実行してフラグをセット
303 Judgment(Parameter);
304
305 //je (Wend まで)
306 OpBuffer[obp++]=(char)0x0F;
307 OpBuffer[obp++]=(char)0x84;
308 obp+=sizeof(long);
309
310 //実行中の番地
311 int je_schedule=obp;
312 pobj_TempSchedule->lock(&je_schedule);
313
314 //レキシカルスコープをレベルアップ
315 obj_LexScopes.Start( obp, SCOPE_TYPE_WHILE );
316
317 //While内をコンパイル
318 CompileBuffer(0,COM_WEND);
319
320 obj_LexScopes.CallDestructorsOfScopeEnd();
321
322 //jmp ...
323 OpBuffer[obp++]=(char)0xE9;
324 *((long *)(OpBuffer+obp))=dwContinueAddress-(obp+sizeof(long));
325 obp+=sizeof(long);
326 pobj_TempSchedule->unlock();
327 pobj_TempSchedule->unlock();
328
329 //レキシカルスコープをレベルダウン
330 obj_LexScopes.End();
331
332 *((long *)(OpBuffer+je_schedule-sizeof(long)))=obp-je_schedule; //jeジャンプ先のオフセット値
333 pobj_TempSchedule->unlock();
334
335 //Continueアドレスを復元
336 dwContinueAddress=dwTempContinue;
337}
338
339char szNextVariable[VN_SIZE];
340void OpcodeFor(char *Parameter){
341 extern HANDLE hHeap;
342 int i,i2,i3;
343 char temporary[VN_SIZE],variable[VN_SIZE],JudgeNum[VN_SIZE],StepNum[VN_SIZE];
344 bool isError = false;
345
346 //第1パラメータを取得
347 i=GetOneParameter(Parameter,0,temporary);
348 if(!Parameter[i]){
349 SetError(12,"For",cp);
350 isError = true;
351 goto ErrorStep;
352 }
353
354 for(i2=0;;i2++){
355 if(temporary[i2]=='='){
356 variable[i2]=0;
357
358 //カウンタ初期化
359 OpcodeCalc(temporary);
360 break;
361 }
362 if(temporary[i2]=='\0'){
363 SetError(12,"For",cp);
364 isError = true;
365 goto ErrorStep;
366 }
367 variable[i2]=temporary[i2];
368 }
369
370 //jmp ...
371 OpBuffer[obp++]=(char)0xE9;
372 i2=obp;
373 obp+=sizeof(long);
374
375 //Continueアドレスのバックアップとセット
376 extern DWORD dwContinueAddress;
377 DWORD dwTempContinue;
378 dwTempContinue=dwContinueAddress;
379 dwContinueAddress=obp;
380 pobj_TempSchedule->lock((int *)&dwTempContinue);
381 pobj_TempSchedule->lock((int *)&dwContinueAddress);
382
383 //第2パラメータを取得(to~)
384 i=GetOneParameter(Parameter,i,JudgeNum);
385
386 //第3パラメータを取得(step~)
387 if(Parameter[i]){
388 i=GetOneParameter(Parameter,i,StepNum);
389 if(Parameter[i]) SetError(12,"For",cp);
390 }
391 else lstrcpy(StepNum,"1");
392
393 //カウンタを増加させる
394 sprintf(temporary,"%s=(%s)+(%s)",variable,variable,StepNum);
395 OpcodeCalc(temporary);
396
397 *((long *)(OpBuffer+i2))=obp-(i2+sizeof(long));
398
399 //増加か減少かを区別する
400 sprintf(temporary,"(%s)>=0",StepNum);
401
402 int reg,type;
403 reg=REG_RAX;
404 type=NumOpe(&reg,temporary,0,0,0);
405
406 //cmp rax,0
407 op_cmp_value(GetTypeSize(type,-1),REG_RAX,0);
408
409 //je [カウンタ減少の場合の判定]
410 OpBuffer[obp++]=(char)0x0F;
411 OpBuffer[obp++]=(char)0x84;
412 i2=obp;
413 obp+=sizeof(long);
414
415 //判定(カウンタ増加の場合)
416 sprintf(temporary,"%s<=(%s)",variable,JudgeNum);
417
418 reg=REG_RAX;
419 type=NumOpe(&reg,temporary,0,0,0);
420
421 //jmp [カウンタ減少の場合の判定を飛び越す]
422 OpBuffer[obp++]=(char)0xE9;
423 i3=obp;
424 obp+=sizeof(long);
425
426 *((long *)(OpBuffer+i2))=obp-(i2+sizeof(long)); //jeジャンプ先のオフセット値
427
428 //判定(カウンタ減少の場合)
429 sprintf(temporary,"%s>=(%s)",variable,JudgeNum);
430
431 reg=REG_RAX;
432 type=NumOpe(&reg,temporary,0,0,0);
433
434 *((long *)(OpBuffer+i3))=obp-(i3+sizeof(long)); //jmpジャンプ先のオフセット値
435
436 //cmp rax,0
437 op_cmp_value(GetTypeSize(type,-1),REG_RAX,0);
438
439ErrorStep:
440
441 //je ...
442 OpBuffer[obp++]=(char)0x0F;
443 OpBuffer[obp++]=(char)0x84;
444 int je_schedule=obp;
445 obp+=sizeof(long);
446 pobj_TempSchedule->lock(&je_schedule);
447
448 //レキシカルスコープをレベルアップ
449 obj_LexScopes.Start( obp, SCOPE_TYPE_FOR );
450
451 //For内をコンパイル
452 CompileBuffer(0,COM_NEXT);
453
454 obj_LexScopes.CallDestructorsOfScopeEnd();
455
456 if(szNextVariable[0]){
457 if(lstrcmp(szNextVariable,variable)!=0){
458 SetError(55,szNextVariable,cp);
459 }
460 }
461
462 //jmp ...
463 OpBuffer[obp++]=(char)0xE9;
464 *((long *)(OpBuffer+obp))=dwContinueAddress-(obp+sizeof(long));
465 obp+=sizeof(long);
466 if( isError == false ){
467 pobj_TempSchedule->unlock();
468 pobj_TempSchedule->unlock();
469 }
470
471 //レキシカルスコープをレベルダウン
472 obj_LexScopes.End();
473
474 *((long *)(OpBuffer+je_schedule))=obp-(je_schedule+sizeof(long)); //jeジャンプ先のオフセット値
475 pobj_TempSchedule->unlock();
476
477 //Continueアドレスを復元
478 dwContinueAddress=dwTempContinue;
479}
480
481void OpcodeDo(char *Parameter){
482 extern HANDLE hHeap;
483 int i,i2,i3;
484
485 if(Parameter[0]) SetError(10,"Do",cp);
486
487 //Continueアドレスのバックアップとセット
488 extern DWORD dwContinueAddress;
489 DWORD dwTempContinue;
490 dwTempContinue=dwContinueAddress;
491 dwContinueAddress=obp;
492 pobj_TempSchedule->lock((int *)&dwTempContinue);
493 pobj_TempSchedule->lock((int *)&dwContinueAddress);
494
495 //レキシカルスコープをレベルアップ
496 obj_LexScopes.Start( obp, SCOPE_TYPE_DO );
497
498 //Do内をコンパイル
499 CompileBuffer(0,COM_LOOP);
500
501 obj_LexScopes.CallDestructorsOfScopeEnd();
502
503 extern char *basbuf;
504 char temporary[VN_SIZE];
505 for(i=cp-1;;i--){
506 if(IsCommandDelimitation(basbuf[i])){
507 i+=3;
508 if(!(basbuf[i]=='0'||basbuf[i]=='1')){
509 //無条件ループ
510 break;
511 }
512 i3=i;
513
514 for(i+=2,i2=0;;i++,i2++){
515 if(IsCommandDelimitation(basbuf[i])){
516 temporary[i2]=0;
517 break;
518 }
519 temporary[i2]=basbuf[i];
520 }
521
522 //条件式を実行してフラグをセット
523 Judgment(temporary);
524
525 if(basbuf[i3]=='0'){
526 //While
527
528 //je 5(ループ終了)
529 OpBuffer[obp++]=(char)0x74;
530 OpBuffer[obp++]=(char)0x05;
531 }
532 else if(basbuf[i3]=='1'){
533 //Until
534
535 //jne 5(ループ終了)
536 OpBuffer[obp++]=(char)0x75;
537 OpBuffer[obp++]=(char)0x05;
538 }
539 break;
540 }
541 }
542
543 //jmp ...
544 OpBuffer[obp++]=(char)0xE9;
545 *((long *)(OpBuffer+obp))=dwContinueAddress-(obp+sizeof(long));
546 obp+=sizeof(long);
547 pobj_TempSchedule->unlock();
548 pobj_TempSchedule->unlock();
549
550 //jmp ...
551 OpBuffer[obp++]=(char)0xE9;
552 int je_schedule=obp;
553 obp+=sizeof(long);
554 pobj_TempSchedule->lock(&je_schedule);
555
556 //レキシカルスコープをレベルダウン
557 obj_LexScopes.End();
558
559 *((long *)(OpBuffer+je_schedule))=obp-(je_schedule+sizeof(long)); //jmpジャンプ先のオフセット値
560 pobj_TempSchedule->unlock();
561
562 //Continueアドレスを復元
563 dwContinueAddress=dwTempContinue;
564}
565void OpcodeContinue(void){
566 extern DWORD dwContinueAddress;
567
568 if(dwContinueAddress==-1){
569 SetError(12,"Continue",cp);
570 return;
571 }
572
573 //jmp ...(Continue addr)
574 OpBuffer[obp++]=(char)0xE9;
575
576 *((long *)(OpBuffer+obp))=dwContinueAddress-(obp+sizeof(long));
577 obp+=sizeof(long);
578}
579
580void OpcodeExitSub(void){
581 extern DWORD *pExitSubSchedule;
582 extern int ExitSubScheduleNum;
583 extern HANDLE hHeap;
584
585 extern BOOL bCompilingGlobal;
586 if(bCompilingGlobal){
587 SetError(12,"Exit Sub/Function",cp);
588 return;
589 }
590
591 //未解放のローカルオブジェクトのデストラクタを呼び出す
592 obj_LexScopes.CallDestructorsOfReturn();
593
594 //jmp ...(End Sub/Function)
595 OpBuffer[obp++]=(char)0xE9;
596
597 pExitSubSchedule=(DWORD *)HeapReAlloc(hHeap,0,pExitSubSchedule,(ExitSubScheduleNum+1)*sizeof(DWORD));
598 pExitSubSchedule[ExitSubScheduleNum]=obp;
599 ExitSubScheduleNum++;
600
601 obp+=sizeof(long);
602}
603
604void AddCaseSchedule(void){
605 extern DWORD *pCaseSchedule;
606 extern int CaseScheduleNum;
607 extern HANDLE hHeap;
608
609 pCaseSchedule=(DWORD *)HeapReAlloc(hHeap,0,pCaseSchedule,(CaseScheduleNum+1)*sizeof(DWORD));
610 pCaseSchedule[CaseScheduleNum]=obp;
611 CaseScheduleNum++;
612}
613void OpcodeSelect(char *Parameter){
614 extern DWORD *pCaseSchedule;
615 extern int CaseScheduleNum;
616 extern int NowCaseSchedule;
617 extern HANDLE hHeap;
618 extern char *basbuf;
619 int i,i2,i3,NowCaseCp;
620 char temporary[VN_SIZE];
621
622 DWORD *temp_pCaseSchedule;
623 int temp_CaseScheduleNum;
624 int temp_NowCaseSchedule;
625
626 temp_pCaseSchedule=pCaseSchedule;
627 temp_CaseScheduleNum=CaseScheduleNum;
628 temp_NowCaseSchedule=NowCaseSchedule;
629 pCaseSchedule=(DWORD *)HeapAlloc(hHeap,0,1);
630 CaseScheduleNum=0;
631 NowCaseSchedule=0;
632
633 int reg1=REG_RAX,type1;
634 LONG_PTR lpIndex;
635 type1=NumOpe(&reg1,Parameter,0,0,&lpIndex);
636
637 if(type1==DEF_DOUBLE){
638 //movsd qword ptr[rsp+offset],xmm_reg ※スタックフレームを利用
639 pobj_sf->push(reg1,sizeof(double));
640 }
641 else if(type1==DEF_SINGLE){
642 //movss dword ptr[rsp+offset],xmm_reg ※スタックフレームを利用
643 pobj_sf->push(reg1,sizeof(float));
644 }
645 else{
646 ExtendTypeTo64(type1,reg1);
647
648 //mov qword ptr[rsp+offset],reg ※スタックフレームを利用
649 pobj_sf->push(reg1);
650 }
651
652 for(i=cp;;i++){
653 if(basbuf[i]=='\0'){
654 HeapDefaultFree(pCaseSchedule);
655 pCaseSchedule=temp_pCaseSchedule;
656 CaseScheduleNum=temp_CaseScheduleNum;
657 NowCaseSchedule=temp_NowCaseSchedule;
658 SetError(22,"Select",cp);
659 return;
660 }
661 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE){
662 for(i2=0;;i++){
663 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE) i2++;
664 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT){
665 i2--;
666 if(i2==0) break;
667 }
668 }
669 continue;
670 }
671 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT) break;
672
673 if(basbuf[i]==1&&basbuf[i+1]==ESC_CASE){
674 NowCaseCp=i;
675
676 i++;
677 while(1){
678 for(i++,i2=0;;i++,i2++){
679 if(basbuf[i]=='\"'){
680 i3=GetStringInQuotation(temporary+i2,basbuf+i);
681 i+=i3-1;
682 i2+=i3-1;
683 continue;
684 }
685 if(basbuf[i]=='('){
686 i3=GetStringInPare(temporary+i2,basbuf+i);
687 i+=i3-1;
688 i2+=i3-1;
689 continue;
690 }
691 if(basbuf[i]=='['){
692 i3=GetStringInBracket(temporary+i2,basbuf+i);
693 i+=i3-1;
694 i2+=i3-1;
695 continue;
696 }
697
698 if(IsCommandDelimitation(basbuf[i])){
699 temporary[i2]=0;
700 break;
701 }
702 if(basbuf[i]==','){
703 temporary[i2]=0;
704 break;
705 }
706
707 temporary[i2]=basbuf[i];
708 }
709
710 //エラー用
711 i2=cp;
712 cp=NowCaseCp;
713
714 int reg2=REG_RDX,type2;
715 LONG_PTR lpIndex2;
716 type2=NumOpe(&reg2,temporary,type1,lpIndex,&lpIndex2);
717
718 cp=i2;
719
720 if(type1==DEF_OBJECT){
721 CClass *pobj_c;
722 pobj_c=(CClass *)lpIndex;
723
724 std::vector<SubInfo *> subs;
725 pobj_c->EnumMethod( CALC_EQUAL, subs );
726 if( subs.size() == 0 ){
727 return;
728 }
729
730 PARAMETER_INFO *ppi = (PARAMETER_INFO *)HeapAlloc(hHeap,0,sizeof(PARAMETER_INFO)*3);
731 int iParmNum=0;
732 ppi[iParmNum].bArray=0;
733 ppi[iParmNum].bByVal=0;
734 ppi[iParmNum].name=0;
735 ppi[iParmNum].type=type2;
736 ppi[iParmNum].u.index=lpIndex2;
737 ppi[iParmNum].SubScripts[0]=-1;
738 iParmNum++;
739
740 //オーバーロードを解決
741 SubInfo *psi;
742 psi=OverloadSolution("==",subs,ppi,iParmNum,NULL);
743 HeapDefaultFree(ppi);
744
745 if(!psi){
746 //エラー
747 return;
748 }
749
750
751 //実体オブジェクト
752 if(reg2!=REG_RDX){
753 //mov rdx,reg2
754 op_mov_RR(REG_RDX,reg2);
755 }
756
757 //mov rcx,qword ptr[rsp+offset] ※スタックフレームから参照
758 pobj_sf->ref(REG_RCX);
759
760 //call operator_proc ※ ==演算子
761 op_call(psi);
762
763 //test rax,rax
764 op_test(REG_RAX,REG_RAX);
765
766 //jne ...
767 OpBuffer[obp++]=(char)0x0F;
768 OpBuffer[obp++]=(char)0x85;
769 }
770 else{
771 if(type1==DEF_DOUBLE){
772 int xmm_reg;
773 if(IsXmmReg(reg2)) xmm_reg=reg2;
774 else xmm_reg=REG_XMM5;
775 ChangeTypeToXmm_Double(type2,xmm_reg,reg2);
776
777 //movsd xmm4,qword ptr[rsp+offset] ※スタックフレームから参照
778 pobj_sf->ref(REG_XMM4,sizeof(double));
779
780 //comiss xmm_reg1,xmm_reg2
781 op_comisd(xmm_reg,REG_XMM4);
782 }
783 else if(type1==DEF_SINGLE){
784 int xmm_reg;
785 if(IsXmmReg(reg2)) xmm_reg=reg2;
786 else xmm_reg=REG_XMM5;
787 ChangeTypeToXmm_Single(type2,xmm_reg,reg2);
788
789 //movss xmm4,dword ptr[rsp+offset] ※スタックフレームから参照
790 pobj_sf->ref(REG_XMM4,sizeof(float));
791
792 //comiss xmm_reg1,xmm_reg2
793 op_comiss(xmm_reg,REG_XMM4);
794 }
795 else{
796 //その他整数型
797
798 i2=NeutralizationType(type1,-1,type2,-1);
799
800 //mov r14,qword ptr[rsp+offset] ※スタックフレームから参照
801 pobj_sf->ref(REG_R14);
802
803 //cmp reg2,r14
804 op_cmp_reg(GetTypeSize(i2,-1),reg2,REG_R14);
805 }
806
807 //je ...
808 OpBuffer[obp++]=(char)0x0F;
809 OpBuffer[obp++]=(char)0x84;
810 }
811 AddCaseSchedule();
812 obp+=sizeof(long);
813
814 if(basbuf[i]!=',') break;
815 }
816 }
817 if(basbuf[i]==1&&basbuf[i+1]==ESC_CASEELSE){
818 //jmp ...
819 OpBuffer[obp++]=(char)0xE9;
820 AddCaseSchedule();
821 obp+=sizeof(long);
822 }
823 }
824
825 //スタックフレームを1スペースだけ解除
826 pobj_sf->pop(REG_NON);
827
828 //レキシカルスコープをレベルアップ
829 obj_LexScopes.Start( obp, SCOPE_TYPE_SELECT );
830
831 //Select Case内をコンパイル
832 CompileBuffer(ESC_ENDSELECT,0);
833
834 //jmp EndSelect
835 OpBuffer[obp++]=(char)0xE9;
836 AddCaseSchedule();
837 obp+=sizeof(long);
838
839 //最終スケジュール
840 for(i=NowCaseSchedule;i<CaseScheduleNum;i++){
841 *(long *)(OpBuffer+pCaseSchedule[i])=obp-(pCaseSchedule[i]+sizeof(long));
842 }
843 HeapDefaultFree(pCaseSchedule);
844
845 //レキシカルスコープをレベルダウン
846 obj_LexScopes.End();
847
848 pCaseSchedule=temp_pCaseSchedule;
849 CaseScheduleNum=temp_CaseScheduleNum;
850 NowCaseSchedule=temp_NowCaseSchedule;
851}
852void OpcodeCase(char *Parameter){
853 extern DWORD *pCaseSchedule;
854 extern int NowCaseSchedule;
855 int i;
856
857 if(!pCaseSchedule){
858 SetError(30,"Case",cp);
859 return;
860 }
861
862 //jmp EndSelect
863 OpBuffer[obp++]=(char)0xE9;
864 AddCaseSchedule();
865 obp+=sizeof(long);
866
867 i=0;
868 while(1){
869 //Caseスケジュール
870 *(long *)(OpBuffer+pCaseSchedule[NowCaseSchedule])=obp-(pCaseSchedule[NowCaseSchedule]+sizeof(long));
871 NowCaseSchedule++;
872
873 i=JumpOneParameter(Parameter,i);
874 if(Parameter[i]=='\0') break;
875 }
876}
877
878void OpcodeGosub(char *Parameter){
879 extern HANDLE hHeap;
880 extern GOTOLABELSCHEDULE *pGotoLabelSchedule;
881 extern int GotoLabelScheduleNum;
882 int i,LineNum;
883
884 //call _System_GetEip
885 extern SubInfo *pSub_System_GetEip;
886 op_call(pSub_System_GetEip);
887
888 //add rax,offset(Gosubステートメントの最終ポイント)
889 int schedule=obp,schedule2;
890 op_add_RV(REG_RAX,0);
891 schedule2=obp-sizeof(long);
892
893 //※戻り先用のrip
894 //mov qword ptr[rsp+offset],rax ※スタックフレームを利用
895 pobj_sf->push(REG_RAX);
896
897
898 if(Parameter[0]=='*'){
899 i=GetLabelAddress(Parameter+1,0);
900
901 //jmp ...
902 OpBuffer[obp++]=(char)0xE9;
903 if(i==-1){
904 pGotoLabelSchedule=(GOTOLABELSCHEDULE *)HeapReAlloc(hHeap,0,pGotoLabelSchedule,(GotoLabelScheduleNum+1)*sizeof(GOTOLABELSCHEDULE));
905 pGotoLabelSchedule[GotoLabelScheduleNum].pName=(char *)HeapAlloc(hHeap,0,lstrlen(Parameter+1)+1);
906 lstrcpy(pGotoLabelSchedule[GotoLabelScheduleNum].pName,Parameter+1);
907 pGotoLabelSchedule[GotoLabelScheduleNum].pos=obp;
908 pGotoLabelSchedule[GotoLabelScheduleNum].now_cp=cp;
909 GotoLabelScheduleNum++;
910 }
911 *((long *)(OpBuffer+obp))=i-(obp+sizeof(long));
912 obp+=sizeof(long);
913 }
914 else{
915 LineNum=atoi(Parameter);
916 i=GetLabelAddress(0,LineNum);
917
918 //jmp ...
919 OpBuffer[obp++]=(char)0xE9;
920 if(i==-1){
921 pGotoLabelSchedule=(GOTOLABELSCHEDULE *)HeapReAlloc(hHeap,0,pGotoLabelSchedule,(GotoLabelScheduleNum+1)*sizeof(GOTOLABELSCHEDULE));
922 pGotoLabelSchedule[GotoLabelScheduleNum].pName=0;
923 pGotoLabelSchedule[GotoLabelScheduleNum].line=LineNum;
924 pGotoLabelSchedule[GotoLabelScheduleNum].pos=obp;
925 pGotoLabelSchedule[GotoLabelScheduleNum].now_cp=cp;
926 GotoLabelScheduleNum++;
927 }
928 *((long *)(OpBuffer+obp))=i-(obp+sizeof(long));
929 obp+=sizeof(long);
930 }
931
932 *((long *)(OpBuffer+schedule2))=obp-schedule;
933
934 //※スタックフレームを元に戻す
935 pobj_sf->pop(REG_NON);
936
937 SetError(-1,"Gosub ~ Returnステートメントは64ビットコンパイラで利用することはできません。",cp);
938}
939void OpcodeReturn(char *Parameter){
940 extern BOOL bCompilingGlobal;
941 if(bCompilingGlobal){
942 SetError(62,NULL,cp);
943 }
944 else{
945 //戻り値をセット
946 if(Parameter[0]){
947 extern SubInfo *pCompilingSubInfo;
948 char *temp;
949 if(pCompilingSubInfo->name[0]==1&&pCompilingSubInfo->name[1]==ESC_OPERATOR)
950 temp="_System_ReturnValue";
951 else temp=pCompilingSubInfo->name;
952
953 /*
954 TODO: 消す
955 if( pCompilingSubInfo->isReturnRef ){
956 //参照型
957 SetRefVariable( temp, Parameter );
958 }
959 else{
960 //値型*/
961 char temporary[VN_SIZE];
962 sprintf(temporary,"%s=%s",temp,Parameter);
963 OpcodeCalc(temporary);
964 //}
965 }
966
967 //プロシージャを抜け出す(C言語のreturnと同様の処理を行う)
968 OpcodeExitSub();
969 }
970}
971
972void Opcode_Input(const char *Parameter){
973 extern int cp;
974 int i2,i3,i4,i5,type;
975 BOOL bFile;
976 char temporary[VN_SIZE],temp2[VN_SIZE],buffer[VN_SIZE];
977
978 if(Parameter[0]=='#'){
979 bFile=1;
980 for(i2=0,i3=1;;i2++,i3++){
981 buffer[i2]=Parameter[i3];
982 if(Parameter[i3]==','||Parameter[i3]=='\0') break;
983 }
984 buffer[i2+1]=0;
985 i2=i3+1;
986 }
987 else{
988 bFile=0;
989 i2=0;
990 buffer[0]=0;
991
992 //表示用文字列パラメータをセット
993 if(Parameter[0]=='\"'){
994 buffer[0]='\"';
995 for(i2=1;;i2++){
996 if(Parameter[i2]=='\"'){
997 buffer[i2]=0;
998 break;
999 }
1000 buffer[i2]=Parameter[i2];
1001 }
1002 if(Parameter[i2+1]==';') lstrcpy(buffer+i2,"? \"");
1003 else if(Parameter[i2+1]==',') lstrcpy(buffer+i2,"\"");
1004 else SetError(10,"Input",cp);
1005 i2+=2;
1006 }
1007 else if((Parameter[0]=='e'||Parameter[0]=='E')&&
1008 (Parameter[1]=='x'||Parameter[1]=='X')&&
1009 Parameter[2]=='\"'){
1010 memcpy(buffer,Parameter,3);
1011 for(i2=3;;i2++){
1012 if(Parameter[i2]=='\"'){
1013 buffer[i2]=0;
1014 break;
1015 }
1016 buffer[i2]=Parameter[i2];
1017 }
1018 if(Parameter[i2+1]==';') lstrcpy(buffer+i2,"? \"");
1019 else if(Parameter[i2+1]==',') lstrcpy(buffer+i2,"\"");
1020 else SetError(10,"Input",cp);
1021 i2+=2;
1022 }
1023 else{
1024 lstrcpy(buffer,"\"? \"");
1025 i2=0;
1026 }
1027 }
1028
1029 //変数ポインタ、変数のタイプをセット
1030 i4=0;
1031 while(1){
1032 for(i3=0;;i2++,i3++){
1033 if(Parameter[i2]=='('){
1034 i5=GetStringInPare(temporary+i3,Parameter+i2);
1035 i2+=i5-1;
1036 i3+=i5-1;
1037 }
1038 if(Parameter[i2]=='['){
1039 i5=GetStringInBracket(temporary+i3,Parameter+i2);
1040 i2+=i5-1;
1041 i3+=i5-1;
1042 }
1043 if(Parameter[i2]==','){
1044 temporary[i3]=0;
1045 i2++;
1046 break;
1047 }
1048 temporary[i3]=Parameter[i2];
1049 if(Parameter[i2]=='\0') break;
1050 }
1051 if(temporary[0]=='\0'){
1052 SetError(10,"Input",cp);
1053 return;
1054 }
1055
1056 LONG_PTR lpIndex;
1057 type = GetVarType(temporary, &lpIndex, 1);
1058
1059 sprintf(temp2,"_System_InputDataPtr[%d]=VarPtr(%s)",i4,temporary);
1060 OpcodeCalc(temp2);
1061
1062 if(type==DEF_LONG) type=DEF_DWORD;
1063 else if(type==DEF_INTEGER) type=DEF_WORD;
1064 else if(type==DEF_OBJECT){
1065 CClass *pobj_Class=(CClass *)lpIndex;
1066 if(lstrcmp(pobj_Class->name,"String")==0) type=DEF_STRING;
1067 }
1068 sprintf(temp2,"_System_InputDataType[%d]=%d",i4,type);
1069 OpcodeCalc(temp2);
1070
1071 i4++;
1072 if(Parameter[i2]=='\0') break;
1073 }
1074 sprintf(temp2,"_System_InputDataPtr[%d]=0",i4);
1075 OpcodeCalc(temp2);
1076
1077 SubInfo *psi;
1078 if(bFile) psi=GetSubHash("INPUT_FromFile");
1079 else psi=GetSubHash("INPUT_FromPrompt");
1080 if(!psi){
1081 SetError(3,"Input",cp);
1082 return;
1083 }
1084 Opcode_CallProc(buffer,psi,0,"",0);
1085}
1086void Opcode_PrintUsing(const char *Parameter,char *buffer,BOOL bFile){
1087 extern int cp;
1088 int i2,i3,i4,i5;
1089 char temporary[VN_SIZE],temp2[8192];
1090 BOOL bReturnLine;
1091
1092 char parms[8192];
1093 lstrcpy( parms, Parameter );
1094
1095 i2=lstrlen(parms);
1096 if(parms[i2-1]==';'){
1097 bReturnLine=0;
1098 parms[i2-1]=0;
1099 }
1100 else bReturnLine=1;
1101
1102 i3=lstrlen(buffer);
1103 for(i2=0;;i2++,i3++){
1104 if(parms[i2]==';'){
1105 buffer[i3]=0;
1106 break;
1107 }
1108 buffer[i3]=parms[i2];
1109 if(parms[i2]=='\0') break;
1110 }
1111 if(parms[i2]==';') i2++;
1112
1113 if(bReturnLine) lstrcat(buffer,"+Ex\"\\r\\n\"");
1114
1115 //データポインタ、データのタイプをセット
1116 i4=0;
1117 while(1){
1118 for(i3=0;;i2++,i3++){
1119 if(parms[i2]=='\"'){
1120 temporary[i3]=parms[i2];
1121 for(i2++,i3++;;i2++,i3++){
1122 temporary[i3]=parms[i2];
1123 if(parms[i2]=='\"') break;
1124 }
1125 continue;
1126 }
1127 if(parms[i2]=='('){
1128 i5=GetStringInPare(temporary+i3,parms+i2);
1129 i2+=i5-1;
1130 i3+=i5-1;
1131 continue;
1132 }
1133 if(parms[i2]=='['){
1134 i5=GetStringInBracket(temporary+i3,parms+i2);
1135 i2+=i5-1;
1136 i3+=i5-1;
1137 continue;
1138 }
1139 if(parms[i2]==','){
1140 temporary[i3]=0;
1141 i2++;
1142 break;
1143 }
1144 temporary[i3]=parms[i2];
1145 if(parms[i2]=='\0') break;
1146 }
1147 if(temporary[0]=='\0'){
1148 SetError(10,"Print",cp);
1149 return;
1150 }
1151
1152 int iResult;
1153 iResult=IsStrCalculation(temporary);
1154
1155 if(iResult==1){
1156 //文字列
1157 sprintf(temp2,"_System_UsingStrData[%d]=%s",i4,temporary);
1158 OpcodeCalc(temp2);
1159
1160 sprintf(temp2,"_System_UsingDataType[%d]=%d",i4,DEF_STRING);
1161 OpcodeCalc(temp2);
1162 }
1163 else if(iResult==0){
1164 //数値
1165 sprintf(temp2,"_System_UsingDblData[%d]=%s",i4,temporary);
1166 OpcodeCalc(temp2);
1167
1168 sprintf(temp2,"_System_UsingDataType[%d]=%d",i4,DEF_DOUBLE);
1169 OpcodeCalc(temp2);
1170 }
1171 //else if(iResult==-1) エラー
1172
1173 i4++;
1174 if(parms[i2]=='\0') break;
1175 }
1176 sprintf(temp2,"_System_UsingDataType[%d]=-1",i4);
1177 OpcodeCalc(temp2);
1178
1179 SubInfo *psi;
1180 if(bFile) psi=GetSubHash("PRINTUSING_ToFile");
1181 else psi=GetSubHash("PRINTUSING_ToPrompt");
1182 if(!psi){
1183 SetError(3,"Print",cp);
1184 return;
1185 }
1186 Opcode_CallProc(buffer,psi,0,"",0);
1187}
1188void Opcode_Print(const char *Parameter,BOOL bWrite){
1189 int i2,i3,i4,sw;
1190 char temporary[VN_SIZE],buffer[VN_SIZE];
1191 BOOL bFile;
1192
1193 if(Parameter[0]=='#'){
1194 bFile=1;
1195 for(i2=0,i3=1;;i2++,i3++){
1196 buffer[i2]=Parameter[i3];
1197 if(Parameter[i3]==','||Parameter[i3]=='\0') break;
1198 }
1199 buffer[i2+1]=0;
1200 if(Parameter[i3]==',') i3++;
1201 i2=i3;
1202 }
1203 else{
1204 bFile=0;
1205 i2=0;
1206 buffer[0]=0;
1207 }
1208 if(Parameter[i2]==1&&Parameter[i2+1]==ESC_USING){
1209 Opcode_PrintUsing(Parameter+i2+2,buffer,bFile);
1210 return;
1211 }
1212
1213 lstrcat(buffer,"_System_DummyStr+");
1214
1215 sw=1;
1216 while(1){
1217 for(i3=0;;i2++,i3++){
1218 if(Parameter[i2]=='\"'){
1219 temporary[i3]=Parameter[i2];
1220 for(i2++,i3++;;i2++,i3++){
1221 temporary[i3]=Parameter[i2];
1222 if(Parameter[i2]=='\"') break;
1223 }
1224 continue;
1225 }
1226 if(Parameter[i2]=='('){
1227 i4=GetStringInPare(temporary+i3,Parameter+i2);
1228 i2+=i4-1;
1229 i3+=i4-1;
1230 continue;
1231 }
1232 if(Parameter[i2]=='['){
1233 i4=GetStringInBracket(temporary+i3,Parameter+i2);
1234 i2+=i4-1;
1235 i3+=i4-1;
1236 continue;
1237 }
1238 if(Parameter[i2]==','||Parameter[i2]==';'){
1239 temporary[i3]=0;
1240 break;
1241 }
1242 temporary[i3]=Parameter[i2];
1243 if(Parameter[i2]=='\0') break;
1244 }
1245
1246 if(temporary[0]=='\0') lstrcat(buffer,"\"\"");
1247 else{
1248 int iResult;
1249 iResult=IsStrCalculation(temporary);
1250 if(iResult==-1){
1251 //エラー
1252 lstrcat(buffer,"\"\"");
1253 }
1254 else if(iResult){
1255 //文字列
1256 lstrcat(buffer,temporary);
1257 }
1258 else{
1259 //数値
1260 sprintf(buffer+lstrlen(buffer),"Str$(%s)",temporary);
1261 }
1262 }
1263
1264 if(Parameter[i2]==','){
1265 if(bWrite) lstrcat(buffer,"+\",\"+");
1266 else lstrcat(buffer,"+\"\t\"+");
1267 }
1268 else if(Parameter[i2]==';'){
1269 if(Parameter[i2+1]=='\0'){
1270 sw=0;
1271 break;
1272 }
1273 if(bWrite) lstrcat(buffer,"+\",\"+");
1274 else lstrcat(buffer,"+\" \"+");
1275 }
1276 else if(Parameter[i2]=='\0') break;
1277
1278 i2++;
1279 }
1280
1281 if(sw) lstrcat(buffer,"+Ex\"\\r\\n\"");
1282
1283 SubInfo *psi;
1284 if(bFile) psi=GetSubHash("PRINT_ToFile");
1285 else psi=GetSubHash("PRINT_ToPrompt");
1286 if(!psi){
1287 SetError(3,"Print",cp);
1288 return;
1289 }
1290 Opcode_CallProc(buffer,psi,0,"",0);
1291}
1292
1293
1294
1295
1296////////////
1297// ポインタ
1298////////////
1299
1300void OpcodeSetPtrData(char *Parameter,int type){
1301 int i,i2;
1302 char temporary[VN_SIZE];
1303
1304 if(Parameter[0]=='('){
1305 i=JumpStringInPare(Parameter,1);
1306 if(Parameter[i+1]=='\0'){
1307 for(i=0;;i++){
1308 Parameter[i]=Parameter[i+1];
1309 if(Parameter[i]=='\0') break;
1310 }
1311 Parameter[i-1]=0;
1312 }
1313 }
1314
1315 //第1パラメータを取得
1316 i=GetOneParameter(Parameter,0,temporary);
1317 if(!Parameter[i]){
1318 SetError(1,NULL,cp);
1319 return;
1320 }
1321
1322 int reg_ptr=REG_RAX;
1323 i2=NumOpe(&reg_ptr,temporary,0,0,0);
1324 if(!IsWholeNumberType(i2)){
1325 SetError(11,Parameter,cp);
1326 return;
1327 }
1328
1329 //結果を格納しているレジスタをブロッキング
1330 pobj_BlockReg->lock(reg_ptr);
1331
1332 //第2パラメータを取得
1333 i=GetOneParameter(Parameter,i,temporary);
1334 if(Parameter[i]){
1335 SetError(1,NULL,cp);
1336 return;
1337 }
1338
1339 int temp_reg=REG_NON;
1340 i2=NumOpe(&temp_reg,temporary,0,0,0);
1341
1342 //レジスタのブロッキングを解除
1343 pobj_BlockReg->clear();
1344
1345 if(type==DEF_DOUBLE){
1346 ChangeTypeToXmm_Double(i2,REG_XMM0,temp_reg);
1347
1348 //movsd qword ptr[reg_ptr],xmm0
1349 op_movsd_MR(REG_XMM0,reg_ptr,0,MOD_BASE);
1350 }
1351 else if(type==DEF_SINGLE){
1352 ChangeTypeToXmm_Single(i2,REG_XMM0,temp_reg);
1353
1354 //movss dword ptr[reg_ptr],xmm0
1355 op_movss_MR(REG_XMM0,reg_ptr,0,MOD_BASE);
1356 }
1357 else{
1358 ChangeTypeToWhole(i2,type,REG_RCX,temp_reg);
1359
1360 //mov ptr[reg_ptr],rcx
1361 op_mov_MR(GetTypeSize(type,-1),REG_RCX,reg_ptr,0,MOD_BASE);
1362 }
1363}
Note: See TracBrowser for help on using the repository browser.