source: dev/BasicCompiler64/Compile_Statement.cpp@ 36

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

Boolean型に対応。

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