source: dev/BasicCompiler_Common/Compile.cpp@ 7

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

Constステートメントで定数変数を宣言できるように改良。

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 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 for(cp++,i2=0;;cp++,i2++){
395 if(i2>=BufferSize){
396 //バッファ領域が足りなくなった場合はバッファを増量する
397 BufferSize+=128;
398 Command=(char *)HeapReAlloc(hHeap,0,Command,BufferSize);
399 }
400 if(basbuf[cp]=='\"'){
401 Command[i2]=basbuf[cp];
402 for(cp++,i2++;;cp++,i2++){
403 if(i2>=BufferSize){
404 //バッファ領域が足りなくなった場合はバッファを増量する
405 BufferSize+=128;
406 Command=(char *)HeapReAlloc(hHeap,0,Command,BufferSize);
407 }
408 Command[i2]=basbuf[cp];
409 if(basbuf[cp]=='\"') break;
410 }
411 continue;
412 }
413 if(IsCommandDelimitation(basbuf[cp])){
414 Command[i2]=0;
415
416 if(Command[0]==1&&Command[1]==ESC_LINENUM){
417 for(i=2,i2=0;;i++,i2++){
418 if(Command[i]==','){
419 temporary[i2]=0;
420 break;
421 }
422 temporary[i2]=Command[i];
423 }
424 i3=atoi(temporary);
425 i4=i+1;
426
427 //Goto先ラベル
428 pLabelNames=(LABEL *)HeapReAlloc(hHeap,0,pLabelNames,(MaxLabelNum+1)*sizeof(LABEL));
429 pLabelNames[MaxLabelNum].pName=0;
430 pLabelNames[MaxLabelNum].line=i3;
431 pLabelNames[MaxLabelNum].address=obp;
432 MaxLabelNum++;
433
434 //書き込みスケジュール
435 for(i=0;i<GotoLabelScheduleNum;i++){
436 if(pGotoLabelSchedule[i].pName==0&&
437 pGotoLabelSchedule[i].line==i3){
438 *((long *)(OpBuffer+pGotoLabelSchedule[i].pos))=obp-(pGotoLabelSchedule[i].pos+sizeof(long));
439
440 //詰める
441 GotoLabelScheduleNum--;
442 for(i2=i;i2<GotoLabelScheduleNum;i2++){
443 pGotoLabelSchedule[i2].pName=pGotoLabelSchedule[i2+1].pName;
444 pGotoLabelSchedule[i2].line=pGotoLabelSchedule[i2+1].line;
445 pGotoLabelSchedule[i2].pos=pGotoLabelSchedule[i2+1].pos;
446 }
447 i--;
448 }
449 }
450
451 temp2=(char *)HeapAlloc(hHeap,0,lstrlen(Command+i4)+1);
452 lstrcpy(temp2,Command+i4);
453 lstrcpy(Command,temp2);
454 HeapDefaultFree(temp2);
455 }
456
457 if(Command[0]==1&&
458 (((Command[1]==ESC_VIRTUAL||Command[1]==ESC_OVERRIDE)&&Command[2]==1&&(Command[3]==ESC_SUB||Command[3]==ESC_FUNCTION))||
459 Command[1]==ESC_SUB||
460 Command[1]==ESC_FUNCTION||
461 Command[1]==ESC_MACRO||
462 Command[1]==ESC_TYPE||
463 Command[1]==ESC_CLASS||
464 Command[1]==ESC_INTERFACE||
465 Command[1]==ESC_ENUM||
466 (Command[1]==ESC_CONST&&Command[2]==1&&Command[3]==ESC_ENUM)
467 )
468 ){
469 if(Command[1]==ESC_VIRTUAL||Command[1]==ESC_OVERRIDE||Command[1]==ESC_CONST){
470 GetDefaultNameFromES(Command[3],temporary);
471 }
472 else{
473 GetDefaultNameFromES(Command[1],temporary);
474 }
475 if(Return_Sequence){
476 SetError(12,temporary,cp);
477 break;
478 }
479
480 if(Command[1]==ESC_CONST) i3=GetEndXXXCommand(Command[3]);
481 else i3=GetEndXXXCommand(Command[1]);
482 for(i2=cp;;cp++){
483 if(basbuf[cp]==1){
484 if(basbuf[cp+1]==i3) break;
485 if(Command[1]==ESC_CLASS||Command[1]==ESC_INTERFACE){
486 //クラス、インターフェイスではSub、Functionの定義を可能にしておく
487 if(basbuf[cp+1]==ESC_MACRO||
488 basbuf[cp+1]==ESC_TYPE||
489 basbuf[cp+1]==ESC_CLASS||
490 basbuf[cp+1]==ESC_INTERFACE||
491 basbuf[cp+1]==ESC_ENUM){
492 GetDefaultNameFromES(basbuf[cp+1],temp3);
493 SetError(12,temp3,cp);
494 }
495 }
496 else{
497 if(basbuf[cp-1]!='*'&&(
498 basbuf[cp+1]==ESC_VIRTUAL||
499 basbuf[cp+1]==ESC_OVERRIDE||
500 basbuf[cp+1]==ESC_SUB||
501 basbuf[cp+1]==ESC_FUNCTION||
502 basbuf[cp+1]==ESC_MACRO||
503 basbuf[cp+1]==ESC_TYPE||
504 basbuf[cp+1]==ESC_CLASS||
505 basbuf[cp+1]==ESC_INTERFACE||
506 basbuf[cp+1]==ESC_ENUM)){
507 GetDefaultNameFromES(basbuf[cp+1],temp3);
508 SetError(12,temp3,cp);
509 }
510 }
511 }
512 if(basbuf[cp]=='\0'){
513 //error
514 //既にエラー発行済みのため、何もせずに抜ける
515 break;
516 }
517 }
518 if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break;
519 cp+=2;
520 i2=-1;
521 continue;
522 }
523
524 if(Command[0]==0x10||Command[0]==0x11){
525 //Wend、Next、Loopなど
526 if(Return_Command==MAKEWORD(Command[1],Command[0])){
527 if(Return_Command==COM_NEXT){
528 //Nextの場合は、パラメータ(省略化)の整合性を判断する必要がある(OpcodeFor関数を参照)
529 extern char szNextVariable[VN_SIZE];
530 if(Command[2]) lstrcpy(szNextVariable,Command+2);
531 else szNextVariable[0]=0;
532 }
533 break;
534 }
535 }
536
537 NextLine();
538
539 if(Command[0]==1){
540 if(Return_Sequence==ESC_ENDIF&&Command[1]==ESC_ELSE){
541 dwRetCode=ESC_ELSE;
542 break;
543 }
544
545 if(Command[1]==Return_Sequence){
546 dwRetCode=Command[1];
547 break;
548 }
549 }
550
551 ChangeOpcode(Command);
552
553#ifdef _DEBUG
554 epi_check();
555#endif
556
557 //コンパイルを中断するとき
558 extern BOOL bStopCompile;
559 if(bStopCompile) return 0;
560
561 if(obp_AllocSize<obp+8192){
562 obp_AllocSize+=8192;
563 OpBuffer=(char *)HeapReAlloc(hHeap,0,OpBuffer,obp_AllocSize);
564 }
565
566 if(basbuf[cp]=='\0'){
567 switch(Return_Command){
568 case COM_WEND:
569 SetError(4,"\"While\" - \"Wend\" ",ScopeStart);
570 break;
571 case COM_NEXT:
572 SetError(4,"\"For\" - \"Next\" ",ScopeStart);
573 break;
574 case COM_LOOP:
575 SetError(4,"\"Do\" - \"Loop\" ",ScopeStart);
576 break;
577 }
578 switch(Return_Sequence){
579 case ESC_ENDSUB:
580 SetError(4,"\"Sub\" - \"End Sub\" ",ScopeStart);
581 break;
582 case ESC_ENDFUNCTION:
583 SetError(4,"\"Function\" - \"End Function\" ",ScopeStart);
584 break;
585 case ESC_ENDMACRO:
586 SetError(4,"\"Macro\" - \"End Macro\" ",ScopeStart);
587 break;
588 case ESC_ENDIF:
589 SetError(22,"If",ScopeStart);
590 break;
591 }
592 break;
593 }
594 i2=-1;
595 continue;
596 }
597 Command[i2]=basbuf[cp];
598 }
599 HeapDefaultFree(Command);
600
601 return dwRetCode;
602}
Note: See TracBrowser for help on using the repository browser.