source: dev/BasicCompiler_Common/Compile.cpp@ 107

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

Importsステートメントを導入した。実装は作り途中。

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