source: dev/BasicCompiler32/Compile_Statement.cpp@ 14

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

Const変数の書き込み規制を有効化(グローバル/ローカル変数のみ)
定数オブジェクトと定数メンバは未実装。

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