source: dev/BasicCompiler64/Compile_Statement.cpp@ 47

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

列挙子の比較演算が正常に行えないバグを修正。
クラス名と同名のグローバル関数を定義できないバグを修正

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