source: dev/BasicCompiler_Common/Compile.cpp@ 78

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

CTypeDef → TypeDef
Houseクラスを追加。
オーバーロードレベルの種類を追加(レベル1に挿入)

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