source: dev/BasicCompiler_Common/Compile.cpp@ 89

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

実行時型情報の生成に対応。
関数の戻り値の型に抽象クラスを指定できるようにした。

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