source: dev/BasicCompiler_Common/Compile.cpp@ 56

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

・[Unicode]リテラル文字列のスイッチング
・[Unicode]Char型を文字型として扱うようにする
・[Unicode]SByte型を追加する
に対応。

/unicodeコマンドオプションに対応。

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