source: dev/BasicCompiler64/Compile_Statement.cpp@ 50

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

オーバーロード解決用の関数保持リストを "SUBINFO " ではなく、"vector<SUBINFO *>" に変更した。

File size: 30.6 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 std::vector<SUBINFO *> subs;
728 pobj_c->EnumMethod( CALC_EQUAL, subs );
729 if( subs.size() == 0 ){
730 return;
731 }
732
733 PARAMETER_INFO *ppi = (PARAMETER_INFO *)HeapAlloc(hHeap,0,sizeof(PARAMETER_INFO)*3);
734 int iParmNum=0;
735 ppi[iParmNum].bArray=0;
736 ppi[iParmNum].bByVal=0;
737 ppi[iParmNum].name=0;
738 ppi[iParmNum].type=type2;
739 ppi[iParmNum].u.index=lpIndex2;
740 ppi[iParmNum].SubScripts[0]=-1;
741 iParmNum++;
742
743 //オーバーロードを解決
744 SUBINFO *psi;
745 psi=OverloadSolution("==",subs,ppi,iParmNum,NULL);
746 HeapDefaultFree(ppi);
747
748 if(!psi){
749 //エラー
750 return;
751 }
752
753
754 //実体オブジェクト
755 if(reg2!=REG_RDX){
756 //mov rdx,reg2
757 op_mov_RR(REG_RDX,reg2);
758 }
759
760 //mov rcx,qword ptr[rsp+offset] ※スタックフレームから参照
761 pobj_sf->ref(REG_RCX);
762
763 //call operator_proc ※ ==演算子
764 op_call(psi);
765
766 //test rax,rax
767 op_test(REG_RAX,REG_RAX);
768
769 //jne ...
770 OpBuffer[obp++]=(char)0x0F;
771 OpBuffer[obp++]=(char)0x85;
772 }
773 else{
774 if(type1==DEF_DOUBLE){
775 int xmm_reg;
776 if(IsXmmReg(reg2)) xmm_reg=reg2;
777 else xmm_reg=REG_XMM5;
778 ChangeTypeToXmm_Double(type2,xmm_reg,reg2);
779
780 //movsd xmm4,qword ptr[rsp+offset] ※スタックフレームから参照
781 pobj_sf->ref(REG_XMM4,sizeof(double));
782
783 //comiss xmm_reg1,xmm_reg2
784 op_comisd(xmm_reg,REG_XMM4);
785 }
786 else if(type1==DEF_SINGLE){
787 int xmm_reg;
788 if(IsXmmReg(reg2)) xmm_reg=reg2;
789 else xmm_reg=REG_XMM5;
790 ChangeTypeToXmm_Single(type2,xmm_reg,reg2);
791
792 //movss xmm4,dword ptr[rsp+offset] ※スタックフレームから参照
793 pobj_sf->ref(REG_XMM4,sizeof(float));
794
795 //comiss xmm_reg1,xmm_reg2
796 op_comiss(xmm_reg,REG_XMM4);
797 }
798 else{
799 //その他整数型
800
801 i2=NeutralizationType(type1,-1,type2,-1);
802
803 //mov r14,qword ptr[rsp+offset] ※スタックフレームから参照
804 pobj_sf->ref(REG_R14);
805
806 //cmp reg2,r14
807 op_cmp_reg(GetTypeSize(i2,-1),reg2,REG_R14);
808 }
809
810 //je ...
811 OpBuffer[obp++]=(char)0x0F;
812 OpBuffer[obp++]=(char)0x84;
813 }
814 AddCaseSchedule();
815 obp+=sizeof(long);
816
817 if(basbuf[i]!=',') break;
818 }
819 }
820 if(basbuf[i]==1&&basbuf[i+1]==ESC_CASEELSE){
821 //jmp ...
822 OpBuffer[obp++]=(char)0xE9;
823 AddCaseSchedule();
824 obp+=sizeof(long);
825 }
826 }
827
828 //スタックフレームを1スペースだけ解除
829 pobj_sf->pop(REG_NON);
830
831 //レキシカルスコープをレベルアップ
832 obj_LexScopes.Start( obp, SCOPE_TYPE_SELECT );
833
834 //Select Case内をコンパイル
835 CompileBuffer(ESC_ENDSELECT,0);
836
837 //jmp EndSelect
838 OpBuffer[obp++]=(char)0xE9;
839 AddCaseSchedule();
840 obp+=sizeof(long);
841
842 //最終スケジュール
843 for(i=NowCaseSchedule;i<CaseScheduleNum;i++){
844 *(long *)(OpBuffer+pCaseSchedule[i])=obp-(pCaseSchedule[i]+sizeof(long));
845 }
846 HeapDefaultFree(pCaseSchedule);
847
848 //レキシカルスコープをレベルダウン
849 obj_LexScopes.End();
850
851 pCaseSchedule=temp_pCaseSchedule;
852 CaseScheduleNum=temp_CaseScheduleNum;
853 NowCaseSchedule=temp_NowCaseSchedule;
854}
855void OpcodeCase(char *Parameter){
856 extern DWORD *pCaseSchedule;
857 extern int NowCaseSchedule;
858 int i;
859
860 if(!pCaseSchedule){
861 SetError(30,"Case",cp);
862 return;
863 }
864
865 //jmp EndSelect
866 OpBuffer[obp++]=(char)0xE9;
867 AddCaseSchedule();
868 obp+=sizeof(long);
869
870 i=0;
871 while(1){
872 //Caseスケジュール
873 *(long *)(OpBuffer+pCaseSchedule[NowCaseSchedule])=obp-(pCaseSchedule[NowCaseSchedule]+sizeof(long));
874 NowCaseSchedule++;
875
876 i=JumpOneParameter(Parameter,i);
877 if(Parameter[i]=='\0') break;
878 }
879}
880
881void OpcodeGosub(char *Parameter){
882 extern HANDLE hHeap;
883 extern GOTOLABELSCHEDULE *pGotoLabelSchedule;
884 extern int GotoLabelScheduleNum;
885 int i,LineNum;
886
887 //call _System_GetEip
888 extern SUBINFO *pSub_System_GetEip;
889 op_call(pSub_System_GetEip);
890
891 //add rax,offset(Gosubステートメントの最終ポイント)
892 int schedule=obp,schedule2;
893 op_add64_value(REG_RAX,0);
894 schedule2=obp-sizeof(long);
895
896 //※戻り先用のrip
897 //mov qword ptr[rsp+offset],rax ※スタックフレームを利用
898 pobj_sf->push(REG_RAX);
899
900
901 if(Parameter[0]=='*'){
902 i=GetLabelAddress(Parameter+1,0);
903
904 //jmp ...
905 OpBuffer[obp++]=(char)0xE9;
906 if(i==-1){
907 pGotoLabelSchedule=(GOTOLABELSCHEDULE *)HeapReAlloc(hHeap,0,pGotoLabelSchedule,(GotoLabelScheduleNum+1)*sizeof(GOTOLABELSCHEDULE));
908 pGotoLabelSchedule[GotoLabelScheduleNum].pName=(char *)HeapAlloc(hHeap,0,lstrlen(Parameter+1)+1);
909 lstrcpy(pGotoLabelSchedule[GotoLabelScheduleNum].pName,Parameter+1);
910 pGotoLabelSchedule[GotoLabelScheduleNum].pos=obp;
911 pGotoLabelSchedule[GotoLabelScheduleNum].now_cp=cp;
912 GotoLabelScheduleNum++;
913 }
914 *((long *)(OpBuffer+obp))=i-(obp+sizeof(long));
915 obp+=sizeof(long);
916 }
917 else{
918 LineNum=atoi(Parameter);
919 i=GetLabelAddress(0,LineNum);
920
921 //jmp ...
922 OpBuffer[obp++]=(char)0xE9;
923 if(i==-1){
924 pGotoLabelSchedule=(GOTOLABELSCHEDULE *)HeapReAlloc(hHeap,0,pGotoLabelSchedule,(GotoLabelScheduleNum+1)*sizeof(GOTOLABELSCHEDULE));
925 pGotoLabelSchedule[GotoLabelScheduleNum].pName=0;
926 pGotoLabelSchedule[GotoLabelScheduleNum].line=LineNum;
927 pGotoLabelSchedule[GotoLabelScheduleNum].pos=obp;
928 pGotoLabelSchedule[GotoLabelScheduleNum].now_cp=cp;
929 GotoLabelScheduleNum++;
930 }
931 *((long *)(OpBuffer+obp))=i-(obp+sizeof(long));
932 obp+=sizeof(long);
933 }
934
935 *((long *)(OpBuffer+schedule2))=obp-schedule;
936
937 //※スタックフレームを元に戻す
938 pobj_sf->pop(REG_NON);
939
940 SetError(-1,"Gosub ~ Returnステートメントは64ビットコンパイラで利用することはできません。",cp);
941}
942void OpcodeReturn(char *Parameter){
943 extern BOOL bCompilingGlobal;
944 if(bCompilingGlobal){
945 SetError(62,NULL,cp);
946 }
947 else{
948 //戻り値をセット
949 if(Parameter[0]){
950 extern SUBINFO *pCompilingSubInfo;
951 char *temp;
952 if(pCompilingSubInfo->name[0]==1&&pCompilingSubInfo->name[1]==ESC_OPERATOR)
953 temp="_System_ReturnValue";
954 else temp=pCompilingSubInfo->name;
955
956 if( pCompilingSubInfo->isReturnRef ){
957 //参照型
958 SetRefVariable( temp, Parameter );
959 }
960 else{
961 //値型
962 char temporary[VN_SIZE];
963 sprintf(temporary,"%s=%s",temp,Parameter);
964 OpcodeCalc(temporary);
965 }
966 }
967
968 //プロシージャを抜け出す(C言語のreturnと同様の処理を行う)
969 OpcodeExitSub();
970 }
971}
972
973void Opcode_Input(char *Parameter){
974 extern int cp;
975 int i2,i3,i4,i5,type;
976 BOOL bFile;
977 char temporary[VN_SIZE],temp2[VN_SIZE],buffer[VN_SIZE];
978
979 KillStringSpaces(Parameter);
980
981 if(Parameter[0]=='#'){
982 bFile=1;
983 for(i2=0,i3=1;;i2++,i3++){
984 buffer[i2]=Parameter[i3];
985 if(Parameter[i3]==','||Parameter[i3]=='\0') break;
986 }
987 buffer[i2+1]=0;
988 i2=i3+1;
989 }
990 else{
991 bFile=0;
992 i2=0;
993 buffer[0]=0;
994
995 //表示用文字列パラメータをセット
996 if(Parameter[0]=='\"'){
997 buffer[0]='\"';
998 for(i2=1;;i2++){
999 if(Parameter[i2]=='\"'){
1000 buffer[i2]=0;
1001 break;
1002 }
1003 buffer[i2]=Parameter[i2];
1004 }
1005 if(Parameter[i2+1]==';') lstrcpy(buffer+i2,"? \"");
1006 else if(Parameter[i2+1]==',') lstrcpy(buffer+i2,"\"");
1007 else SetError(10,"Input",cp);
1008 i2+=2;
1009 }
1010 else if((Parameter[0]=='e'||Parameter[0]=='E')&&
1011 (Parameter[1]=='x'||Parameter[1]=='X')&&
1012 Parameter[2]=='\"'){
1013 memcpy(buffer,Parameter,3);
1014 for(i2=3;;i2++){
1015 if(Parameter[i2]=='\"'){
1016 buffer[i2]=0;
1017 break;
1018 }
1019 buffer[i2]=Parameter[i2];
1020 }
1021 if(Parameter[i2+1]==';') lstrcpy(buffer+i2,"? \"");
1022 else if(Parameter[i2+1]==',') lstrcpy(buffer+i2,"\"");
1023 else SetError(10,"Input",cp);
1024 i2+=2;
1025 }
1026 else{
1027 lstrcpy(buffer,"\"? \"");
1028 i2=0;
1029 }
1030 }
1031
1032 //変数ポインタ、変数のタイプをセット
1033 i4=0;
1034 while(1){
1035 for(i3=0;;i2++,i3++){
1036 if(Parameter[i2]=='('){
1037 i5=GetStringInPare(temporary+i3,Parameter+i2);
1038 i2+=i5-1;
1039 i3+=i5-1;
1040 }
1041 if(Parameter[i2]=='['){
1042 i5=GetStringInBracket(temporary+i3,Parameter+i2);
1043 i2+=i5-1;
1044 i3+=i5-1;
1045 }
1046 if(Parameter[i2]==','){
1047 temporary[i3]=0;
1048 i2++;
1049 break;
1050 }
1051 temporary[i3]=Parameter[i2];
1052 if(Parameter[i2]=='\0') break;
1053 }
1054 if(temporary[0]=='\0'){
1055 SetError(10,"Input",cp);
1056 return;
1057 }
1058
1059 LONG_PTR lpIndex;
1060 type = GetVarType(temporary, &lpIndex, 1);
1061
1062 sprintf(temp2,"_System_InputDataPtr[%d]=VarPtr(%s)",i4,temporary);
1063 OpcodeCalc(temp2);
1064
1065 if(type==DEF_LONG) type=DEF_DWORD;
1066 else if(type==DEF_INTEGER) type=DEF_WORD;
1067 else if(type==DEF_OBJECT){
1068 CClass *pobj_Class=(CClass *)lpIndex;
1069 if(lstrcmp(pobj_Class->name,"String")==0) type=DEF_STRING;
1070 }
1071 sprintf(temp2,"_System_InputDataType[%d]=%d",i4,type);
1072 OpcodeCalc(temp2);
1073
1074 i4++;
1075 if(Parameter[i2]=='\0') break;
1076 }
1077 sprintf(temp2,"_System_InputDataPtr[%d]=0",i4);
1078 OpcodeCalc(temp2);
1079
1080 SUBINFO *psi;
1081 if(bFile) psi=GetSubHash("INPUT_FromFile");
1082 else psi=GetSubHash("INPUT_FromPrompt");
1083 if(!psi){
1084 SetError(3,"Input",cp);
1085 return;
1086 }
1087 Opcode_CallProc(buffer,psi,0,"",0);
1088}
1089void Opcode_PrintUsing(char *Parameter,char *buffer,BOOL bFile){
1090 extern int cp;
1091 int i2,i3,i4,i5;
1092 char temporary[VN_SIZE],temp2[8192];
1093 BOOL bReturnLine;
1094
1095 i2=lstrlen(Parameter);
1096 if(Parameter[i2-1]==';'){
1097 bReturnLine=0;
1098 Parameter[i2-1]=0;
1099 }
1100 else bReturnLine=1;
1101
1102 i3=lstrlen(buffer);
1103 for(i2=0;;i2++,i3++){
1104 if(Parameter[i2]==';'){
1105 buffer[i3]=0;
1106 break;
1107 }
1108 buffer[i3]=Parameter[i2];
1109 if(Parameter[i2]=='\0') break;
1110 }
1111 if(Parameter[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(Parameter[i2]=='\"'){
1120 temporary[i3]=Parameter[i2];
1121 for(i2++,i3++;;i2++,i3++){
1122 temporary[i3]=Parameter[i2];
1123 if(Parameter[i2]=='\"') break;
1124 }
1125 continue;
1126 }
1127 if(Parameter[i2]=='('){
1128 i5=GetStringInPare(temporary+i3,Parameter+i2);
1129 i2+=i5-1;
1130 i3+=i5-1;
1131 continue;
1132 }
1133 if(Parameter[i2]=='['){
1134 i5=GetStringInBracket(temporary+i3,Parameter+i2);
1135 i2+=i5-1;
1136 i3+=i5-1;
1137 continue;
1138 }
1139 if(Parameter[i2]==','){
1140 temporary[i3]=0;
1141 i2++;
1142 break;
1143 }
1144 temporary[i3]=Parameter[i2];
1145 if(Parameter[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(Parameter[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(char *Parameter,BOOL bWrite){
1189 int i2,i3,i4,sw;
1190 char temporary[VN_SIZE],buffer[VN_SIZE];
1191 BOOL bFile;
1192
1193 KillStringSpaces(Parameter);
1194
1195 if(Parameter[0]=='#'){
1196 bFile=1;
1197 for(i2=0,i3=1;;i2++,i3++){
1198 buffer[i2]=Parameter[i3];
1199 if(Parameter[i3]==','||Parameter[i3]=='\0') break;
1200 }
1201 buffer[i2+1]=0;
1202 if(Parameter[i3]==',') i3++;
1203 i2=i3;
1204 }
1205 else{
1206 bFile=0;
1207 i2=0;
1208 buffer[0]=0;
1209 }
1210 if(Parameter[i2]==1&&Parameter[i2+1]==ESC_USING){
1211 Opcode_PrintUsing(Parameter+i2+2,buffer,bFile);
1212 return;
1213 }
1214
1215 lstrcat(buffer,"_System_DummyStr+");
1216
1217 sw=1;
1218 while(1){
1219 for(i3=0;;i2++,i3++){
1220 if(Parameter[i2]=='\"'){
1221 temporary[i3]=Parameter[i2];
1222 for(i2++,i3++;;i2++,i3++){
1223 temporary[i3]=Parameter[i2];
1224 if(Parameter[i2]=='\"') break;
1225 }
1226 continue;
1227 }
1228 if(Parameter[i2]=='('){
1229 i4=GetStringInPare(temporary+i3,Parameter+i2);
1230 i2+=i4-1;
1231 i3+=i4-1;
1232 continue;
1233 }
1234 if(Parameter[i2]=='['){
1235 i4=GetStringInBracket(temporary+i3,Parameter+i2);
1236 i2+=i4-1;
1237 i3+=i4-1;
1238 continue;
1239 }
1240 if(Parameter[i2]==','||Parameter[i2]==';'){
1241 temporary[i3]=0;
1242 break;
1243 }
1244 temporary[i3]=Parameter[i2];
1245 if(Parameter[i2]=='\0') break;
1246 }
1247
1248 if(temporary[0]=='\0') lstrcat(buffer,"\"\"");
1249 else{
1250 int iResult;
1251 iResult=IsStrCalculation(temporary);
1252 if(iResult==-1){
1253 //エラー
1254 lstrcat(buffer,"\"\"");
1255 }
1256 else if(iResult){
1257 //文字列
1258 lstrcat(buffer,temporary);
1259 }
1260 else{
1261 //数値
1262 sprintf(buffer+lstrlen(buffer),"Str$(%s)",temporary);
1263 }
1264 }
1265
1266 if(Parameter[i2]==','){
1267 if(bWrite) lstrcat(buffer,"+\",\"+");
1268 else lstrcat(buffer,"+\"\t\"+");
1269 }
1270 else if(Parameter[i2]==';'){
1271 if(Parameter[i2+1]=='\0'){
1272 sw=0;
1273 break;
1274 }
1275 if(bWrite) lstrcat(buffer,"+\",\"+");
1276 else lstrcat(buffer,"+\" \"+");
1277 }
1278 else if(Parameter[i2]=='\0') break;
1279
1280 i2++;
1281 }
1282
1283 if(sw) lstrcat(buffer,"+Ex\"\\r\\n\"");
1284
1285 SUBINFO *psi;
1286 if(bFile) psi=GetSubHash("PRINT_ToFile");
1287 else psi=GetSubHash("PRINT_ToPrompt");
1288 if(!psi){
1289 SetError(3,"Print",cp);
1290 return;
1291 }
1292 Opcode_CallProc(buffer,psi,0,"",0);
1293}
1294
1295
1296
1297
1298////////////
1299// ポインタ
1300////////////
1301
1302void OpcodeSetPtrData(char *Parameter,int type){
1303 int i,i2;
1304 char temporary[VN_SIZE];
1305
1306 if(Parameter[0]=='('){
1307 i=JumpStringInPare(Parameter,1);
1308 if(Parameter[i+1]=='\0'){
1309 for(i=0;;i++){
1310 Parameter[i]=Parameter[i+1];
1311 if(Parameter[i]=='\0') break;
1312 }
1313 Parameter[i-1]=0;
1314 }
1315 }
1316
1317 //第1パラメータを取得
1318 i=GetOneParameter(Parameter,0,temporary);
1319 if(!Parameter[i]){
1320 SetError(1,NULL,cp);
1321 return;
1322 }
1323
1324 int reg_ptr=REG_RAX;
1325 i2=NumOpe(&reg_ptr,temporary,0,0,0);
1326 if(!IsWholeNumberType(i2)){
1327 SetError(11,Parameter,cp);
1328 return;
1329 }
1330
1331 //結果を格納しているレジスタをブロッキング
1332 pobj_BlockReg->lock(reg_ptr);
1333
1334 //第2パラメータを取得
1335 i=GetOneParameter(Parameter,i,temporary);
1336 if(Parameter[i]){
1337 SetError(1,NULL,cp);
1338 return;
1339 }
1340
1341 int temp_reg=REG_NON;
1342 i2=NumOpe(&temp_reg,temporary,0,0,0);
1343
1344 //レジスタのブロッキングを解除
1345 pobj_BlockReg->clear();
1346
1347 if(type==DEF_DOUBLE){
1348 ChangeTypeToXmm_Double(i2,REG_XMM0,temp_reg);
1349
1350 //movsd qword ptr[reg_ptr],xmm0
1351 op_movsd_MR(REG_XMM0,reg_ptr,0,MOD_BASE);
1352 }
1353 else if(type==DEF_SINGLE){
1354 ChangeTypeToXmm_Single(i2,REG_XMM0,temp_reg);
1355
1356 //movss dword ptr[reg_ptr],xmm0
1357 op_movss_MR(REG_XMM0,reg_ptr,0,MOD_BASE);
1358 }
1359 else{
1360 ChangeTypeToWhole(i2,type,REG_RCX,temp_reg);
1361
1362 //mov ptr[reg_ptr],rcx
1363 op_mov_MR(GetTypeSize(type,-1),REG_RCX,reg_ptr,0,MOD_BASE);
1364 }
1365}
Note: See TracBrowser for help on using the repository browser.