source: dev/BasicCompiler_Common/Compile.cpp@ 99

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

Namespaceステートメントのエスケープシーケンス化を行った。
[IDE]バックアップに失敗したときにエラーメッセージを出さないようにした。

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