source: dev/BasicCompiler_Common/Compile.cpp@ 5

Last change on this file since 5 was 5, checked in by dai_9181, 17 years ago
File size: 14.5 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2
3#ifdef _AMD64_
4#include "../BasicCompiler64/opcode.h"
5#else
6#include "../BasicCompiler32/opcode.h"
7#endif
8
9int obp,obp_AllocSize;
10int GlobalOpBufferSize;
11char *OpBuffer;
12
13//ラベルアドレス
14LABEL *pLabelNames;
15int MaxLabelNum;
16
17//ループごとのスケジュール
18DWORD *pExitWhileSchedule; //ExitWhileスケジュール
19int ExitWhileScheduleNum;
20DWORD *pExitForSchedule; //ExitForスケジュール
21int ExitForScheduleNum;
22DWORD *pExitDoSchedule; //ExitDoスケジュール
23int ExitDoScheduleNum;
24
25//Continueアドレス
26DWORD dwContinueAddress;
27
28//Caseスケジュール
29DWORD *pCaseSchedule;
30int CaseScheduleNum;
31int NowCaseSchedule;
32
33//プロシージャ抜け出しスケジュール(Exit Sub/Function)
34DWORD *pExitSubSchedule;
35int ExitSubScheduleNum;
36
37//Goto未知ラベル スケジュール
38GOTOLABELSCHEDULE *pGotoLabelSchedule;
39int GotoLabelScheduleNum;
40
41//データ テーブル
42char *DataTable;
43int DataTableSize;
44
45//グローバル変数初期バッファ
46BYTE *initGlobalBuf;
47
48//With情報
49WITHINFO WithInfo;
50
51
52void NextLine(void){
53 extern HANDLE hHeap;
54 extern int MaxLineInfoNum;
55 extern LINEINFO *pLineInfo;
56 if(MaxLineInfoNum){
57 if(pLineInfo[MaxLineInfoNum-1].TopObp==obp){
58 pLineInfo[MaxLineInfoNum-1].TopCp=cp;
59 return;
60 }
61 }
62 pLineInfo=(LINEINFO *)HeapReAlloc(hHeap,0,pLineInfo,(MaxLineInfoNum+1)*sizeof(LINEINFO));
63 pLineInfo[MaxLineInfoNum].TopCp=cp;
64 pLineInfo[MaxLineInfoNum].TopObp=obp;
65
66 extern BOOL bDebugSupportProc;
67 extern BOOL bSystemProc;
68 pLineInfo[MaxLineInfoNum].dwCodeType=0;
69 if(bDebugSupportProc)
70 pLineInfo[MaxLineInfoNum].dwCodeType|=CODETYPE_DEBUGPROC;
71 if(bSystemProc)
72 pLineInfo[MaxLineInfoNum].dwCodeType|=CODETYPE_SYSTEMPROC;
73
74 MaxLineInfoNum++;
75}
76
77void ChangeOpcode(char *Command){
78 extern HANDLE hHeap;
79 int i,i2;
80
81 if(Command[0]=='\0') return;
82 if(Command[0]=='*'&&IsVariableTopChar(Command[1])){
83 //Goto先ラベル
84 pLabelNames=(LABEL *)HeapReAlloc(hHeap,0,pLabelNames,(MaxLabelNum+1)*sizeof(LABEL));
85 pLabelNames[MaxLabelNum].pName=(char *)HeapAlloc(hHeap,0,lstrlen(Command+1)+1);
86 lstrcpy(pLabelNames[MaxLabelNum].pName,Command+1);
87 pLabelNames[MaxLabelNum].address=obp;
88 MaxLabelNum++;
89
90 //書き込みスケジュール
91 for(i=0;i<GotoLabelScheduleNum;i++){
92 if(lstrcmp(pGotoLabelSchedule[i].pName,Command+1)==0){
93 *((long *)(OpBuffer+pGotoLabelSchedule[i].pos))=obp-(pGotoLabelSchedule[i].pos+sizeof(long));
94
95 HeapDefaultFree(pGotoLabelSchedule[i].pName);
96
97 //詰める
98 GotoLabelScheduleNum--;
99 for(i2=i;i2<GotoLabelScheduleNum;i2++){
100 pGotoLabelSchedule[i2].pName=pGotoLabelSchedule[i2+1].pName;
101 pGotoLabelSchedule[i2].line=pGotoLabelSchedule[i2+1].line;
102 pGotoLabelSchedule[i2].pos=pGotoLabelSchedule[i2+1].pos;
103 }
104 i--;
105 continue;
106 }
107 }
108 return;
109 }
110 if(Command[0]==1){
111 switch(Command[1]){
112 case ESC_CONST:
113 case ESC_TYPEDEF:
114 break;
115
116 case ESC_STATIC:
117 OpcodeDim(Command+2,DIMFLAG_STATIC);
118 break;
119
120 case ESC_IF:
121 OpcodeIf(Command+2);
122 break;
123 case ESC_EXITWHILE:
124 OpcodeExitWhile();
125 break;
126 case ESC_EXITFOR:
127 OpcodeExitFor();
128 break;
129 case ESC_EXITDO:
130 OpcodeExitDo();
131 break;
132 case ESC_CONTINUE:
133 OpcodeContinue();
134 break;
135
136 case ESC_EXITSUB:
137 case ESC_EXITFUNCTION:
138 case ESC_EXITMACRO:
139 OpcodeExitSub();
140 break;
141
142 case ESC_SELECTCASE:
143 OpcodeSelect(Command+2);
144 break;
145 case ESC_CASE:
146 case ESC_CASEELSE:
147 OpcodeCase(Command+2);
148 break;
149
150 case ESC_WITH:
151 extern WITHINFO WithInfo;
152
153 WithInfo.ppName=(char **)HeapReAlloc(hHeap,0,WithInfo.ppName,(WithInfo.num+1)*sizeof(char **));
154 WithInfo.ppName[WithInfo.num]=(char *)HeapAlloc(hHeap,0,lstrlen(Command+2)+1);
155 lstrcpy(WithInfo.ppName[WithInfo.num],Command+2);
156
157 WithInfo.pWithCp=(int *)HeapReAlloc(hHeap,0,WithInfo.pWithCp,(WithInfo.num+1)*sizeof(int));
158 WithInfo.pWithCp[WithInfo.num]=cp;
159
160 WithInfo.num++;
161 break;
162 case ESC_ENDWITH:
163 if(WithInfo.num<=0){
164 SetError(12,"End With",cp);
165 return;
166 }
167 WithInfo.num--;
168 HeapDefaultFree(WithInfo.ppName[WithInfo.num]);
169 break;
170 case ESC_DECLARE:
171 break;
172 default:
173 char temporary[64];
174 GetDefaultNameFromES(Command[1],temporary);
175 SetError(30,temporary,cp);
176 break;
177 }
178 return;
179 }
180 switch(MAKEWORD(Command[1],Command[0])){
181 case COM_DIM:
182 OpcodeDim(Command+2,0);
183 break;
184 case COM_DELETE:
185 OpcodeDelete(Command+2);
186 break;
187
188 case COM_GOTO:
189 OpcodeGoto(Command+2);
190 break;
191 case COM_WHILE:
192 OpcodeWhile(Command+2);
193 break;
194 case COM_FOR:
195 OpcodeFor(Command+2);
196 break;
197 case COM_DO:
198 OpcodeDo(Command+2);
199 break;
200
201 case COM_GOSUB:
202 OpcodeGosub(Command+2);
203 break;
204 case COM_RETURN:
205 OpcodeReturn(Command+2);
206 break;
207
208 case COM_SETDOUBLE:
209 OpcodeSetPtrData(Command+2,DEF_DOUBLE);
210 break;
211 case COM_SETSINGLE:
212 OpcodeSetPtrData(Command+2,DEF_SINGLE);
213 break;
214 case COM_SETQWORD:
215 OpcodeSetPtrData(Command+2,DEF_QWORD);
216 break;
217 case COM_SETDWORD:
218 OpcodeSetPtrData(Command+2,DEF_DWORD);
219 break;
220 case COM_SETWORD:
221 OpcodeSetPtrData(Command+2,DEF_WORD);
222 break;
223 case COM_SETBYTE:
224 OpcodeSetPtrData(Command+2,DEF_BYTE);
225 break;
226
227 case COM_DEBUG:
228 extern BOOL bDebugCompile;
229 //int 3
230 if(bDebugCompile) OpBuffer[obp++]=(char)0xCC;
231#if defined(_DEBUG)
232 else OpBuffer[obp++]=(char)0xCC;
233#endif
234 break;
235
236 case COM_LET:
237 OpcodeCalc(Command+2);
238 break;
239 default:
240 OpcodeOthers(Command);
241 break;
242 }
243}
244
245void GetGlobalDataForDll(void){
246 extern char *basbuf;
247 extern HANDLE hHeap;
248 int i2,BufferSize;
249 char *Command;
250 DWORD dwRetCode;
251
252 dwRetCode=0;
253 BufferSize=128;
254 Command=(char *)HeapAlloc(hHeap,0,BufferSize);
255 for(cp++,i2=0;;cp++,i2++){
256 if(i2>=BufferSize){
257 //バッファ領域が足りなくなった場合はバッファを増量する
258 BufferSize+=128;
259 Command=(char *)HeapReAlloc(hHeap,0,Command,BufferSize);
260 }
261 if(basbuf[cp]=='\"'){
262 Command[i2]=basbuf[cp];
263 for(cp++,i2++;;cp++,i2++){
264 if(i2>=BufferSize){
265 //バッファ領域が足りなくなった場合はバッファを増量する
266 BufferSize+=128;
267 Command=(char *)HeapReAlloc(hHeap,0,Command,BufferSize);
268 }
269 Command[i2]=basbuf[cp];
270 if(basbuf[cp]=='\"') break;
271 }
272 continue;
273 }
274 if(IsCommandDelimitation(basbuf[cp])){
275 Command[i2]=0;
276
277 if(Command[0]==1&&Command[1]==ESC_SUB){
278 i2=cp;
279 while(!(basbuf[cp]==1&&basbuf[cp+1]==ESC_ENDSUB)){
280 if(basbuf[cp]=='\0'){
281 SetError(22,"Sub",i2);
282 break;
283 }
284 cp++;
285 }
286 if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break;
287 cp+=2;
288 i2=-1;
289 continue;
290 }
291 if(Command[0]==1&&Command[1]==ESC_FUNCTION){
292 i2=cp;
293 while(!(basbuf[cp]==1&&basbuf[cp+1]==ESC_ENDFUNCTION)){
294 if(basbuf[cp]=='\0'){
295 SetError(22,"Function",i2);
296 break;
297 }
298 cp++;
299 }
300 if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break;
301 cp+=2;
302 i2=-1;
303 continue;
304 }
305 if(Command[0]==1&&Command[1]==ESC_MACRO){
306 i2=cp;
307 while(!(basbuf[cp]==1&&basbuf[cp+1]==ESC_ENDMACRO)){
308 if(basbuf[cp]=='\0'){
309 SetError(22,"Macro",i2);
310 break;
311 }
312 cp++;
313 }
314 if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break;
315 cp+=2;
316 i2=-1;
317 continue;
318 }
319 if(Command[0]==1&&Command[1]==ESC_TYPE){
320 i2=cp;
321 while(!(basbuf[cp]==1&&basbuf[cp+1]==ESC_ENDTYPE)){
322 if(basbuf[cp]=='\0'){
323 SetError(22,"Type",i2);
324 break;
325 }
326 cp++;
327 }
328 if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break;
329 cp+=2;
330 i2=-1;
331 continue;
332 }
333 if(Command[0]==1&&Command[1]==ESC_CLASS){
334 i2=cp;
335 while(!(basbuf[cp]==1&&basbuf[cp+1]==ESC_ENDCLASS)){
336 if(basbuf[cp]=='\0'){
337 SetError(22,"Class",i2);
338 break;
339 }
340 cp++;
341 }
342 if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break;
343 cp+=2;
344 i2=-1;
345 continue;
346 }
347 if(Command[0]==1&&Command[1]==ESC_INTERFACE){
348 i2=cp;
349 while(!(basbuf[cp]==1&&basbuf[cp+1]==ESC_ENDINTERFACE)){
350 if(basbuf[cp]=='\0'){
351 SetError(22,"Interface",i2);
352 break;
353 }
354 cp++;
355 }
356 if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break;
357 cp+=2;
358 i2=-1;
359 continue;
360 }
361
362 //DLLのグローバルデータに必要なコマンドだけ
363 if(MAKEWORD(Command[1],Command[0])==COM_DIM)
364 OpcodeDim(Command+2,0);
365
366 if(obp_AllocSize<obp+8192){
367 obp_AllocSize+=8192;
368 OpBuffer=(char *)HeapReAlloc(hHeap,0,OpBuffer,obp_AllocSize);
369 }
370
371 if(basbuf[cp]=='\0') break;
372 i2=-1;
373 continue;
374 }
375 Command[i2]=basbuf[cp];
376 }
377 HeapDefaultFree(Command);
378}
379DWORD CompileBuffer(char Return_Sequence,WORD Return_Command){
380 extern char *basbuf;
381 extern HANDLE hHeap;
382 int i,i2,i3,i4,BufferSize,ScopeStart;
383 char *Command,temporary[VN_SIZE],*temp2,temp3[32];
384 DWORD dwRetCode;
385
386 ScopeStart=cp;
387
388 dwRetCode=0;
389 BufferSize=128;
390 Command=(char *)HeapAlloc(hHeap,0,BufferSize);
391 for(cp++,i2=0;;cp++,i2++){
392 if(i2>=BufferSize){
393 //バッファ領域が足りなくなった場合はバッファを増量する
394 BufferSize+=128;
395 Command=(char *)HeapReAlloc(hHeap,0,Command,BufferSize);
396 }
397 if(basbuf[cp]=='\"'){
398 Command[i2]=basbuf[cp];
399 for(cp++,i2++;;cp++,i2++){
400 if(i2>=BufferSize){
401 //バッファ領域が足りなくなった場合はバッファを増量する
402 BufferSize+=128;
403 Command=(char *)HeapReAlloc(hHeap,0,Command,BufferSize);
404 }
405 Command[i2]=basbuf[cp];
406 if(basbuf[cp]=='\"') break;
407 }
408 continue;
409 }
410 if(IsCommandDelimitation(basbuf[cp])){
411 Command[i2]=0;
412
413 if(Command[0]==1&&Command[1]==ESC_LINENUM){
414 for(i=2,i2=0;;i++,i2++){
415 if(Command[i]==','){
416 temporary[i2]=0;
417 break;
418 }
419 temporary[i2]=Command[i];
420 }
421 i3=atoi(temporary);
422 i4=i+1;
423
424 //Goto先ラベル
425 pLabelNames=(LABEL *)HeapReAlloc(hHeap,0,pLabelNames,(MaxLabelNum+1)*sizeof(LABEL));
426 pLabelNames[MaxLabelNum].pName=0;
427 pLabelNames[MaxLabelNum].line=i3;
428 pLabelNames[MaxLabelNum].address=obp;
429 MaxLabelNum++;
430
431 //書き込みスケジュール
432 for(i=0;i<GotoLabelScheduleNum;i++){
433 if(pGotoLabelSchedule[i].pName==0&&
434 pGotoLabelSchedule[i].line==i3){
435 *((long *)(OpBuffer+pGotoLabelSchedule[i].pos))=obp-(pGotoLabelSchedule[i].pos+sizeof(long));
436
437 //詰める
438 GotoLabelScheduleNum--;
439 for(i2=i;i2<GotoLabelScheduleNum;i2++){
440 pGotoLabelSchedule[i2].pName=pGotoLabelSchedule[i2+1].pName;
441 pGotoLabelSchedule[i2].line=pGotoLabelSchedule[i2+1].line;
442 pGotoLabelSchedule[i2].pos=pGotoLabelSchedule[i2+1].pos;
443 }
444 i--;
445 }
446 }
447
448 temp2=(char *)HeapAlloc(hHeap,0,lstrlen(Command+i4)+1);
449 lstrcpy(temp2,Command+i4);
450 lstrcpy(Command,temp2);
451 HeapDefaultFree(temp2);
452 }
453
454 if(Command[0]==1&&
455 (((Command[1]==ESC_VIRTUAL||Command[1]==ESC_OVERRIDE)&&Command[2]==1&&(Command[3]==ESC_SUB||Command[3]==ESC_FUNCTION))||
456 Command[1]==ESC_SUB||
457 Command[1]==ESC_FUNCTION||
458 Command[1]==ESC_MACRO||
459 Command[1]==ESC_TYPE||
460 Command[1]==ESC_CLASS||
461 Command[1]==ESC_INTERFACE||
462 Command[1]==ESC_ENUM||
463 (Command[1]==ESC_CONST&&Command[2]==1&&Command[3]==ESC_ENUM)
464 )
465 ){
466 if(Command[1]==ESC_VIRTUAL||Command[1]==ESC_OVERRIDE||Command[1]==ESC_CONST){
467 GetDefaultNameFromES(Command[3],temporary);
468 }
469 else{
470 GetDefaultNameFromES(Command[1],temporary);
471 }
472 if(Return_Sequence){
473 SetError(12,temporary,cp);
474 break;
475 }
476
477 if(Command[1]==ESC_CONST) i3=GetEndXXXCommand(Command[3]);
478 else i3=GetEndXXXCommand(Command[1]);
479 for(i2=cp;;cp++){
480 if(basbuf[cp]==1){
481 if(basbuf[cp+1]==i3) break;
482 if(Command[1]==ESC_CLASS||Command[1]==ESC_INTERFACE){
483 //クラス、インターフェイスではSub、Functionの定義を可能にしておく
484 if(basbuf[cp+1]==ESC_MACRO||
485 basbuf[cp+1]==ESC_TYPE||
486 basbuf[cp+1]==ESC_CLASS||
487 basbuf[cp+1]==ESC_INTERFACE||
488 basbuf[cp+1]==ESC_ENUM){
489 GetDefaultNameFromES(basbuf[cp+1],temp3);
490 SetError(12,temp3,cp);
491 }
492 }
493 else{
494 if(basbuf[cp-1]!='*'&&(
495 basbuf[cp+1]==ESC_VIRTUAL||
496 basbuf[cp+1]==ESC_OVERRIDE||
497 basbuf[cp+1]==ESC_SUB||
498 basbuf[cp+1]==ESC_FUNCTION||
499 basbuf[cp+1]==ESC_MACRO||
500 basbuf[cp+1]==ESC_TYPE||
501 basbuf[cp+1]==ESC_CLASS||
502 basbuf[cp+1]==ESC_INTERFACE||
503 basbuf[cp+1]==ESC_ENUM)){
504 GetDefaultNameFromES(basbuf[cp+1],temp3);
505 SetError(12,temp3,cp);
506 }
507 }
508 }
509 if(basbuf[cp]=='\0'){
510 //error
511 //既にエラー発行済みのため、何もせずに抜ける
512 break;
513 }
514 }
515 if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break;
516 cp+=2;
517 i2=-1;
518 continue;
519 }
520
521 if(Command[0]==0x10||Command[0]==0x11){
522 //Wend、Next、Loopなど
523 if(Return_Command==MAKEWORD(Command[1],Command[0])){
524 if(Return_Command==COM_NEXT){
525 //Nextの場合は、パラメータ(省略化)の整合性を判断する必要がある(OpcodeFor関数を参照)
526 extern char szNextVariable[VN_SIZE];
527 if(Command[2]) lstrcpy(szNextVariable,Command+2);
528 else szNextVariable[0]=0;
529 }
530 break;
531 }
532 }
533
534 NextLine();
535
536 if(Command[0]==1){
537 if(Return_Sequence==ESC_ENDIF&&Command[1]==ESC_ELSE){
538 dwRetCode=ESC_ELSE;
539 break;
540 }
541
542 if(Command[1]==Return_Sequence){
543 dwRetCode=Command[1];
544 break;
545 }
546 }
547
548 ChangeOpcode(Command);
549
550#ifdef _DEBUG
551 epi_check();
552#endif
553
554 //コンパイルを中断するとき
555 extern BOOL bStopCompile;
556 if(bStopCompile) return 0;
557
558 if(obp_AllocSize<obp+8192){
559 obp_AllocSize+=8192;
560 OpBuffer=(char *)HeapReAlloc(hHeap,0,OpBuffer,obp_AllocSize);
561 }
562
563 if(basbuf[cp]=='\0'){
564 switch(Return_Command){
565 case COM_WEND:
566 SetError(4,"\"While\" - \"Wend\" ",ScopeStart);
567 break;
568 case COM_NEXT:
569 SetError(4,"\"For\" - \"Next\" ",ScopeStart);
570 break;
571 case COM_LOOP:
572 SetError(4,"\"Do\" - \"Loop\" ",ScopeStart);
573 break;
574 }
575 switch(Return_Sequence){
576 case ESC_ENDSUB:
577 SetError(4,"\"Sub\" - \"End Sub\" ",ScopeStart);
578 break;
579 case ESC_ENDFUNCTION:
580 SetError(4,"\"Function\" - \"End Function\" ",ScopeStart);
581 break;
582 case ESC_ENDMACRO:
583 SetError(4,"\"Macro\" - \"End Macro\" ",ScopeStart);
584 break;
585 case ESC_ENDIF:
586 SetError(22,"If",ScopeStart);
587 break;
588 }
589 break;
590 }
591 i2=-1;
592 continue;
593 }
594 Command[i2]=basbuf[cp];
595 }
596 HeapDefaultFree(Command);
597
598 return dwRetCode;
599}
Note: See TracBrowser for help on using the repository browser.