source: dev/BasicCompiler64/Compile_Statement.cpp@ 75

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

TYPEINFO→Typeへのリファクタリングを実施。64bitはほぼ完了。32bitが全般的に未完成。

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