source: dev/BasicCompiler_Common/Compile.cpp@ 16

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

グローバル領域外のConst定義を初期段階で収集しないようにしました。

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