source: dev/BasicCompiler_Common/Compile.cpp@ 15

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

LexicalAnalysisを廃止。

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