source: dev/BasicCompiler_Common/Compile.cpp@ 26

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

実体オブジェクトを戻り値に持つ静的メソッドをクラス内から呼び出すと「パラメータが異なる」というエラーが出るバグを修正。
Exceptionに関するファイルを追加。

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