source: dev/BasicCompiler_Common/Compile.cpp@ 103

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

名前空間機能をグローバル変数、定数と列挙型に適用。
一部、クラスの静的メンバと名前空間の相性が悪いコードが潜んでいるため、要改修

File size: 16.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
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 Smoothie::Lexical::liveingNamespaceScopes.push_back( Command + 2 );
225 break;
226 case ESC_ENDNAMESPACE:
227 if( Smoothie::Lexical::liveingNamespaceScopes.size() <= 0 ){
228 SetError(12,"End Namespace",cp);
229 }
230 Smoothie::Lexical::liveingNamespaceScopes.pop_back();
231 break;
232
233 //Tryによる例外処理
234 case ESC_TRY:
235 Exception::TryCommand();
236 break;
237 case ESC_CATCH:
238 Exception::CatchCommand();
239 break;
240 case ESC_FINALLY:
241 Exception::FinallyCommand();
242 break;
243 case ESC_ENDTRY:
244 Exception::EndTryCommand();
245 break;
246 case ESC_THROW:
247 Exception::ThrowCommand( Command + 2 );
248 break;
249
250 default:
251 char temporary[64];
252 GetDefaultNameFromES(Command[1],temporary);
253 SetError(30,temporary,cp);
254 break;
255 }
256 return;
257 }
258 switch(MAKEWORD(Command[1],Command[0])){
259 case COM_DIM:
260 OpcodeDim(Command+2,0);
261 break;
262 case COM_DELETE:
263 OpcodeDelete(Command+2, false);
264 break;
265 case COM_SWEEPINGDELETE:
266 OpcodeDelete(Command+2, true);
267 break;
268
269 case COM_GOTO:
270 OpcodeGoto(Command+2);
271 break;
272 case COM_WHILE:
273 OpcodeWhile(Command+2);
274 break;
275 case COM_FOR:
276 OpcodeFor(Command+2);
277 break;
278 case COM_DO:
279 OpcodeDo(Command+2);
280 break;
281
282 case COM_GOSUB:
283 OpcodeGosub(Command+2);
284 break;
285 case COM_RETURN:
286 OpcodeReturn(Command+2);
287 break;
288
289 case COM_SETDOUBLE:
290 OpcodeSetPtrData(Command+2,DEF_DOUBLE);
291 break;
292 case COM_SETSINGLE:
293 OpcodeSetPtrData(Command+2,DEF_SINGLE);
294 break;
295 case COM_SETQWORD:
296 OpcodeSetPtrData(Command+2,DEF_QWORD);
297 break;
298 case COM_SETDWORD:
299 OpcodeSetPtrData(Command+2,DEF_DWORD);
300 break;
301 case COM_SETWORD:
302 OpcodeSetPtrData(Command+2,DEF_WORD);
303 break;
304 case COM_SETBYTE:
305 OpcodeSetPtrData(Command+2,DEF_BYTE);
306 break;
307
308 case COM_DEBUG:
309 extern BOOL bDebugCompile;
310 //int 3
311 if(bDebugCompile) OpBuffer[obp++]=(char)0xCC;
312#if defined(_DEBUG)
313 else OpBuffer[obp++]=(char)0xCC;
314#endif
315 break;
316
317 case COM_LET:
318 OpcodeCalc(Command+2);
319 break;
320 default:
321 OpcodeOthers(Command);
322 break;
323 }
324}
325
326void GetGlobalDataForDll(void){
327 extern char *basbuf;
328 extern HANDLE hHeap;
329 int i2,BufferSize;
330 char *Command;
331 DWORD dwRetCode;
332
333 dwRetCode=0;
334 BufferSize=128;
335 Command=(char *)HeapAlloc(hHeap,0,BufferSize);
336 for(cp++,i2=0;;cp++,i2++){
337 if(i2>=BufferSize){
338 //バッファ領域が足りなくなった場合はバッファを増量する
339 BufferSize+=128;
340 Command=(char *)HeapReAlloc(hHeap,0,Command,BufferSize);
341 }
342 if(basbuf[cp]=='\"'){
343 Command[i2]=basbuf[cp];
344 for(cp++,i2++;;cp++,i2++){
345 if(i2>=BufferSize){
346 //バッファ領域が足りなくなった場合はバッファを増量する
347 BufferSize+=128;
348 Command=(char *)HeapReAlloc(hHeap,0,Command,BufferSize);
349 }
350 Command[i2]=basbuf[cp];
351 if(basbuf[cp]=='\"') break;
352 }
353 continue;
354 }
355 if(IsCommandDelimitation(basbuf[cp])){
356 Command[i2]=0;
357
358 if(Command[0]==1&&Command[1]==ESC_SUB){
359 i2=cp;
360 while(!(basbuf[cp]==1&&basbuf[cp+1]==ESC_ENDSUB)){
361 if(basbuf[cp]=='\0'){
362 SetError(22,"Sub",i2);
363 break;
364 }
365 cp++;
366 }
367 if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break;
368 cp+=2;
369 i2=-1;
370 continue;
371 }
372 if(Command[0]==1&&Command[1]==ESC_FUNCTION){
373 i2=cp;
374 while(!(basbuf[cp]==1&&basbuf[cp+1]==ESC_ENDFUNCTION)){
375 if(basbuf[cp]=='\0'){
376 SetError(22,"Function",i2);
377 break;
378 }
379 cp++;
380 }
381 if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break;
382 cp+=2;
383 i2=-1;
384 continue;
385 }
386 if(Command[0]==1&&Command[1]==ESC_MACRO){
387 i2=cp;
388 while(!(basbuf[cp]==1&&basbuf[cp+1]==ESC_ENDMACRO)){
389 if(basbuf[cp]=='\0'){
390 SetError(22,"Macro",i2);
391 break;
392 }
393 cp++;
394 }
395 if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break;
396 cp+=2;
397 i2=-1;
398 continue;
399 }
400 if(Command[0]==1&&Command[1]==ESC_TYPE){
401 i2=cp;
402 while(!(basbuf[cp]==1&&basbuf[cp+1]==ESC_ENDTYPE)){
403 if(basbuf[cp]=='\0'){
404 SetError(22,"Type",i2);
405 break;
406 }
407 cp++;
408 }
409 if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break;
410 cp+=2;
411 i2=-1;
412 continue;
413 }
414 if(Command[0]==1&&Command[1]==ESC_CLASS){
415 i2=cp;
416 while(!(basbuf[cp]==1&&basbuf[cp+1]==ESC_ENDCLASS)){
417 if(basbuf[cp]=='\0'){
418 SetError(22,"Class",i2);
419 break;
420 }
421 cp++;
422 }
423 if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break;
424 cp+=2;
425 i2=-1;
426 continue;
427 }
428 if(Command[0]==1&&Command[1]==ESC_INTERFACE){
429 i2=cp;
430 while(!(basbuf[cp]==1&&basbuf[cp+1]==ESC_ENDINTERFACE)){
431 if(basbuf[cp]=='\0'){
432 SetError(22,"Interface",i2);
433 break;
434 }
435 cp++;
436 }
437 if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break;
438 cp+=2;
439 i2=-1;
440 continue;
441 }
442
443 //DLLのグローバルデータに必要なコマンドだけ
444 if(MAKEWORD(Command[1],Command[0])==COM_DIM)
445 OpcodeDim(Command+2,0);
446
447 // ネイティブコードバッファの再確保
448 ReallocNativeCodeBuffer();
449
450 if(basbuf[cp]=='\0') break;
451 i2=-1;
452 continue;
453 }
454 Command[i2]=basbuf[cp];
455 }
456 HeapDefaultFree(Command);
457}
458DWORD CompileBuffer(char Return_Sequence,WORD Return_Command){
459 extern char *basbuf;
460 extern HANDLE hHeap;
461 int i,i2,i3,i4,BufferSize,ScopeStart;
462 char *Command,temporary[VN_SIZE],*temp2,temp3[32];
463 DWORD dwRetCode;
464
465 ScopeStart=cp;
466
467 dwRetCode=0;
468 BufferSize=128;
469 Command=(char *)HeapAlloc(hHeap,0,BufferSize);
470
471 for(cp++,i2=0;;cp++,i2++){
472 if(i2>=BufferSize){
473 //バッファ領域が足りなくなった場合はバッファを増量する
474 BufferSize+=128;
475 Command=(char *)HeapReAlloc(hHeap,0,Command,BufferSize);
476 }
477 if(basbuf[cp]=='\"'){
478 Command[i2]=basbuf[cp];
479 for(cp++,i2++;;cp++,i2++){
480 if(i2>=BufferSize){
481 //バッファ領域が足りなくなった場合はバッファを増量する
482 BufferSize+=128;
483 Command=(char *)HeapReAlloc(hHeap,0,Command,BufferSize);
484 }
485 Command[i2]=basbuf[cp];
486 if(basbuf[cp]=='\"') break;
487 }
488 continue;
489 }
490 if(IsCommandDelimitation(basbuf[cp])){
491 Command[i2]=0;
492
493 if(Command[0]==1&&Command[1]==ESC_LINENUM){
494 for(i=2,i2=0;;i++,i2++){
495 if(Command[i]==','){
496 temporary[i2]=0;
497 break;
498 }
499 temporary[i2]=Command[i];
500 }
501 i3=atoi(temporary);
502 i4=i+1;
503
504 //Goto先ラベル
505 pLabelNames=(LABEL *)HeapReAlloc(hHeap,0,pLabelNames,(MaxLabelNum+1)*sizeof(LABEL));
506 pLabelNames[MaxLabelNum].pName=0;
507 pLabelNames[MaxLabelNum].line=i3;
508 pLabelNames[MaxLabelNum].address=obp;
509 MaxLabelNum++;
510
511 //書き込みスケジュール
512 for(i=0;i<GotoLabelScheduleNum;i++){
513 if(pGotoLabelSchedule[i].pName==0&&
514 pGotoLabelSchedule[i].line==i3){
515 *((long *)(OpBuffer+pGotoLabelSchedule[i].pos))=obp-(pGotoLabelSchedule[i].pos+sizeof(long));
516
517 //詰める
518 GotoLabelScheduleNum--;
519 for(i2=i;i2<GotoLabelScheduleNum;i2++){
520 pGotoLabelSchedule[i2].pName=pGotoLabelSchedule[i2+1].pName;
521 pGotoLabelSchedule[i2].line=pGotoLabelSchedule[i2+1].line;
522 pGotoLabelSchedule[i2].pos=pGotoLabelSchedule[i2+1].pos;
523 }
524 i--;
525 }
526 }
527
528 temp2=(char *)HeapAlloc(hHeap,0,lstrlen(Command+i4)+1);
529 lstrcpy(temp2,Command+i4);
530 lstrcpy(Command,temp2);
531 HeapDefaultFree(temp2);
532 }
533
534 if(Command[0]==1&&
535 (((Command[1]==ESC_VIRTUAL||Command[1]==ESC_OVERRIDE)&&Command[2]==1&&(Command[3]==ESC_SUB||Command[3]==ESC_FUNCTION))||
536 Command[1]==ESC_SUB||
537 Command[1]==ESC_FUNCTION||
538 Command[1]==ESC_MACRO||
539 Command[1]==ESC_TYPE||
540 Command[1]==ESC_CLASS||
541 Command[1]==ESC_INTERFACE||
542 Command[1]==ESC_ENUM||
543 (Command[1]==ESC_CONST&&Command[2]==1&&Command[3]==ESC_ENUM)
544 )
545 ){
546 if(Command[1]==ESC_VIRTUAL||Command[1]==ESC_OVERRIDE||Command[1]==ESC_CONST){
547 GetDefaultNameFromES(Command[3],temporary);
548 }
549 else{
550 GetDefaultNameFromES(Command[1],temporary);
551 }
552 if(Return_Sequence){
553 SetError(12,temporary,cp);
554 break;
555 }
556
557 if(Command[1]==ESC_CONST) i3=GetEndXXXCommand(Command[3]);
558 else i3=GetEndXXXCommand(Command[1]);
559 for(i2=cp;;cp++){
560 if(basbuf[cp]==1){
561 if(basbuf[cp+1]==i3) break;
562 if(Command[1]==ESC_CLASS||Command[1]==ESC_INTERFACE){
563 //クラス、インターフェイスではSub、Functionの定義を可能にしておく
564 if(basbuf[cp+1]==ESC_MACRO||
565 basbuf[cp+1]==ESC_TYPE||
566 basbuf[cp+1]==ESC_CLASS||
567 basbuf[cp+1]==ESC_INTERFACE||
568 basbuf[cp+1]==ESC_ENUM){
569 GetDefaultNameFromES(basbuf[cp+1],temp3);
570 SetError(12,temp3,cp);
571 }
572 }
573 else{
574 if(basbuf[cp-1]!='*'&&(
575 basbuf[cp+1]==ESC_VIRTUAL||
576 basbuf[cp+1]==ESC_OVERRIDE||
577 basbuf[cp+1]==ESC_SUB||
578 basbuf[cp+1]==ESC_FUNCTION||
579 basbuf[cp+1]==ESC_MACRO||
580 basbuf[cp+1]==ESC_TYPE||
581 basbuf[cp+1]==ESC_CLASS||
582 basbuf[cp+1]==ESC_INTERFACE||
583 basbuf[cp+1]==ESC_ENUM)){
584 GetDefaultNameFromES(basbuf[cp+1],temp3);
585 SetError(12,temp3,cp);
586 }
587 }
588 }
589 if(basbuf[cp]=='\0'){
590 //error
591 //既にエラー発行済みのため、何もせずに抜ける
592 break;
593 }
594 }
595 if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break;
596 cp+=2;
597 i2=-1;
598 continue;
599 }
600
601 if(Command[0]==0x10||Command[0]==0x11){
602 //Wend、Next、Loopなど
603 if(Return_Command==MAKEWORD(Command[1],Command[0])){
604 if(Return_Command==COM_NEXT){
605 //Nextの場合は、パラメータ(省略化)の整合性を判断する必要がある(OpcodeFor関数を参照)
606 extern char szNextVariable[VN_SIZE];
607 if(Command[2]) lstrcpy(szNextVariable,Command+2);
608 else szNextVariable[0]=0;
609 }
610 break;
611 }
612 }
613
614 NextLine();
615
616 if(Command[0]==1){
617 if(Return_Sequence==ESC_ENDIF&&Command[1]==ESC_ELSE){
618 dwRetCode=ESC_ELSE;
619 break;
620 }
621
622 if(Command[1]==Return_Sequence){
623 dwRetCode=Command[1];
624 break;
625 }
626 }
627
628 ChangeOpcode(Command);
629
630#ifdef _DEBUG
631 epi_check();
632#endif
633
634 //コンパイルを中断するとき
635 extern BOOL bStopCompile;
636 if(bStopCompile) return 0;
637
638 if(obp_AllocSize<obp+8192){
639 obp_AllocSize+=8192;
640 OpBuffer=(char *)HeapReAlloc(hHeap,0,OpBuffer,obp_AllocSize);
641 }
642
643 if(basbuf[cp]=='\0'){
644 switch(Return_Command){
645 case COM_WEND:
646 SetError(4,"\"While\" - \"Wend\" ",ScopeStart);
647 break;
648 case COM_NEXT:
649 SetError(4,"\"For\" - \"Next\" ",ScopeStart);
650 break;
651 case COM_LOOP:
652 SetError(4,"\"Do\" - \"Loop\" ",ScopeStart);
653 break;
654 }
655 switch(Return_Sequence){
656 case ESC_ENDSUB:
657 SetError(4,"\"Sub\" - \"End Sub\" ",ScopeStart);
658 break;
659 case ESC_ENDFUNCTION:
660 SetError(4,"\"Function\" - \"End Function\" ",ScopeStart);
661 break;
662 case ESC_ENDMACRO:
663 SetError(4,"\"Macro\" - \"End Macro\" ",ScopeStart);
664 break;
665 case ESC_ENDIF:
666 SetError(22,"If",ScopeStart);
667 break;
668 }
669 break;
670 }
671 i2=-1;
672 continue;
673 }
674 Command[i2]=basbuf[cp];
675 }
676 HeapDefaultFree(Command);
677
678 return dwRetCode;
679}
Note: See TracBrowser for help on using the repository browser.