source: dev/BasicCompiler64/Compile_Statement.cpp@ 40

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

ByRef修飾子を関数戻り値とDimステートメントで指定可能にした。

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
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 if( pCompilingSubInfo->isReturnRef ){
962 //参照型
963 SetRefVariable( temp, Parameter );
964 }
965 else{
966 //値型
967 char temporary[VN_SIZE];
968 sprintf(temporary,"%s=%s",temp,Parameter);
969 OpcodeCalc(temporary);
970 }
971 }
972
973 //プロシージャを抜け出す(C言語のreturnと同様の処理を行う)
974 OpcodeExitSub();
975 }
976}
977
978void Opcode_Input(char *Parameter){
979 extern int cp;
980 int i2,i3,i4,i5,type;
981 BOOL bFile;
982 char temporary[VN_SIZE],temp2[VN_SIZE],buffer[VN_SIZE];
983
984 KillStringSpaces(Parameter);
985
986 if(Parameter[0]=='#'){
987 bFile=1;
988 for(i2=0,i3=1;;i2++,i3++){
989 buffer[i2]=Parameter[i3];
990 if(Parameter[i3]==','||Parameter[i3]=='\0') break;
991 }
992 buffer[i2+1]=0;
993 i2=i3+1;
994 }
995 else{
996 bFile=0;
997 i2=0;
998 buffer[0]=0;
999
1000 //表示用文字列パラメータをセット
1001 if(Parameter[0]=='\"'){
1002 buffer[0]='\"';
1003 for(i2=1;;i2++){
1004 if(Parameter[i2]=='\"'){
1005 buffer[i2]=0;
1006 break;
1007 }
1008 buffer[i2]=Parameter[i2];
1009 }
1010 if(Parameter[i2+1]==';') lstrcpy(buffer+i2,"? \"");
1011 else if(Parameter[i2+1]==',') lstrcpy(buffer+i2,"\"");
1012 else SetError(10,"Input",cp);
1013 i2+=2;
1014 }
1015 else if((Parameter[0]=='e'||Parameter[0]=='E')&&
1016 (Parameter[1]=='x'||Parameter[1]=='X')&&
1017 Parameter[2]=='\"'){
1018 memcpy(buffer,Parameter,3);
1019 for(i2=3;;i2++){
1020 if(Parameter[i2]=='\"'){
1021 buffer[i2]=0;
1022 break;
1023 }
1024 buffer[i2]=Parameter[i2];
1025 }
1026 if(Parameter[i2+1]==';') lstrcpy(buffer+i2,"? \"");
1027 else if(Parameter[i2+1]==',') lstrcpy(buffer+i2,"\"");
1028 else SetError(10,"Input",cp);
1029 i2+=2;
1030 }
1031 else{
1032 lstrcpy(buffer,"\"? \"");
1033 i2=0;
1034 }
1035 }
1036
1037 //変数ポインタ、変数のタイプをセット
1038 i4=0;
1039 while(1){
1040 for(i3=0;;i2++,i3++){
1041 if(Parameter[i2]=='('){
1042 i5=GetStringInPare(temporary+i3,Parameter+i2);
1043 i2+=i5-1;
1044 i3+=i5-1;
1045 }
1046 if(Parameter[i2]=='['){
1047 i5=GetStringInBracket(temporary+i3,Parameter+i2);
1048 i2+=i5-1;
1049 i3+=i5-1;
1050 }
1051 if(Parameter[i2]==','){
1052 temporary[i3]=0;
1053 i2++;
1054 break;
1055 }
1056 temporary[i3]=Parameter[i2];
1057 if(Parameter[i2]=='\0') break;
1058 }
1059 if(temporary[0]=='\0'){
1060 SetError(10,"Input",cp);
1061 return;
1062 }
1063
1064 LONG_PTR lpIndex;
1065 type = GetVarType(temporary, &lpIndex, 1);
1066
1067 sprintf(temp2,"_System_InputDataPtr[%d]=VarPtr(%s)",i4,temporary);
1068 OpcodeCalc(temp2);
1069
1070 if(type==DEF_LONG) type=DEF_DWORD;
1071 else if(type==DEF_INTEGER) type=DEF_WORD;
1072 else if(type==DEF_OBJECT){
1073 CClass *pobj_Class=(CClass *)lpIndex;
1074 if(lstrcmp(pobj_Class->name,"String")==0) type=DEF_STRING;
1075 }
1076 sprintf(temp2,"_System_InputDataType[%d]=%d",i4,type);
1077 OpcodeCalc(temp2);
1078
1079 i4++;
1080 if(Parameter[i2]=='\0') break;
1081 }
1082 sprintf(temp2,"_System_InputDataPtr[%d]=0",i4);
1083 OpcodeCalc(temp2);
1084
1085 SUBINFO *psi;
1086 if(bFile) psi=GetSubHash("INPUT_FromFile");
1087 else psi=GetSubHash("INPUT_FromPrompt");
1088 if(!psi){
1089 SetError(3,"Input",cp);
1090 return;
1091 }
1092 Opcode_CallProc(buffer,psi,0,"",0);
1093}
1094void Opcode_PrintUsing(char *Parameter,char *buffer,BOOL bFile){
1095 extern int cp;
1096 int i2,i3,i4,i5;
1097 char temporary[VN_SIZE],temp2[8192];
1098 BOOL bReturnLine;
1099
1100 i2=lstrlen(Parameter);
1101 if(Parameter[i2-1]==';'){
1102 bReturnLine=0;
1103 Parameter[i2-1]=0;
1104 }
1105 else bReturnLine=1;
1106
1107 i3=lstrlen(buffer);
1108 for(i2=0;;i2++,i3++){
1109 if(Parameter[i2]==';'){
1110 buffer[i3]=0;
1111 break;
1112 }
1113 buffer[i3]=Parameter[i2];
1114 if(Parameter[i2]=='\0') break;
1115 }
1116 if(Parameter[i2]==';') i2++;
1117
1118 if(bReturnLine) lstrcat(buffer,"+Ex\"\\r\\n\"");
1119
1120 //データポインタ、データのタイプをセット
1121 i4=0;
1122 while(1){
1123 for(i3=0;;i2++,i3++){
1124 if(Parameter[i2]=='\"'){
1125 temporary[i3]=Parameter[i2];
1126 for(i2++,i3++;;i2++,i3++){
1127 temporary[i3]=Parameter[i2];
1128 if(Parameter[i2]=='\"') break;
1129 }
1130 continue;
1131 }
1132 if(Parameter[i2]=='('){
1133 i5=GetStringInPare(temporary+i3,Parameter+i2);
1134 i2+=i5-1;
1135 i3+=i5-1;
1136 continue;
1137 }
1138 if(Parameter[i2]=='['){
1139 i5=GetStringInBracket(temporary+i3,Parameter+i2);
1140 i2+=i5-1;
1141 i3+=i5-1;
1142 continue;
1143 }
1144 if(Parameter[i2]==','){
1145 temporary[i3]=0;
1146 i2++;
1147 break;
1148 }
1149 temporary[i3]=Parameter[i2];
1150 if(Parameter[i2]=='\0') break;
1151 }
1152 if(temporary[0]=='\0'){
1153 SetError(10,"Print",cp);
1154 return;
1155 }
1156
1157 int iResult;
1158 iResult=IsStrCalculation(temporary);
1159
1160 if(iResult==1){
1161 //文字列
1162 sprintf(temp2,"_System_UsingStrData[%d]=%s",i4,temporary);
1163 OpcodeCalc(temp2);
1164
1165 sprintf(temp2,"_System_UsingDataType[%d]=%d",i4,DEF_STRING);
1166 OpcodeCalc(temp2);
1167 }
1168 else if(iResult==0){
1169 //数値
1170 sprintf(temp2,"_System_UsingDblData[%d]=%s",i4,temporary);
1171 OpcodeCalc(temp2);
1172
1173 sprintf(temp2,"_System_UsingDataType[%d]=%d",i4,DEF_DOUBLE);
1174 OpcodeCalc(temp2);
1175 }
1176 //else if(iResult==-1) エラー
1177
1178 i4++;
1179 if(Parameter[i2]=='\0') break;
1180 }
1181 sprintf(temp2,"_System_UsingDataType[%d]=-1",i4);
1182 OpcodeCalc(temp2);
1183
1184 SUBINFO *psi;
1185 if(bFile) psi=GetSubHash("PRINTUSING_ToFile");
1186 else psi=GetSubHash("PRINTUSING_ToPrompt");
1187 if(!psi){
1188 SetError(3,"Print",cp);
1189 return;
1190 }
1191 Opcode_CallProc(buffer,psi,0,"",0);
1192}
1193void Opcode_Print(char *Parameter,BOOL bWrite){
1194 int i2,i3,i4,sw;
1195 char temporary[VN_SIZE],buffer[VN_SIZE];
1196 BOOL bFile;
1197
1198 KillStringSpaces(Parameter);
1199
1200 if(Parameter[0]=='#'){
1201 bFile=1;
1202 for(i2=0,i3=1;;i2++,i3++){
1203 buffer[i2]=Parameter[i3];
1204 if(Parameter[i3]==','||Parameter[i3]=='\0') break;
1205 }
1206 buffer[i2+1]=0;
1207 if(Parameter[i3]==',') i3++;
1208 i2=i3;
1209 }
1210 else{
1211 bFile=0;
1212 i2=0;
1213 buffer[0]=0;
1214 }
1215 if(Parameter[i2]==1&&Parameter[i2+1]==ESC_USING){
1216 Opcode_PrintUsing(Parameter+i2+2,buffer,bFile);
1217 return;
1218 }
1219
1220 lstrcat(buffer,"_System_DummyStr+");
1221
1222 sw=1;
1223 while(1){
1224 for(i3=0;;i2++,i3++){
1225 if(Parameter[i2]=='\"'){
1226 temporary[i3]=Parameter[i2];
1227 for(i2++,i3++;;i2++,i3++){
1228 temporary[i3]=Parameter[i2];
1229 if(Parameter[i2]=='\"') break;
1230 }
1231 continue;
1232 }
1233 if(Parameter[i2]=='('){
1234 i4=GetStringInPare(temporary+i3,Parameter+i2);
1235 i2+=i4-1;
1236 i3+=i4-1;
1237 continue;
1238 }
1239 if(Parameter[i2]=='['){
1240 i4=GetStringInBracket(temporary+i3,Parameter+i2);
1241 i2+=i4-1;
1242 i3+=i4-1;
1243 continue;
1244 }
1245 if(Parameter[i2]==','||Parameter[i2]==';'){
1246 temporary[i3]=0;
1247 break;
1248 }
1249 temporary[i3]=Parameter[i2];
1250 if(Parameter[i2]=='\0') break;
1251 }
1252
1253 if(temporary[0]=='\0') lstrcat(buffer,"\"\"");
1254 else{
1255 int iResult;
1256 iResult=IsStrCalculation(temporary);
1257 if(iResult==-1){
1258 //エラー
1259 lstrcat(buffer,"\"\"");
1260 }
1261 else if(iResult){
1262 //文字列
1263 lstrcat(buffer,temporary);
1264 }
1265 else{
1266 //数値
1267 sprintf(buffer+lstrlen(buffer),"Str$(%s)",temporary);
1268 }
1269 }
1270
1271 if(Parameter[i2]==','){
1272 if(bWrite) lstrcat(buffer,"+\",\"+");
1273 else lstrcat(buffer,"+\"\t\"+");
1274 }
1275 else if(Parameter[i2]==';'){
1276 if(Parameter[i2+1]=='\0'){
1277 sw=0;
1278 break;
1279 }
1280 if(bWrite) lstrcat(buffer,"+\",\"+");
1281 else lstrcat(buffer,"+\" \"+");
1282 }
1283 else if(Parameter[i2]=='\0') break;
1284
1285 i2++;
1286 }
1287
1288 if(sw) lstrcat(buffer,"+Ex\"\\r\\n\"");
1289
1290 SUBINFO *psi;
1291 if(bFile) psi=GetSubHash("PRINT_ToFile");
1292 else psi=GetSubHash("PRINT_ToPrompt");
1293 if(!psi){
1294 SetError(3,"Print",cp);
1295 return;
1296 }
1297 Opcode_CallProc(buffer,psi,0,"",0);
1298}
1299
1300
1301
1302
1303////////////
1304// ポインタ
1305////////////
1306
1307void OpcodeSetPtrData(char *Parameter,int type){
1308 int i,i2;
1309 char temporary[VN_SIZE];
1310
1311 if(Parameter[0]=='('){
1312 i=JumpStringInPare(Parameter,1);
1313 if(Parameter[i+1]=='\0'){
1314 for(i=0;;i++){
1315 Parameter[i]=Parameter[i+1];
1316 if(Parameter[i]=='\0') break;
1317 }
1318 Parameter[i-1]=0;
1319 }
1320 }
1321
1322 //第1パラメータを取得
1323 i=GetOneParameter(Parameter,0,temporary);
1324 if(!Parameter[i]){
1325 SetError(1,NULL,cp);
1326 return;
1327 }
1328
1329 int reg_ptr=REG_RAX;
1330 i2=NumOpe(&reg_ptr,temporary,0,0,0);
1331 if(!IsWholeNumberType(i2)){
1332 SetError(11,Parameter,cp);
1333 return;
1334 }
1335
1336 //結果を格納しているレジスタをブロッキング
1337 pobj_BlockReg->lock(reg_ptr);
1338
1339 //第2パラメータを取得
1340 i=GetOneParameter(Parameter,i,temporary);
1341 if(Parameter[i]){
1342 SetError(1,NULL,cp);
1343 return;
1344 }
1345
1346 int temp_reg=REG_NON;
1347 i2=NumOpe(&temp_reg,temporary,0,0,0);
1348
1349 //レジスタのブロッキングを解除
1350 pobj_BlockReg->clear();
1351
1352 if(type==DEF_DOUBLE){
1353 ChangeTypeToXmm_Double(i2,REG_XMM0,temp_reg);
1354
1355 //movsd qword ptr[reg_ptr],xmm0
1356 op_movsd_MR(REG_XMM0,reg_ptr,0,MOD_BASE);
1357 }
1358 else if(type==DEF_SINGLE){
1359 ChangeTypeToXmm_Single(i2,REG_XMM0,temp_reg);
1360
1361 //movss dword ptr[reg_ptr],xmm0
1362 op_movss_MR(REG_XMM0,reg_ptr,0,MOD_BASE);
1363 }
1364 else{
1365 ChangeTypeToWhole(i2,type,REG_RCX,temp_reg);
1366
1367 //mov ptr[reg_ptr],rcx
1368 op_mov_MR(GetTypeSize(type,-1),REG_RCX,reg_ptr,0,MOD_BASE);
1369 }
1370}
Note: See TracBrowser for help on using the repository browser.