source: dev/BasicCompiler32/Compile_Statement.cpp@ 75

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

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

File size: 39.2 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
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_DOUBLE||i2==DEF_SINGLE){
103 //fstp st(0)
104 OpBuffer[obp++]=(char)0xDD;
105 OpBuffer[obp++]=(char)0xD8;
106 }
107 if(i2==DEF_STRUCT){
108 //mov ebx,eax
109 op_mov_RR(REG_EBX,REG_EAX);
110
111 FreeTempObject(REG_EBX,(CClass *)lp);
112 }
113 return;
114 }
115
116
117 //////////////////////////
118 // その他は代入演算を行う
119 //////////////////////////
120 OpcodeCalc(Command);
121}
122
123void OpcodeIf(char *Parameter){
124 int i,i2,i3,i4,type;
125
126 for(i=0;;i++){
127 if(Parameter[i]=='\0'){
128 SetError(21,NULL,cp);
129 return;
130 }
131 if(Parameter[i]==1&&Parameter[i+1]==ESC_THEN){
132 Parameter[i]=0;
133 break;
134 }
135 }
136
137 type=NumOpe(Parameter,0,0,0);
138
139 if(type==-1){
140 //NumOpe内でエラー
141 i3=-1; //ダミー
142 }
143 else if(type==DEF_DOUBLE){
144 //fld qword ptr[esp]
145 op_fld_ptr_esp(DEF_DOUBLE);
146
147 //push 0
148 op_push_V(0);
149
150 //fild dword ptr[esp]
151 op_fld_ptr_esp(DEF_LONG);
152
153 //add esp,sizeof(double)+sizeof(long)
154 op_add_esp(sizeof(double)+sizeof(long));
155
156 //fcompp
157 OpBuffer[obp++]=(char)0xDE;
158 OpBuffer[obp++]=(char)0xD9;
159
160 //fnstsw ax
161 OpBuffer[obp++]=(char)0xDF;
162 OpBuffer[obp++]=(char)0xE0;
163
164 //test ah,40
165 OpBuffer[obp++]=(char)0xF6;
166 OpBuffer[obp++]=(char)0xC4;
167 OpBuffer[obp++]=(char)0x40;
168
169 //jne (endif、または else まで)
170 OpBuffer[obp++]=(char)0x0F;
171 OpBuffer[obp++]=(char)0x85;
172 obp+=sizeof(long);
173
174 //jneの番地
175 i3=obp;
176 }
177 else if(type==DEF_SINGLE){
178 //fld dword ptr[esp]
179 op_fld_ptr_esp(DEF_SINGLE);
180
181 //push 0
182 op_push_V(0);
183
184 //fild dword ptr[esp]
185 op_fld_ptr_esp(DEF_LONG);
186
187 //add esp,sizeof(float)+sizeof(long)
188 op_add_esp(sizeof(float)+sizeof(long));
189
190 //fcompp
191 OpBuffer[obp++]=(char)0xDE;
192 OpBuffer[obp++]=(char)0xD9;
193
194 //fnstsw ax
195 OpBuffer[obp++]=(char)0xDF;
196 OpBuffer[obp++]=(char)0xE0;
197
198 //test ah,40
199 OpBuffer[obp++]=(char)0xF6;
200 OpBuffer[obp++]=(char)0xC4;
201 OpBuffer[obp++]=(char)0x40;
202
203 //jne (endif、または else まで)
204 OpBuffer[obp++]=(char)0x0F;
205 OpBuffer[obp++]=(char)0x85;
206 obp+=sizeof(long);
207
208 //jneの番地
209 i3=obp;
210 }
211 else if(type==DEF_INT64||type==DEF_QWORD){
212 //64ビット型
213
214 //pop eax
215 op_pop(REG_EAX);
216
217 //pop ebx
218 op_pop(REG_EBX);
219
220 //cmp eax,0
221 OpBuffer[obp++]=(char)0x83;
222 OpBuffer[obp++]=(char)0xF8;
223 OpBuffer[obp++]=(char)0x00;
224
225 //jne
226 OpBuffer[obp++]=(char)0x0F;
227 OpBuffer[obp++]=(char)0x85;
228 obp+=sizeof(long);
229 i3=obp;
230
231
232 //cmp ebx,0
233 OpBuffer[obp++]=(char)0x83;
234 OpBuffer[obp++]=(char)0xFB;
235 OpBuffer[obp++]=(char)0x00;
236
237 //jne
238 OpBuffer[obp++]=(char)0x0F;
239 OpBuffer[obp++]=(char)0x85;
240 obp+=sizeof(long);
241 i4=obp;
242
243
244
245 //jmp (endif、または else までジャンプ)
246 OpBuffer[obp++]=(char)0xE9;
247 obp+=sizeof(long);
248
249 *((long *)(OpBuffer+i3-sizeof(long)))=obp-i3;
250 *((long *)(OpBuffer+i4-sizeof(long)))=obp-i4;
251
252 //jmpの番地
253 i3=obp;
254 }
255 else{
256 //32ビット型
257
258 //pop eax
259 op_pop(REG_EAX);
260
261 //cmp eax,0
262 OpBuffer[obp++]=(char)0x83;
263 OpBuffer[obp++]=(char)0xF8;
264 OpBuffer[obp++]=(char)0x00;
265
266 //je (endif、または else まで条件ジャンプ)
267 OpBuffer[obp++]=(char)0x0F;
268 OpBuffer[obp++]=(char)0x84;
269 obp+=sizeof(long);
270
271 //jeの番地
272 i3=obp;
273 }
274
275
276 /////////////////////////
277 // If内をコード化
278 /////////////////////////
279
280 //レキシカルスコープをレベルアップ
281 obj_LexScopes.Start( obp, SCOPE_TYPE_IF );
282
283 i2=CompileBuffer(ESC_ENDIF,0);
284
285 //レキシカルスコープをレベルダウン
286 obj_LexScopes.End();
287
288
289 if(i3==-1) return;
290
291 extern char *basbuf;
292 if(i2==ESC_ELSE){
293 //jmp (endifまで)
294 OpBuffer[obp++]=(char)0xE9;
295 obp+=sizeof(long);
296
297 *((long *)(OpBuffer+i3-sizeof(long)))=obp-i3; //ifからelseへのジャンプ先のオフセット値
298
299 i3=obp;
300
301
302 /////////////////////////
303 // Else内をコード化
304 /////////////////////////
305
306 //レキシカルスコープをレベルアップ
307 obj_LexScopes.Start( obp, SCOPE_TYPE_IF );
308
309 CompileBuffer(ESC_ENDIF,0);
310
311 //レキシカルスコープをレベルダウン
312 obj_LexScopes.End();
313
314
315 *((long *)(OpBuffer+i3-sizeof(long)))=obp-i3; //jmpジャンプ先のオフセット値
316 }
317 else{
318 *((long *)(OpBuffer+i3-sizeof(long)))=obp-i3; //jeジャンプ先のオフセット値
319 }
320}
321
322int GetLabelAddress(char *LabelName,int LineNum){
323 extern int MaxLabelNum;
324 extern LABEL *pLabelNames;
325 int i;
326
327 if(LabelName){
328 for(i=0;i<MaxLabelNum;i++){
329 if(pLabelNames[i].pName){
330 if(lstrcmp(LabelName,pLabelNames[i].pName)==0) return pLabelNames[i].address;
331 }
332 }
333 }
334 else{
335 for(i=0;i<MaxLabelNum;i++){
336 if(pLabelNames[i].pName==0){
337 if(LineNum==pLabelNames[i].line) return pLabelNames[i].address;
338 }
339 }
340 }
341 return -1;
342}
343void OpcodeGoto(char *Parameter){
344 extern HANDLE hHeap;
345 extern GOTOLABELSCHEDULE *pGotoLabelSchedule;
346 extern int GotoLabelScheduleNum;
347 int i,LineNum;
348
349 if(Parameter[0]=='*'){
350 i=GetLabelAddress(Parameter+1,0);
351
352 //jmp ...
353 OpBuffer[obp++]=(char)0xE9;
354 if(i==-1){
355 pGotoLabelSchedule=(GOTOLABELSCHEDULE *)HeapReAlloc(hHeap,0,pGotoLabelSchedule,(GotoLabelScheduleNum+1)*sizeof(GOTOLABELSCHEDULE));
356 pGotoLabelSchedule[GotoLabelScheduleNum].pName=(char *)HeapAlloc(hHeap,0,lstrlen(Parameter+1)+1);
357 lstrcpy(pGotoLabelSchedule[GotoLabelScheduleNum].pName,Parameter+1);
358 pGotoLabelSchedule[GotoLabelScheduleNum].pos=obp;
359 pGotoLabelSchedule[GotoLabelScheduleNum].now_cp=cp;
360 GotoLabelScheduleNum++;
361 }
362 *((long *)(OpBuffer+obp))=i-(obp+sizeof(long));
363 obp+=sizeof(long);
364 }
365 else{
366 LineNum=atoi(Parameter);
367 i=GetLabelAddress(0,LineNum);
368
369 //jmp ...
370 OpBuffer[obp++]=(char)0xE9;
371 if(i==-1){
372 pGotoLabelSchedule=(GOTOLABELSCHEDULE *)HeapReAlloc(hHeap,0,pGotoLabelSchedule,(GotoLabelScheduleNum+1)*sizeof(GOTOLABELSCHEDULE));
373 pGotoLabelSchedule[GotoLabelScheduleNum].pName=0;
374 pGotoLabelSchedule[GotoLabelScheduleNum].line=LineNum;
375 pGotoLabelSchedule[GotoLabelScheduleNum].pos=obp;
376 pGotoLabelSchedule[GotoLabelScheduleNum].now_cp=cp;
377 GotoLabelScheduleNum++;
378 }
379 *((long *)(OpBuffer+obp))=i-(obp+sizeof(long));
380 obp+=sizeof(long);
381 }
382}
383void OpcodeWhile(char *Parameter){
384 extern HANDLE hHeap;
385 int i2,i3,type;
386
387 //Continueアドレスのバックアップとセット
388 extern DWORD dwContinueAddress;
389 DWORD dwTempContinue;
390 dwTempContinue=dwContinueAddress;
391 dwContinueAddress=obp;
392
393 if(!Parameter[0]) SetError(10,"While",cp);
394 type=NumOpe(Parameter,0,0,0);
395
396 int je_schedule;
397 if(type==DEF_DOUBLE){
398 //fld qword ptr[esp]
399 op_fld_ptr_esp(DEF_DOUBLE);
400
401 //push 0
402 op_push_V(0);
403
404 //fild dword ptr[esp]
405 op_fld_ptr_esp(DEF_LONG);
406
407 //add esp,sizeof(double)+sizeof(long)
408 op_add_esp(sizeof(double)+sizeof(long));
409
410 //fcompp
411 OpBuffer[obp++]=(char)0xDE;
412 OpBuffer[obp++]=(char)0xD9;
413
414 //fnstsw ax
415 OpBuffer[obp++]=(char)0xDF;
416 OpBuffer[obp++]=(char)0xE0;
417
418 //test ah,40
419 OpBuffer[obp++]=(char)0xF6;
420 OpBuffer[obp++]=(char)0xC4;
421 OpBuffer[obp++]=(char)0x40;
422
423 //jne (Wend まで)
424 OpBuffer[obp++]=(char)0x0F;
425 OpBuffer[obp++]=(char)0x85;
426 obp+=sizeof(long);
427
428 //jeの番地
429 je_schedule=obp;
430 }
431 else if(type==DEF_SINGLE){
432 //fld dword ptr[esp]
433 op_fld_ptr_esp(DEF_SINGLE);
434
435 //push 0
436 op_push_V(0);
437
438 //fild dword ptr[esp]
439 op_fld_ptr_esp(DEF_LONG);
440
441 //add esp,sizeof(float)+sizeof(long)
442 op_add_esp(sizeof(float)+sizeof(long));
443
444 //fcompp
445 OpBuffer[obp++]=(char)0xDE;
446 OpBuffer[obp++]=(char)0xD9;
447
448 //fnstsw ax
449 OpBuffer[obp++]=(char)0xDF;
450 OpBuffer[obp++]=(char)0xE0;
451
452 //test ah,40
453 OpBuffer[obp++]=(char)0xF6;
454 OpBuffer[obp++]=(char)0xC4;
455 OpBuffer[obp++]=(char)0x40;
456
457 //jne (Wend まで)
458 OpBuffer[obp++]=(char)0x0F;
459 OpBuffer[obp++]=(char)0x85;
460 obp+=sizeof(long);
461
462 //jeの番地
463 je_schedule=obp;
464 }
465 else if(type==DEF_INT64||type==DEF_QWORD){
466 //64ビット型
467
468 //pop eax
469 op_pop(REG_EAX);
470
471 //pop ebx
472 op_pop(REG_EBX);
473
474 //cmp eax,0
475 OpBuffer[obp++]=(char)0x83;
476 OpBuffer[obp++]=(char)0xF8;
477 OpBuffer[obp++]=(char)0x00;
478
479 //jne
480 OpBuffer[obp++]=(char)0x0F;
481 OpBuffer[obp++]=(char)0x85;
482 obp+=sizeof(long);
483 i2=obp;
484
485
486 //cmp ebx,0
487 OpBuffer[obp++]=(char)0x83;
488 OpBuffer[obp++]=(char)0xFB;
489 OpBuffer[obp++]=(char)0x00;
490
491 //jne
492 OpBuffer[obp++]=(char)0x0F;
493 OpBuffer[obp++]=(char)0x85;
494 obp+=sizeof(long);
495 i3=obp;
496
497
498 //jmp (endif、または else までジャンプ)
499 OpBuffer[obp++]=(char)0xE9;
500 obp+=sizeof(long);
501
502 *((long *)(OpBuffer+i2-sizeof(long)))=obp-i2;
503 *((long *)(OpBuffer+i3-sizeof(long)))=obp-i3;
504
505 //jmpの番地
506 je_schedule=obp;
507 }
508 else{
509 //その他整数型
510
511 //pop eax
512 op_pop(REG_EAX);
513
514 //cmp eax,0
515 OpBuffer[obp++]=(char)0x83;
516 OpBuffer[obp++]=(char)0xF8;
517 OpBuffer[obp++]=(char)0x00;
518
519 //je (Wend まで)
520 OpBuffer[obp++]=(char)0x0F;
521 OpBuffer[obp++]=(char)0x84;
522 obp+=sizeof(long);
523
524 //実行中の番地
525 je_schedule=obp;
526 }
527
528 //レキシカルスコープをレベルアップ
529 obj_LexScopes.Start( obp, SCOPE_TYPE_WHILE );
530
531 //While内をコンパイル
532 CompileBuffer(0,COM_WEND);
533
534 obj_LexScopes.CallDestructorsOfScopeEnd();
535
536 //jmp ...
537 OpBuffer[obp++]=(char)0xE9;
538 *((long *)(OpBuffer+obp))=dwContinueAddress-(obp+sizeof(long));
539 obp+=sizeof(long);
540
541 //レキシカルスコープをレベルダウン
542 obj_LexScopes.End();
543
544 *((long *)(OpBuffer+je_schedule-sizeof(long)))=obp-je_schedule; //jeジャンプ先のオフセット値
545
546 //Continueアドレスを復元
547 dwContinueAddress=dwTempContinue;
548}
549
550char szNextVariable[VN_SIZE];
551void OpcodeFor(char *Parameter){
552 extern HANDLE hHeap;
553 int i,i2,i3;
554 char temporary[VN_SIZE],variable[VN_SIZE],JudgeNum[VN_SIZE],StepNum[VN_SIZE];
555
556 //第1パラメータを取得
557 i=GetOneParameter(Parameter,0,temporary);
558 if(!Parameter[i]){
559 SetError(12,"For",cp);
560 goto ErrorStep;
561 }
562
563 for(i2=0;;i2++){
564 if(temporary[i2]=='='){
565 variable[i2]=0;
566
567 //カウンタ初期化
568 OpcodeCalc(temporary);
569 break;
570 }
571 if(temporary[i2]=='\0'){
572 SetError(12,"For",cp);
573 goto ErrorStep;
574 }
575 variable[i2]=temporary[i2];
576 }
577
578 //jmp ...
579 OpBuffer[obp++]=(char)0xE9;
580 i2=obp;
581 obp+=sizeof(long);
582
583 //Continueアドレスのバックアップとセット
584 extern DWORD dwContinueAddress;
585 DWORD dwTempContinue;
586 dwTempContinue=dwContinueAddress;
587 dwContinueAddress=obp;
588
589 //第2パラメータを取得(to~)
590 i=GetOneParameter(Parameter,i,JudgeNum);
591
592 //第3パラメータを取得(step~)
593 if(Parameter[i]){
594 i=GetOneParameter(Parameter,i,StepNum);
595 if(Parameter[i]) SetError(12,"For",cp);
596 }
597 else lstrcpy(StepNum,"1");
598
599 //カウンタを増加させる
600 sprintf(temporary,"%s=(%s)+(%s)",variable,variable,StepNum);
601 OpcodeCalc(temporary);
602
603 *((long *)(OpBuffer+i2))=obp-(i2+sizeof(long));
604
605 //増加か減少かを区別する
606 sprintf(temporary,"(%s)>=0",StepNum);
607 NumOpe(temporary,0,0,0);
608
609 //pop eax
610 op_pop(REG_EAX);
611
612 //cmp eax,0
613 OpBuffer[obp++]=(char)0x83;
614 OpBuffer[obp++]=(char)0xF8;
615 OpBuffer[obp++]=(char)0x00;
616
617 //je [カウンタ減少の場合の判定]
618 OpBuffer[obp++]=(char)0x0F;
619 OpBuffer[obp++]=(char)0x84;
620 i2=obp;
621 obp+=sizeof(long);
622
623 //判定(カウンタ増加の場合)
624 sprintf(temporary,"%s<=(%s)",variable,JudgeNum);
625 NumOpe(temporary,0,0,0);
626
627 //pop eax
628 op_pop(REG_EAX);
629
630 //jmp [カウンタ減少の場合の判定を飛び越す]
631 OpBuffer[obp++]=(char)0xE9;
632 i3=obp;
633 obp+=sizeof(long);
634
635 *((long *)(OpBuffer+i2))=obp-(i2+sizeof(long)); //jeジャンプ先のオフセット値
636
637 //判定(カウンタ減少の場合)
638 sprintf(temporary,"%s>=(%s)",variable,JudgeNum);
639 NumOpe(temporary,0,0,0);
640
641 //pop eax
642 op_pop(REG_EAX);
643
644 *((long *)(OpBuffer+i3))=obp-(i3+sizeof(long)); //jmpジャンプ先のオフセット値
645
646 //cmp eax,0
647 OpBuffer[obp++]=(char)0x83;
648 OpBuffer[obp++]=(char)0xF8;
649 OpBuffer[obp++]=(char)0x00;
650
651ErrorStep:
652
653 //je ...
654 OpBuffer[obp++]=(char)0x0F;
655 OpBuffer[obp++]=(char)0x84;
656 int je_schedule=obp;
657 obp+=sizeof(long);
658
659 //レキシカルスコープをレベルアップ
660 obj_LexScopes.Start( obp, SCOPE_TYPE_FOR );
661
662 //For内をコンパイル
663 CompileBuffer(0,COM_NEXT);
664
665 obj_LexScopes.CallDestructorsOfScopeEnd();
666
667 if(szNextVariable[0]){
668 if(lstrcmp(szNextVariable,variable)!=0){
669 SetError(55,szNextVariable,cp);
670 }
671 }
672
673 //jmp ...
674 OpBuffer[obp++]=(char)0xE9;
675 *((long *)(OpBuffer+obp))=dwContinueAddress-(obp+sizeof(long));
676 obp+=sizeof(long);
677
678 //レキシカルスコープをレベルダウン
679 obj_LexScopes.End();
680
681 *((long *)(OpBuffer+je_schedule))=obp-(je_schedule+sizeof(long)); //jeジャンプ先のオフセット値
682
683 //Continueアドレスを復元
684 dwContinueAddress=dwTempContinue;
685}
686
687void OpcodeDo(char *Parameter){
688 extern HANDLE hHeap;
689 int i,i2,i3,i4,type;
690
691 if(Parameter[0]) SetError(10,"Do",cp);
692
693 //Continueアドレスのバックアップとセット
694 extern DWORD dwContinueAddress;
695 DWORD dwTempContinue;
696 dwTempContinue=dwContinueAddress;
697 dwContinueAddress=obp;
698
699 //レキシカルスコープをレベルアップ
700 obj_LexScopes.Start( obp, SCOPE_TYPE_DO );
701
702 //Do内をコンパイル
703 CompileBuffer(0,COM_LOOP);
704
705 obj_LexScopes.CallDestructorsOfScopeEnd();
706
707 extern char *basbuf;
708 char temporary[VN_SIZE];
709 for(i=cp-1;;i--){
710 if(IsCommandDelimitation(basbuf[i])){
711 i+=3;
712 if(!(basbuf[i]=='0'||basbuf[i]=='1')){
713 //無条件ループ
714 break;
715 }
716 i3=i;
717
718 for(i+=2,i2=0;;i++,i2++){
719 if(IsCommandDelimitation(basbuf[i])){
720 temporary[i2]=0;
721 break;
722 }
723 temporary[i2]=basbuf[i];
724 }
725
726 type=NumOpe(temporary,0,0,0);
727
728 if(type==DEF_DOUBLE){
729 //fld qword ptr[esp]
730 op_fld_ptr_esp(DEF_DOUBLE);
731
732 //push 0
733 op_push_V(0);
734
735 //fild dword ptr[esp]
736 op_fld_ptr_esp(DEF_LONG);
737
738 //add esp,sizeof(double)+sizeof(long)
739 op_add_esp(sizeof(double)+sizeof(long));
740
741 //fcompp
742 OpBuffer[obp++]=(char)0xDE;
743 OpBuffer[obp++]=(char)0xD9;
744
745 //fnstsw ax
746 OpBuffer[obp++]=(char)0xDF;
747 OpBuffer[obp++]=(char)0xE0;
748
749 //test ah,40
750 OpBuffer[obp++]=(char)0xF6;
751 OpBuffer[obp++]=(char)0xC4;
752 OpBuffer[obp++]=(char)0x40;
753
754 if(basbuf[i3]=='0'){
755 //While
756
757 //jne 5(ループ終了)
758 OpBuffer[obp++]=(char)0x75;
759 OpBuffer[obp++]=(char)0x05;
760 }
761 else if(basbuf[i3]=='1'){
762 //Until
763
764 //je 5(ループ終了)
765 OpBuffer[obp++]=(char)0x74;
766 OpBuffer[obp++]=(char)0x05;
767 }
768 }
769 else if(type==DEF_SINGLE){
770 //fld dword ptr[esp]
771 op_fld_ptr_esp(DEF_SINGLE);
772
773 //push 0
774 op_push_V(0);
775
776 //fild dword ptr[esp]
777 op_fld_ptr_esp(DEF_LONG);
778
779 //add esp,sizeof(float)+sizeof(long)
780 op_add_esp(sizeof(float)+sizeof(long));
781
782 //fcompp
783 OpBuffer[obp++]=(char)0xDE;
784 OpBuffer[obp++]=(char)0xD9;
785
786 //fnstsw ax
787 OpBuffer[obp++]=(char)0xDF;
788 OpBuffer[obp++]=(char)0xE0;
789
790 //test ah,40
791 OpBuffer[obp++]=(char)0xF6;
792 OpBuffer[obp++]=(char)0xC4;
793 OpBuffer[obp++]=(char)0x40;
794
795 if(basbuf[i3]=='0'){
796 //While
797
798 //jne 5(ループ終了)
799 OpBuffer[obp++]=(char)0x75;
800 OpBuffer[obp++]=(char)0x05;
801 }
802 else if(basbuf[i3]=='1'){
803 //Until
804
805 //je 5(ループ終了)
806 OpBuffer[obp++]=(char)0x74;
807 OpBuffer[obp++]=(char)0x05;
808 }
809 }
810 else if(type==DEF_INT64||type==DEF_QWORD){
811 //64ビット型
812
813 //pop eax
814 op_pop(REG_EAX);
815
816 //pop ebx
817 op_pop(REG_EBX);
818
819 //cmp eax,0
820 OpBuffer[obp++]=(char)0x83;
821 OpBuffer[obp++]=(char)0xF8;
822 OpBuffer[obp++]=(char)0x00;
823
824 //jne
825 OpBuffer[obp++]=(char)0x0F;
826 OpBuffer[obp++]=(char)0x85;
827 obp+=sizeof(long);
828 i2=obp;
829
830
831 //cmp ebx,0
832 OpBuffer[obp++]=(char)0x83;
833 OpBuffer[obp++]=(char)0xFB;
834 OpBuffer[obp++]=(char)0x00;
835
836 //jne
837 OpBuffer[obp++]=(char)0x0F;
838 OpBuffer[obp++]=(char)0x85;
839 obp+=sizeof(long);
840 i4=obp;
841
842
843 if(basbuf[i3]=='0'){
844 //While
845
846 //jmp 5(ループ終了)
847 OpBuffer[obp++]=(char)0xEB;
848 OpBuffer[obp++]=(char)0x05;
849
850 *((long *)(OpBuffer+i2-sizeof(long)))=obp-i2;
851 *((long *)(OpBuffer+i4-sizeof(long)))=obp-i4;
852 }
853 else if(basbuf[i3]=='1'){
854 //Until
855
856 //jmp 2(ループを続ける)
857 OpBuffer[obp++]=(char)0xEB;
858 OpBuffer[obp++]=(char)0x02;
859
860 *((long *)(OpBuffer+i2-sizeof(long)))=obp-i2;
861 *((long *)(OpBuffer+i4-sizeof(long)))=obp-i4;
862
863 //jmp 5(ループ終了)
864 OpBuffer[obp++]=(char)0xEB;
865 OpBuffer[obp++]=(char)0x05;
866 }
867 }
868 else{
869 //pop eax
870 op_pop(REG_EAX);
871
872 //cmp eax,0
873 OpBuffer[obp++]=(char)0x83;
874 OpBuffer[obp++]=(char)0xF8;
875 OpBuffer[obp++]=(char)0x00;
876
877 if(basbuf[i3]=='0'){
878 //While
879
880 //je 5(ループ終了)
881 OpBuffer[obp++]=(char)0x74;
882 OpBuffer[obp++]=(char)0x05;
883 }
884 else if(basbuf[i3]=='1'){
885 //Until
886
887 //jne 5(ループ終了)
888 OpBuffer[obp++]=(char)0x75;
889 OpBuffer[obp++]=(char)0x05;
890 }
891 }
892 break;
893 }
894 }
895
896 //jmp ...
897 OpBuffer[obp++]=(char)0xE9;
898 *((long *)(OpBuffer+obp))=dwContinueAddress-(obp+sizeof(long));
899 obp+=sizeof(long);
900
901 //jmp ...
902 OpBuffer[obp++]=(char)0xE9;
903 int je_schedule=obp;
904 obp+=sizeof(long);
905
906 //レキシカルスコープをレベルダウン
907 obj_LexScopes.End();
908
909 *((long *)(OpBuffer+je_schedule))=obp-(je_schedule+sizeof(long)); //jmpジャンプ先のオフセット値
910
911
912 //Continueアドレスを復元
913 dwContinueAddress=dwTempContinue;
914}
915void OpcodeContinue(void){
916 extern DWORD dwContinueAddress;
917
918 if(dwContinueAddress==-1){
919 SetError(12,"Continue",cp);
920 return;
921 }
922
923 //jmp ...(Continue addr)
924 OpBuffer[obp++]=(char)0xE9;
925
926 *((long *)(OpBuffer+obp))=dwContinueAddress-(obp+sizeof(long));
927 obp+=sizeof(long);
928}
929
930void OpcodeExitSub(void){
931 extern DWORD *pExitSubSchedule;
932 extern int ExitSubScheduleNum;
933 extern HANDLE hHeap;
934
935 extern BOOL bCompilingGlobal;
936 if(bCompilingGlobal){
937 SetError(12,"Exit Sub/Function",cp);
938 return;
939 }
940
941 //未解放のローカルオブジェクトのデストラクタを呼び出す
942 obj_LexScopes.CallDestructorsOfReturn();
943
944 //jmp ...(End Sub/Function)
945 OpBuffer[obp++]=(char)0xE9;
946
947 pExitSubSchedule=(DWORD *)HeapReAlloc(hHeap,0,pExitSubSchedule,(ExitSubScheduleNum+1)*sizeof(DWORD));
948 pExitSubSchedule[ExitSubScheduleNum]=obp;
949 ExitSubScheduleNum++;
950
951 obp+=sizeof(long);
952}
953
954void AddCaseSchedule(void){
955 extern DWORD *pCaseSchedule;
956 extern int CaseScheduleNum;
957 extern HANDLE hHeap;
958
959 pCaseSchedule=(DWORD *)HeapReAlloc(hHeap,0,pCaseSchedule,(CaseScheduleNum+1)*sizeof(DWORD));
960 pCaseSchedule[CaseScheduleNum]=obp;
961 CaseScheduleNum++;
962}
963
964int CaseTypeSize;
965void OpcodeSelect(const char *lpszParams){
966 extern DWORD *pCaseSchedule;
967 extern int CaseScheduleNum;
968 extern int NowCaseSchedule;
969 extern int CaseTypeSize;
970 extern HANDLE hHeap;
971 extern char *basbuf;
972 int i,i2,i3,sw,type1,type2,NowCaseCp;
973 char temporary[VN_SIZE];
974
975 DWORD *temp_pCaseSchedule;
976 int temp_CaseScheduleNum;
977 int temp_NowCaseSchedule;
978 int temp_CaseTypeSize;
979
980 temp_pCaseSchedule=pCaseSchedule;
981 temp_CaseScheduleNum=CaseScheduleNum;
982 temp_NowCaseSchedule=NowCaseSchedule;
983 temp_CaseTypeSize=CaseTypeSize;
984 pCaseSchedule=(DWORD *)HeapAlloc(hHeap,0,1);
985 CaseScheduleNum=0;
986 NowCaseSchedule=0;
987
988 LONG_PTR lpIndex;
989 type1=NumOpe(lpszParams,0,0,&lpIndex);
990 if(type1==DEF_INTEGER||
991 type1==DEF_WORD||
992 type1==DEF_SBYTE||
993 type1==DEF_BYTE||
994 type1==DEF_BOOLEAN||
995 type1==DEF_CHAR) CaseTypeSize=sizeof(long);
996 else{
997 CaseTypeSize=GetTypeSize(type1,lpIndex);
998 if(type1==DEF_OBJECT) CaseTypeSize=PTR_SIZE;
999 }
1000
1001 for(i=cp,sw=0;;i++){
1002 if(basbuf[i]=='\0'){
1003 HeapDefaultFree(pCaseSchedule);
1004 pCaseSchedule=temp_pCaseSchedule;
1005 CaseScheduleNum=temp_CaseScheduleNum;
1006 NowCaseSchedule=temp_NowCaseSchedule;
1007 CaseTypeSize=temp_CaseTypeSize;
1008 SetError(22,"Select",cp);
1009 return;
1010 }
1011 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE){
1012 for(i2=0;;i++){
1013 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE) i2++;
1014 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT){
1015 i2--;
1016 if(i2==0) break;
1017 }
1018 }
1019 continue;
1020 }
1021 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT){
1022 if(sw==0){
1023 //add esp,CaseTypeSize
1024 op_add_esp(CaseTypeSize);
1025 }
1026 break;
1027 }
1028 if(basbuf[i]==1&&basbuf[i+1]==ESC_CASE){
1029 NowCaseCp=i;
1030
1031 i++;
1032 while(1){
1033 for(i++,i2=0;;i++,i2++){
1034 if(basbuf[i]=='\"'){
1035 i3=GetStringInQuotation(temporary+i2,basbuf+i);
1036 i+=i3-1;
1037 i2+=i3-1;
1038 continue;
1039 }
1040 if(basbuf[i]=='('){
1041 i3=GetStringInPare(temporary+i2,basbuf+i);
1042 i+=i3-1;
1043 i2+=i3-1;
1044 continue;
1045 }
1046 if(basbuf[i]=='['){
1047 i3=GetStringInBracket(temporary+i2,basbuf+i);
1048 i+=i3-1;
1049 i2+=i3-1;
1050 continue;
1051 }
1052
1053 if(IsCommandDelimitation(basbuf[i])){
1054 temporary[i2]=0;
1055 break;
1056 }
1057 if(basbuf[i]==','){
1058 temporary[i2]=0;
1059 break;
1060 }
1061
1062 temporary[i2]=basbuf[i];
1063 }
1064
1065 //エラー用
1066 i2=cp;
1067 cp=NowCaseCp;
1068
1069 LONG_PTR lpIndex2;
1070 type2=NumOpe(temporary,type1,lpIndex,&lpIndex2);
1071
1072 cp=i2;
1073
1074 if(type1==DEF_OBJECT){
1075 CClass *pobj_c;
1076 pobj_c=(CClass *)lpIndex;
1077
1078 std::vector<UserProc *> subs;
1079 pobj_c->EnumMethod( CALC_EQUAL, subs );
1080 if( subs.size() == 0 ){
1081 return;
1082 }
1083
1084 Parameters params;
1085 params.push_back( new Parameter( "", Type( type2, lpIndex2 ) ) );
1086
1087 //オーバーロードを解決
1088 UserProc *pUserProc;
1089 pUserProc=OverloadSolution("==",subs, params, NULL);
1090
1091 delete params[0];
1092
1093 if(!pUserProc){
1094 //エラー
1095 return;
1096 }
1097
1098
1099 //pop edx
1100 op_pop(REG_EDX);
1101
1102 //mov ecx,dword ptr[esp]
1103 op_mov_RM(sizeof(long),REG_ECX,REG_ESP,0,MOD_BASE);
1104
1105 //push edx
1106 op_push(REG_EDX);
1107
1108 //push ecx
1109 op_push(REG_ECX);
1110
1111 //call operator_proc ※ ==演算子
1112 op_call(pUserProc);
1113
1114 //test eax,eax
1115 op_test(REG_EAX,REG_EAX);
1116
1117 //jne ...
1118 OpBuffer[obp++]=(char)0x0F;
1119 OpBuffer[obp++]=(char)0x85;
1120 AddCaseSchedule();
1121 obp+=sizeof(long);
1122 }
1123 else if(type1==DEF_DOUBLE){
1124 ChangeTypeToDouble(type2);
1125
1126 //fld qword ptr[esp]
1127 op_fld_ptr_esp(DEF_DOUBLE);
1128
1129 //add esp,CaseTypeSize
1130 op_add_esp(CaseTypeSize);
1131
1132 //fld qword ptr[esp]
1133 op_fld_ptr_esp(DEF_DOUBLE);
1134
1135 //fcompp
1136 OpBuffer[obp++]=(char)0xDE;
1137 OpBuffer[obp++]=(char)0xD9;
1138
1139 //fnstsw ax
1140 OpBuffer[obp++]=(char)0xDF;
1141 OpBuffer[obp++]=(char)0xE0;
1142
1143 //test ah,40
1144 OpBuffer[obp++]=(char)0xF6;
1145 OpBuffer[obp++]=(char)0xC4;
1146 OpBuffer[obp++]=(char)0x40;
1147
1148 //jne ...
1149 OpBuffer[obp++]=(char)0x0F;
1150 OpBuffer[obp++]=(char)0x85;
1151 AddCaseSchedule();
1152 obp+=sizeof(long);
1153 }
1154 else if(type1==DEF_SINGLE){
1155 ChangeTypeToSingle(type2);
1156
1157 //fld dword ptr[esp]
1158 op_fld_ptr_esp(DEF_SINGLE);
1159
1160 //add esp,CaseTypeSize
1161 op_add_esp(CaseTypeSize);
1162
1163 //fld dword ptr[esp]
1164 op_fld_ptr_esp(DEF_SINGLE);
1165
1166 //fcompp
1167 OpBuffer[obp++]=(char)0xDE;
1168 OpBuffer[obp++]=(char)0xD9;
1169
1170 //fnstsw ax
1171 OpBuffer[obp++]=(char)0xDF;
1172 OpBuffer[obp++]=(char)0xE0;
1173
1174 //test ah,40
1175 OpBuffer[obp++]=(char)0xF6;
1176 OpBuffer[obp++]=(char)0xC4;
1177 OpBuffer[obp++]=(char)0x40;
1178
1179 //jne ...
1180 OpBuffer[obp++]=(char)0x0F;
1181 OpBuffer[obp++]=(char)0x85;
1182 AddCaseSchedule();
1183 obp+=sizeof(long);
1184 }
1185 else{
1186 //その他整数型
1187
1188 //pop ebx
1189 op_pop(REG_EBX);
1190
1191 //mov eax,dword ptr[esp]
1192 OpBuffer[obp++]=(char)0x8B;
1193 OpBuffer[obp++]=(char)0x04;
1194 OpBuffer[obp++]=(char)0x24;
1195
1196 //cmp eax,ebx
1197 OpBuffer[obp++]=(char)0x3B;
1198 OpBuffer[obp++]=(char)0xC3;
1199
1200 //je ...
1201 OpBuffer[obp++]=(char)0x0F;
1202 OpBuffer[obp++]=(char)0x84;
1203 AddCaseSchedule();
1204 obp+=sizeof(long);
1205 }
1206
1207 if(basbuf[i]!=',') break;
1208 }
1209 }
1210 if(basbuf[i]==1&&basbuf[i+1]==ESC_CASEELSE){
1211 sw=1;
1212
1213 //jmp ...
1214 OpBuffer[obp++]=(char)0xE9;
1215 AddCaseSchedule();
1216 obp+=sizeof(long);
1217 }
1218 }
1219
1220 //レキシカルスコープをレベルアップ
1221 obj_LexScopes.Start( obp, SCOPE_TYPE_SELECT );
1222
1223 //Select Case内をコンパイル
1224 CompileBuffer(ESC_ENDSELECT,0);
1225
1226 //jmp EndSelect
1227 OpBuffer[obp++]=(char)0xE9;
1228 AddCaseSchedule();
1229 obp+=sizeof(long);
1230
1231 //最終スケジュール
1232 for(i=NowCaseSchedule;i<CaseScheduleNum;i++){
1233 *(long *)(OpBuffer+pCaseSchedule[i])=obp-(pCaseSchedule[i]+sizeof(long));
1234 }
1235 HeapDefaultFree(pCaseSchedule);
1236
1237 //レキシカルスコープをレベルダウン
1238 obj_LexScopes.End();
1239
1240 pCaseSchedule=temp_pCaseSchedule;
1241 CaseScheduleNum=temp_CaseScheduleNum;
1242 NowCaseSchedule=temp_NowCaseSchedule;
1243 CaseTypeSize=temp_CaseTypeSize;
1244}
1245void OpcodeCase(char *Parameter){
1246 extern DWORD *pCaseSchedule;
1247 extern int NowCaseSchedule;
1248 extern int CaseTypeSize;
1249 int i;
1250
1251 if(!pCaseSchedule){
1252 SetError(30,"Case",cp);
1253 return;
1254 }
1255
1256 //jmp EndSelect
1257 OpBuffer[obp++]=(char)0xE9;
1258 AddCaseSchedule();
1259 obp+=sizeof(long);
1260
1261 i=0;
1262 while(1){
1263 //Caseスケジュール
1264 *(long *)(OpBuffer+pCaseSchedule[NowCaseSchedule])=obp-(pCaseSchedule[NowCaseSchedule]+sizeof(long));
1265 NowCaseSchedule++;
1266
1267 i=JumpOneParameter(Parameter,i);
1268 if(Parameter[i]=='\0') break;
1269 }
1270
1271 //add esp,CaseTypeSize
1272 op_add_esp(CaseTypeSize);
1273}
1274
1275void OpcodeGosub(char *Parameter){
1276 extern HANDLE hHeap;
1277 extern GOTOLABELSCHEDULE *pGotoLabelSchedule;
1278 extern int GotoLabelScheduleNum;
1279 int i,LineNum;
1280
1281 if(Parameter[0]=='*'){
1282 i=GetLabelAddress(Parameter+1,0);
1283
1284 //call ...
1285 OpBuffer[obp++]=(char)0xE8;
1286 if(i==-1){
1287 pGotoLabelSchedule=(GOTOLABELSCHEDULE *)HeapReAlloc(hHeap,0,pGotoLabelSchedule,(GotoLabelScheduleNum+1)*sizeof(GOTOLABELSCHEDULE));
1288 pGotoLabelSchedule[GotoLabelScheduleNum].pName=(char *)HeapAlloc(hHeap,0,lstrlen(Parameter+1)+1);
1289 lstrcpy(pGotoLabelSchedule[GotoLabelScheduleNum].pName,Parameter+1);
1290 pGotoLabelSchedule[GotoLabelScheduleNum].pos=obp;
1291 pGotoLabelSchedule[GotoLabelScheduleNum].now_cp=cp;
1292 GotoLabelScheduleNum++;
1293 }
1294 *((long *)(OpBuffer+obp))=i-(obp+sizeof(long));
1295 obp+=sizeof(long);
1296 }
1297 else{
1298 LineNum=atoi(Parameter);
1299 i=GetLabelAddress(0,LineNum);
1300
1301 //call ...
1302 OpBuffer[obp++]=(char)0xE8;
1303 if(i==-1){
1304 pGotoLabelSchedule=(GOTOLABELSCHEDULE *)HeapReAlloc(hHeap,0,pGotoLabelSchedule,(GotoLabelScheduleNum+1)*sizeof(GOTOLABELSCHEDULE));
1305 pGotoLabelSchedule[GotoLabelScheduleNum].pName=0;
1306 pGotoLabelSchedule[GotoLabelScheduleNum].line=LineNum;
1307 pGotoLabelSchedule[GotoLabelScheduleNum].pos=obp;
1308 pGotoLabelSchedule[GotoLabelScheduleNum].now_cp=cp;
1309 GotoLabelScheduleNum++;
1310 }
1311 *((long *)(OpBuffer+obp))=i-(obp+sizeof(long));
1312 obp+=sizeof(long);
1313 }
1314}
1315void OpcodeReturn(char *Parameter){
1316 extern BOOL bCompilingGlobal;
1317 if(bCompilingGlobal){
1318 //Gosub~Returnとして扱う
1319
1320 //ret
1321 OpBuffer[obp++]=(char)0xC3;
1322 }
1323 else{
1324 //戻り値をセット
1325 if(Parameter[0]){
1326 extern UserProc *pCompilingUserProc;
1327 const char *temp = "_System_ReturnValue";
1328 if(pCompilingUserProc->GetName()[0]==1&&pCompilingUserProc->GetName()[1]==ESC_OPERATOR)
1329 {
1330 }
1331 else temp=pCompilingUserProc->GetName().c_str();
1332
1333 char temporary[VN_SIZE];
1334 sprintf(temporary,"%s=%s",temp,Parameter);
1335 OpcodeCalc(temporary);
1336 }
1337
1338 //プロシージャを抜け出す(C言語のreturnと同様の処理を行う)
1339 OpcodeExitSub();
1340 }
1341}
1342
1343void Opcode_Input(const char *Parameter){
1344 extern int cp;
1345 int i2,i3,i4,i5,type;
1346 BOOL bFile;
1347 char temporary[VN_SIZE],temp2[VN_SIZE],buffer[VN_SIZE];
1348
1349 if(Parameter[0]=='#'){
1350 bFile=1;
1351 for(i2=0,i3=1;;i2++,i3++){
1352 buffer[i2]=Parameter[i3];
1353 if(Parameter[i3]==','||Parameter[i3]=='\0') break;
1354 }
1355 buffer[i2+1]=0;
1356 i2=i3+1;
1357 }
1358 else{
1359 bFile=0;
1360 i2=0;
1361 buffer[0]=0;
1362
1363 //表示用文字列パラメータをセット
1364 if(Parameter[0]=='\"'){
1365 buffer[0]='\"';
1366 for(i2=1;;i2++){
1367 if(Parameter[i2]=='\"'){
1368 buffer[i2]=0;
1369 break;
1370 }
1371 buffer[i2]=Parameter[i2];
1372 }
1373 if(Parameter[i2+1]==';') lstrcpy(buffer+i2,"? \"");
1374 else if(Parameter[i2+1]==',') lstrcpy(buffer+i2,"\"");
1375 else SetError(10,"Input",cp);
1376 i2+=2;
1377 }
1378 else if((Parameter[0]=='e'||Parameter[0]=='E')&&
1379 (Parameter[1]=='x'||Parameter[1]=='X')&&
1380 Parameter[2]=='\"'){
1381 memcpy(buffer,Parameter,3);
1382 for(i2=3;;i2++){
1383 if(Parameter[i2]=='\"'){
1384 buffer[i2]=0;
1385 break;
1386 }
1387 buffer[i2]=Parameter[i2];
1388 }
1389 if(Parameter[i2+1]==';') lstrcpy(buffer+i2,"? \"");
1390 else if(Parameter[i2+1]==',') lstrcpy(buffer+i2,"\"");
1391 else SetError(10,"Input",cp);
1392 i2+=2;
1393 }
1394 else{
1395 lstrcpy(buffer,"\"? \"");
1396 i2=0;
1397 }
1398 }
1399
1400 //変数ポインタ、変数のタイプをセット
1401 i4=0;
1402 while(1){
1403 for(i3=0;;i2++,i3++){
1404 if(Parameter[i2]=='('){
1405 i5=GetStringInPare(temporary+i3,Parameter+i2);
1406 i2+=i5-1;
1407 i3+=i5-1;
1408 }
1409 if(Parameter[i2]=='['){
1410 i5=GetStringInBracket(temporary+i3,Parameter+i2);
1411 i2+=i5-1;
1412 i3+=i5-1;
1413 }
1414 if(Parameter[i2]==','){
1415 temporary[i3]=0;
1416 i2++;
1417 break;
1418 }
1419 temporary[i3]=Parameter[i2];
1420 if(Parameter[i2]=='\0') break;
1421 }
1422 if(temporary[0]=='\0'){
1423 SetError(10,"Input",cp);
1424 return;
1425 }
1426
1427 LONG_PTR lpIndex;
1428 type = GetVarType(temporary,&lpIndex,1);
1429
1430 sprintf(temp2,"_System_InputDataPtr[%d]=VarPtr(%s)",i4,temporary);
1431 OpcodeCalc(temp2);
1432
1433 if(type==DEF_LONG) type=DEF_DWORD;
1434 else if(type==DEF_INTEGER) type=DEF_WORD;
1435 else if(type==DEF_OBJECT){
1436 CClass *pobj_Class=(CClass *)lpIndex;
1437 if(lstrcmp(pobj_Class->name,"String")==0) type=DEF_STRING;
1438 }
1439 sprintf(temp2,"_System_InputDataType[%d]=%d",i4,type);
1440 OpcodeCalc(temp2);
1441
1442 i4++;
1443 if(Parameter[i2]=='\0') break;
1444 }
1445 sprintf(temp2,"_System_InputDataPtr[%d]=0",i4);
1446 OpcodeCalc(temp2);
1447
1448 UserProc *pUserProc;
1449 if(bFile) pUserProc=GetSubHash("INPUT_FromFile");
1450 else pUserProc=GetSubHash("INPUT_FromPrompt");
1451 if(!pUserProc){
1452 SetError(3,"Input",cp);
1453 return;
1454 }
1455 Opcode_CallProc(buffer,pUserProc,0,"",0);
1456}
1457void Opcode_PrintUsing(const char *Parameter,char *buffer,BOOL bFile){
1458 extern int cp;
1459 int i2,i3,i4,i5;
1460 char temporary[VN_SIZE],temp2[8192];
1461 BOOL bReturnLine;
1462
1463 char parms[8192];
1464 lstrcpy( parms, Parameter );
1465
1466 i2=lstrlen(parms);
1467 if(parms[i2-1]==';'){
1468 bReturnLine=0;
1469 parms[i2-1]=0;
1470 }
1471 else bReturnLine=1;
1472
1473 i3=lstrlen(buffer);
1474 for(i2=0;;i2++,i3++){
1475 if(parms[i2]==';'){
1476 buffer[i3]=0;
1477 break;
1478 }
1479 buffer[i3]=parms[i2];
1480 if(parms[i2]=='\0') break;
1481 }
1482 if(parms[i2]==';') i2++;
1483
1484 if(bReturnLine) lstrcat(buffer,"+Ex\"\\r\\n\"");
1485
1486 //データポインタ、データのタイプをセット
1487 i4=0;
1488 while(1){
1489 for(i3=0;;i2++,i3++){
1490 if(parms[i2]=='\"'){
1491 temporary[i3]=parms[i2];
1492 for(i2++,i3++;;i2++,i3++){
1493 temporary[i3]=parms[i2];
1494 if(parms[i2]=='\"') break;
1495 }
1496 continue;
1497 }
1498 if(parms[i2]=='('){
1499 i5=GetStringInPare(temporary+i3,parms+i2);
1500 i2+=i5-1;
1501 i3+=i5-1;
1502 continue;
1503 }
1504 if(parms[i2]=='['){
1505 i5=GetStringInBracket(temporary+i3,parms+i2);
1506 i2+=i5-1;
1507 i3+=i5-1;
1508 continue;
1509 }
1510 if(parms[i2]==','){
1511 temporary[i3]=0;
1512 i2++;
1513 break;
1514 }
1515 temporary[i3]=parms[i2];
1516 if(parms[i2]=='\0') break;
1517 }
1518 if(temporary[0]=='\0'){
1519 SetError(10,"Print",cp);
1520 return;
1521 }
1522
1523 int iResult;
1524 iResult=IsStrCalculation(temporary);
1525
1526 if(iResult==1){
1527 //文字列
1528 sprintf(temp2,"_System_UsingStrData[%d]=%s",i4,temporary);
1529 OpcodeCalc(temp2);
1530
1531 sprintf(temp2,"_System_UsingDataType[%d]=%d",i4,DEF_STRING);
1532 OpcodeCalc(temp2);
1533 }
1534 else if(iResult==0){
1535 //数値
1536 sprintf(temp2,"_System_UsingDblData[%d]=%s",i4,temporary);
1537 OpcodeCalc(temp2);
1538
1539 sprintf(temp2,"_System_UsingDataType[%d]=%d",i4,DEF_DOUBLE);
1540 OpcodeCalc(temp2);
1541 }
1542 //else if(iResult==-1) エラー
1543
1544 i4++;
1545 if(parms[i2]=='\0') break;
1546 }
1547 sprintf(temp2,"_System_UsingDataType[%d]=-1",i4);
1548 OpcodeCalc(temp2);
1549
1550 UserProc *pUserProc;
1551 if(bFile) pUserProc=GetSubHash("PRINTUSING_ToFile");
1552 else pUserProc=GetSubHash("PRINTUSING_ToPrompt");
1553 if(!pUserProc){
1554 SetError(3,"Print",cp);
1555 return;
1556 }
1557 Opcode_CallProc(buffer,pUserProc,0,"",0);
1558}
1559void Opcode_Print(const char *Parameter,BOOL bWrite){
1560 int i2,i3,i4,sw;
1561 char temporary[VN_SIZE],buffer[VN_SIZE];
1562 BOOL bFile;
1563
1564 if(Parameter[0]=='#'){
1565 bFile=1;
1566 for(i2=0,i3=1;;i2++,i3++){
1567 buffer[i2]=Parameter[i3];
1568 if(Parameter[i3]==','||Parameter[i3]=='\0') break;
1569 }
1570 buffer[i2+1]=0;
1571 if(Parameter[i3]==',') i3++;
1572 i2=i3;
1573 }
1574 else{
1575 bFile=0;
1576 i2=0;
1577 buffer[0]=0;
1578 }
1579 if(Parameter[i2]==1&&Parameter[i2+1]==ESC_USING){
1580 Opcode_PrintUsing(Parameter+i2+2,buffer,bFile);
1581 return;
1582 }
1583
1584 lstrcat(buffer,"_System_DummyStr+");
1585
1586 sw=1;
1587 while(1){
1588 for(i3=0;;i2++,i3++){
1589 if(Parameter[i2]=='\"'){
1590 temporary[i3]=Parameter[i2];
1591 for(i2++,i3++;;i2++,i3++){
1592 temporary[i3]=Parameter[i2];
1593 if(Parameter[i2]=='\"') break;
1594 }
1595 continue;
1596 }
1597 if(Parameter[i2]=='('){
1598 i4=GetStringInPare(temporary+i3,Parameter+i2);
1599 i2+=i4-1;
1600 i3+=i4-1;
1601 continue;
1602 }
1603 if(Parameter[i2]=='['){
1604 i4=GetStringInBracket(temporary+i3,Parameter+i2);
1605 i2+=i4-1;
1606 i3+=i4-1;
1607 continue;
1608 }
1609 if(Parameter[i2]==','||Parameter[i2]==';'){
1610 temporary[i3]=0;
1611 break;
1612 }
1613 temporary[i3]=Parameter[i2];
1614 if(Parameter[i2]=='\0') break;
1615 }
1616
1617 if(temporary[0]=='\0') lstrcat(buffer,"\"\"");
1618 else{
1619 int iResult;
1620 iResult=IsStrCalculation(temporary);
1621 if(iResult==-1){
1622 //エラー
1623 lstrcat(buffer,"\"\"");
1624 }
1625 else if(iResult){
1626 //文字列
1627 lstrcat(buffer,temporary);
1628 }
1629 else{
1630 //数値
1631 sprintf(buffer+lstrlen(buffer),"Str$(%s)",temporary);
1632 }
1633 }
1634
1635 if(Parameter[i2]==','){
1636 if(bWrite) lstrcat(buffer,"+\",\"+");
1637 else lstrcat(buffer,"+\"\t\"+");
1638 }
1639 else if(Parameter[i2]==';'){
1640 if(Parameter[i2+1]=='\0'){
1641 sw=0;
1642 break;
1643 }
1644 if(bWrite) lstrcat(buffer,"+\",\"+");
1645 else lstrcat(buffer,"+\" \"+");
1646 }
1647 else if(Parameter[i2]=='\0') break;
1648
1649 i2++;
1650 }
1651
1652 if(sw) lstrcat(buffer,"+Ex\"\\r\\n\"");
1653
1654 UserProc *pUserProc;
1655 if(bFile) pUserProc=GetSubHash("PRINT_ToFile");
1656 else pUserProc=GetSubHash("PRINT_ToPrompt");
1657 if(!pUserProc){
1658 SetError(3,"Print",cp);
1659 return;
1660 }
1661 Opcode_CallProc(buffer,pUserProc,0,"",0);
1662}
1663
1664
1665
1666
1667////////////
1668// ポインタ
1669
1670void OpcodeCallPtr(char *Parameter){
1671 extern HANDLE hHeap;
1672 int i,i2,i3,num,types[255];
1673 BOOL bCdecl;
1674 char szFuncPtr[VN_SIZE],temporary[VN_SIZE],*Parms[255];
1675
1676 //関数ポインタを取得
1677 i=GetOneParameter(Parameter,0,szFuncPtr);
1678
1679 if(lstrcmpi(szFuncPtr,"cdecl")==0){
1680 //cdeclが指定された場合は、第2パラメータを関数ポインタとして扱う
1681 bCdecl=1;
1682
1683 i=GetOneParameter(Parameter,i,szFuncPtr);
1684 }
1685 else bCdecl=0;
1686
1687 if(Parameter[0]=='\0'){
1688 SetError(10,"CallPtr",cp);
1689 }
1690
1691 num=0;
1692 while(Parameter[i]){
1693 i=GetOneParameter(Parameter,i,temporary);
1694
1695 types[num]=DEF_LONG;
1696
1697 for(i2=0;;i2++){
1698 if(temporary[i2]=='\0') break;
1699 if(temporary[i2]==1&&temporary[i2+1]==ESC_AS){
1700 LONG_PTR lp;
1701 types[num]=GetTypeFixed(temporary+i2+2,&lp);
1702
1703 if(types[num]==DEF_OBJECT){
1704 SetError(11,temporary+i2+2,cp);
1705 }
1706
1707 temporary[i2]=0;
1708 break;
1709 }
1710 }
1711
1712 Parms[num]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
1713 lstrcpy(Parms[num],temporary);
1714
1715 num++;
1716 }
1717
1718 int ParmSize=0;
1719
1720 for(i=num-1;i>=0;i--){
1721 //スタックへプッシュ
1722 i3=NumOpe(Parms[i],0,0,0);
1723
1724 switch(types[i]){
1725 case DEF_INT64:
1726 case DEF_QWORD:
1727 ChangeTypeToInt64(i3);
1728 break;
1729 case DEF_SINGLE:
1730 ChangeTypeToSingle(i3);
1731 break;
1732 case DEF_DOUBLE:
1733 ChangeTypeToDouble(i3);
1734 break;
1735
1736 default:
1737 ChangeTypeToLong(i3);
1738 break;
1739 }
1740
1741 ParmSize+=GetTypeSize(types[i],0);
1742
1743 HeapDefaultFree(Parms[i]);
1744 }
1745
1746 i3=NumOpe(szFuncPtr,0,0,0);
1747 ChangeTypeToLong(i3);
1748
1749 //pop eax
1750 op_pop(REG_EAX);
1751
1752 //call eax
1753 OpBuffer[obp++]=(char)0xFF;
1754 OpBuffer[obp++]=(char)0xD0;
1755
1756 if(bCdecl){
1757 //スタックを戻す
1758
1759 //add esp,ParmSize
1760 op_add_esp(ParmSize);
1761 }
1762}
1763
1764void OpcodeSetPtrData(char *Parameter,int type){
1765 int i,i2;
1766 char temporary[VN_SIZE];
1767
1768 if(Parameter[0]=='('){
1769 i=JumpStringInPare(Parameter,1);
1770 if(Parameter[i+1]=='\0'){
1771 for(i=0;;i++){
1772 Parameter[i]=Parameter[i+1];
1773 if(Parameter[i]=='\0') break;
1774 }
1775 Parameter[i-1]=0;
1776 }
1777 }
1778
1779 //第1パラメータを取得
1780 i=GetOneParameter(Parameter,0,temporary);
1781 if(!Parameter[i]){
1782 SetError(1,NULL,cp);
1783 return;
1784 }
1785
1786 i2=NumOpe(temporary,0,0,0);
1787 ChangeTypeToLong(i2);
1788
1789 //第2パラメータを取得
1790 i=GetOneParameter(Parameter,i,temporary);
1791 if(Parameter[i]){
1792 SetError(1,NULL,cp);
1793 return;
1794 }
1795
1796 i2=NumOpe(temporary,0,0,0);
1797 if(type==DEF_DOUBLE){
1798 ChangeTypeToDouble_ToFpuReg(i2);
1799
1800 //pop eax
1801 op_pop(REG_EAX);
1802
1803 //fstp qword ptr[eax]
1804 OpBuffer[obp++]=(char)0xDD;
1805 OpBuffer[obp++]=(char)0x18;
1806 }
1807 else if(type==DEF_SINGLE){
1808 ChangeTypeToSingle(i2);
1809
1810 //pop ebx
1811 op_pop(REG_EBX);
1812
1813 //pop eax
1814 op_pop(REG_EAX);
1815
1816 //mov dword ptr[eax],ebx
1817 OpBuffer[obp++]=(char)0x89;
1818 OpBuffer[obp++]=(char)0x18;
1819 }
1820 else if(type==DEF_QWORD){
1821 ChangeTypeToInt64(i2);
1822
1823 //pop ecx
1824 op_pop(REG_ECX);
1825
1826 //pop ebx
1827 op_pop(REG_EBX);
1828
1829 //pop eax
1830 op_pop(REG_EAX);
1831
1832 //mov dword ptr[eax],ecx
1833 OpBuffer[obp++]=(char)0x89;
1834 OpBuffer[obp++]=(char)0x08;
1835
1836 //mov dword ptr[eax+sizeof(long)],ebx
1837 OpBuffer[obp++]=(char)0x89;
1838 OpBuffer[obp++]=(char)0x58;
1839 OpBuffer[obp++]=(char)0x04;
1840 }
1841 else if(type==DEF_DWORD){
1842 ChangeTypeToLong(i2);
1843
1844 //pop ebx
1845 op_pop(REG_EBX);
1846
1847 //pop eax
1848 op_pop(REG_EAX);
1849
1850 //mov dword ptr[eax],ebx
1851 OpBuffer[obp++]=(char)0x89;
1852 OpBuffer[obp++]=(char)0x18;
1853 }
1854 else if(type==DEF_WORD){
1855 ChangeTypeToLong(i2);
1856
1857 //pop ebx
1858 op_pop(REG_EBX);
1859
1860 //pop eax
1861 op_pop(REG_EAX);
1862
1863 //mov word ptr[eax],bx
1864 OpBuffer[obp++]=(char)0x66;
1865 OpBuffer[obp++]=(char)0x89;
1866 OpBuffer[obp++]=(char)0x18;
1867 }
1868 else if(type==DEF_BYTE){
1869 ChangeTypeToLong(i2);
1870
1871 //pop ebx
1872 op_pop(REG_EBX);
1873
1874 //pop eax
1875 op_pop(REG_EAX);
1876
1877 //mov byte ptr[eax],bl
1878 OpBuffer[obp++]=(char)0x88;
1879 OpBuffer[obp++]=(char)0x18;
1880 }
1881}
Note: See TracBrowser for help on using the repository browser.