source: dev/BasicCompiler_Common/Compile.cpp@ 64

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

すべてのオブジェクトを参照型に切り替えた。

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