source: dev/BasicCompiler64/Compile_Statement.cpp@ 35

Last change on this file since 35 was 34, checked in by dai_9181, 18 years ago

スコープ処理を統一した。関数の途中でReturnしても、スコープにあるローカルオブジェクトを正確に破棄できるようにした。

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