source: dev/BasicCompiler_Common/Compile.cpp@ 17

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

定数メンバ機能を有効にした。

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