source: dev/trunk/abdev/BasicCompiler_Common/Compile.cpp@ 322

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

コンパイラ組み込みテンプレートエンジンを実装。
静的リンクライブラリ、デバッグ情報の内部形式をテキストからバイナリに変更した。

File size: 17.3 KB
Line 
1#include "stdafx.h"
2
3#include <jenga/include/smoothie/Smoothie.h>
4#include <jenga/include/smoothie/LexicalAnalysis.h>
5#include <jenga/include/smoothie/SmoothieException.h>
6
7#include <LexicalScope.h>
8#include <CodeGenerator.h>
9#include <Compiler.h>
10#include <NamespaceSupporter.h>
11
12#include "../BasicCompiler_Common/common.h"
13
14#ifdef _AMD64_
15#include "../BasicCompiler64/opcode.h"
16#else
17#include "../BasicCompiler32/opcode.h"
18#endif
19
20#include <Exception.h>
21
22//With情報
23WITHINFO WithInfo;
24
25//デバッグ用行番号情報
26SourceLines oldSourceLines;
27
28
29
30///////////////////////////////////////////////////
31// トークンを取得
32///////////////////////////////////////////////////
33void GetIdentifierToken( char *token, const char *source, int &pos )
34{
35 for( int i=0; ; i++, pos++ ){
36 if( ! IsVariableChar( source[pos] ) ){
37 token[i] = 0;
38 break;
39 }
40 token[i] = source[pos];
41 }
42}
43void GetCommandToken( char *token, const char *source, int &pos )
44{
45 for( int i=0; ; i++, pos++ ){
46 if( IsCommandDelimitation( source[pos] ) ){
47 token[i] = 0;
48 break;
49 }
50 token[i] = source[pos];
51 }
52}
53
54
55///////////////////////////////////////////////////
56// ジェネリクスのクラス型記述を分析
57///////////////////////////////////////////////////
58void SplitGenericClassInstance( const char *fullName, char *className, Jenga::Common::Strings &typeParameters )
59{
60 int i = 0;
61 typeParameters.clear();
62
63 //クラス名を取得
64 GetIdentifierToken( className, fullName, i );
65
66
67 /////////////////////////////////////////////////////////
68 // ☆★☆ ジェネリクスサポート ☆★☆
69 if( fullName[i] == '<' )
70 {
71 while( true )
72 {
73 i++;
74
75 // 型パラメータを取得
76 char temporary[VN_SIZE];
77 GetIdentifierToken( temporary, fullName, i );
78 if( temporary[0] == '\0' )
79 {
80 extern int cp;
81 SetError(1,NULL,cp);
82 }
83
84 typeParameters.push_back( temporary );
85
86 if( fullName[i] == ',' )
87 {
88 continue;
89 }
90 else if( fullName[i] == '>' )
91 {
92 break;
93 }
94 else
95 {
96 extern int cp;
97 SetError(1,NULL,cp);
98 }
99 }
100 }
101 /////////////////////////////////////////////////////////
102}
103
104
105///////////////////////////////////////////////////
106// 対になっているステートメントを飛び越す
107// ※グローバル領域用
108///////////////////////////////////////////////////
109int JumpStatement(const char *source, int &pos){
110 if( source[pos] != 1 ) return 0;
111
112 if( ! IsCommandDelimitation( source[pos - 1] ) ){
113 //直前がコマンド区切りではない場合
114 return 0;
115 }
116
117 char cStatement = source[pos + 1];
118
119 char cEnd = GetEndXXXCommand( cStatement );
120 if( cEnd == 0 ) return 0;
121
122 pos += 2;
123 while( ! ( source[pos] == 1 && source[pos + 1] == cEnd ) ){
124
125 if( source[pos] == '\0' ){
126 char temporary[64];
127 GetDefaultNameFromES( cStatement, temporary );
128 SetError( 22, temporary, pos );
129 return -1;
130 }
131
132 pos++;
133 }
134 if( ! ( source[pos] == '\0' || source[pos + 2] == '\0' ) ){
135 pos += 2;
136 }
137
138 return 1;
139}
140
141void ChangeOpcode(char *Command){
142 extern HANDLE hHeap;
143
144 if(Command[0]=='\0')
145 {
146 return;
147 }
148
149 trace_for_sourcecodestep( FormatEscapeSequenceStringToDefaultString(Command) );
150
151 if(Command[0]=='*'&&IsVariableTopChar(Command[1])){
152 //Goto先ラベル
153 compiler.codeGenerator.gotoLabels.push_back( GotoLabel( Command + 1, compiler.codeGenerator.GetNativeCodeSize() ) );
154
155 //書き込みスケジュール
156 GotoLabelSchedules::iterator it = compiler.codeGenerator.gotoLabelSchedules.begin();
157 while( it != compiler.codeGenerator.gotoLabelSchedules.end() )
158 {
159 if( (*it)->GetName() == Command+1 )
160 {
161 compiler.codeGenerator.opfix_JmpPertialSchedule( (*it) );
162
163 //詰める
164 it = compiler.codeGenerator.gotoLabelSchedules.erase( it );
165 }
166 else
167 {
168 it++;
169 }
170 }
171 return;
172 }
173 if(Command[0]==1){
174 switch(Command[1]){
175 case ESC_CONST:
176 OpcodeDim(Command+2, DIMFLAG_CONST);
177 break;
178
179 case ESC_TYPEDEF:
180 if( UserProc::IsLocalAreaCompiling() ){
181 // ローカル領域をコンパイルしているとき
182 SetError(65,"TypeDef",cp );
183 }
184
185 //既に収集済み
186 break;
187
188 case ESC_DELEGATE:
189 if( UserProc::IsLocalAreaCompiling() ){
190 // ローカル領域をコンパイルしているとき
191 SetError(65,"Delegate",cp );
192 }
193
194 //既に収集済み
195 break;
196
197 case ESC_STATIC:
198 OpcodeDim(Command+2,DIMFLAG_STATIC);
199 break;
200
201 case ESC_IF:
202 OpcodeIf(Command+2);
203 break;
204 case ESC_EXITWHILE:
205 {
206 LexicalScope *pScope = compiler.codeGenerator.lexicalScopes.SearchScope( LexicalScope::SCOPE_TYPE_WHILE );
207 if( !pScope ){
208 SetError(12,"Exit While",cp);
209 return;
210 }
211 pScope->Break();
212 }
213 break;
214 case ESC_EXITFOR:
215 {
216 LexicalScope *pScope = compiler.codeGenerator.lexicalScopes.SearchScope( LexicalScope::SCOPE_TYPE_FOR );
217 if( !pScope ){
218 SetError(12,"Exit For",cp);
219 return;
220 }
221 pScope->Break();
222 }
223 break;
224 case ESC_EXITDO:
225 {
226 LexicalScope *pScope = compiler.codeGenerator.lexicalScopes.SearchScope( LexicalScope::SCOPE_TYPE_DO );
227 if( !pScope ){
228 SetError(12,"Exit Do",cp);
229 return;
230 }
231 pScope->Break();
232 }
233 break;
234 case ESC_CONTINUE:
235 OpcodeContinue();
236 break;
237
238 case ESC_EXITSUB:
239 case ESC_EXITFUNCTION:
240 case ESC_EXITMACRO:
241 OpcodeExitSub();
242 break;
243
244 case ESC_SELECTCASE:
245 OpcodeSelect(Command+2);
246 break;
247 case ESC_CASE:
248 case ESC_CASEELSE:
249 OpcodeCase(Command+2);
250 break;
251
252 case ESC_WITH:
253 extern WITHINFO WithInfo;
254
255 WithInfo.ppName=(char **)HeapReAlloc(hHeap,0,WithInfo.ppName,(WithInfo.num+1)*sizeof(char **));
256 WithInfo.ppName[WithInfo.num]=(char *)HeapAlloc(hHeap,0,lstrlen(Command+2)+1);
257 lstrcpy(WithInfo.ppName[WithInfo.num],Command+2);
258
259 WithInfo.pWithCp=(int *)HeapReAlloc(hHeap,0,WithInfo.pWithCp,(WithInfo.num+1)*sizeof(int));
260 WithInfo.pWithCp[WithInfo.num]=cp;
261
262 WithInfo.num++;
263 break;
264 case ESC_ENDWITH:
265 if(WithInfo.num<=0){
266 SetError(12,"End With",cp);
267 return;
268 }
269 WithInfo.num--;
270 HeapDefaultFree(WithInfo.ppName[WithInfo.num]);
271 break;
272 case ESC_DECLARE:
273 if( UserProc::IsLocalAreaCompiling() ){
274 // ローカル領域をコンパイルしているとき
275 SetError(65,"Declare",cp );
276 }
277 break;
278
279 case ESC_NAMESPACE:
280 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes().push_back( Command + 2 );
281 break;
282 case ESC_ENDNAMESPACE:
283 if( compiler.GetNamespaceSupporter().GetLivingNamespaceScopes().size() <= 0 ){
284 SetError(12,"End Namespace",cp);
285 }
286 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes().pop_back();
287 break;
288 case ESC_IMPORTS:
289 compiler.GetNamespaceSupporter().ImportsNamespace( Command + 2 );
290 break;
291 case ESC_CLEARNAMESPACEIMPORTED:
292 compiler.GetNamespaceSupporter().GetImportedNamespaces().clear();
293 break;
294
295 //Tryによる例外処理
296 case ESC_TRY:
297 Exception::TryCommand();
298 break;
299 case ESC_CATCH:
300 Exception::CatchCommand();
301 break;
302 case ESC_FINALLY:
303 Exception::FinallyCommand();
304 break;
305 case ESC_ENDTRY:
306 Exception::EndTryCommand();
307 break;
308 case ESC_THROW:
309 Exception::ThrowCommand( Command + 2 );
310 break;
311
312 default:
313 char temporary[64];
314 GetDefaultNameFromES(Command[1],temporary);
315 SetError(30,temporary,cp);
316 break;
317 }
318 return;
319 }
320 switch(MAKEWORD(Command[1],Command[0])){
321 case COM_DIM:
322 OpcodeDim(Command+2,0);
323 break;
324 case COM_DELETE:
325 OpcodeDelete(Command+2, false);
326 break;
327 case COM_SWEEPINGDELETE:
328 OpcodeDelete(Command+2, true);
329 break;
330
331 case COM_GOTO:
332 OpcodeGoto(Command+2);
333 break;
334 case COM_WHILE:
335 OpcodeWhile(Command+2);
336 break;
337 case COM_FOR:
338 OpcodeFor(Command+2);
339 break;
340 case COM_DO:
341 OpcodeDo(Command+2);
342 break;
343
344 case COM_GOSUB:
345 OpcodeGosub(Command+2);
346 break;
347 case COM_RETURN:
348 OpcodeReturn(Command+2);
349 break;
350
351 case COM_SETDOUBLE:
352 OpcodeSetPtrData(Command+2,DEF_DOUBLE);
353 break;
354 case COM_SETSINGLE:
355 OpcodeSetPtrData(Command+2,DEF_SINGLE);
356 break;
357 case COM_SETQWORD:
358 OpcodeSetPtrData(Command+2,DEF_QWORD);
359 break;
360 case COM_SETDWORD:
361 OpcodeSetPtrData(Command+2,DEF_DWORD);
362 break;
363 case COM_SETWORD:
364 OpcodeSetPtrData(Command+2,DEF_WORD);
365 break;
366 case COM_SETBYTE:
367 OpcodeSetPtrData(Command+2,DEF_BYTE);
368 break;
369
370 case COM_DEBUG:
371 extern BOOL bDebugCompile;
372 //int 3
373 if(bDebugCompile)
374 {
375 breakpoint;
376 }
377 else
378 {
379//#if defined(_DEBUG)
380 breakpoint;
381//#endif
382 }
383 break;
384
385 case COM_LET:
386 OpcodeCalc(Command+2);
387 break;
388 default:
389 OpcodeOthers(Command);
390 break;
391 }
392}
393
394void GetGlobalDataForDll(void){
395 extern char *basbuf;
396 extern HANDLE hHeap;
397 int i2,BufferSize;
398 char *Command;
399 DWORD dwRetCode;
400
401 dwRetCode=0;
402 BufferSize=128;
403 Command=(char *)HeapAlloc(hHeap,0,BufferSize);
404 for(cp++,i2=0;;cp++,i2++){
405 if(i2>=BufferSize){
406 //バッファ領域が足りなくなった場合はバッファを増量する
407 BufferSize+=128;
408 Command=(char *)HeapReAlloc(hHeap,0,Command,BufferSize);
409 }
410 if(basbuf[cp]=='\"'){
411 Command[i2]=basbuf[cp];
412 for(cp++,i2++;;cp++,i2++){
413 if(i2>=BufferSize){
414 //バッファ領域が足りなくなった場合はバッファを増量する
415 BufferSize+=128;
416 Command=(char *)HeapReAlloc(hHeap,0,Command,BufferSize);
417 }
418 Command[i2]=basbuf[cp];
419 if(basbuf[cp]=='\"') break;
420 }
421 continue;
422 }
423 if(IsCommandDelimitation(basbuf[cp])){
424 Command[i2]=0;
425
426 if(Command[0]==1&&Command[1]==ESC_SUB){
427 i2=cp;
428 while(!(basbuf[cp]==1&&basbuf[cp+1]==ESC_ENDSUB)){
429 if(basbuf[cp]=='\0'){
430 SetError(22,"Sub",i2);
431 break;
432 }
433 cp++;
434 }
435 if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break;
436 cp+=2;
437 i2=-1;
438 continue;
439 }
440 if(Command[0]==1&&Command[1]==ESC_FUNCTION){
441 i2=cp;
442 while(!(basbuf[cp]==1&&basbuf[cp+1]==ESC_ENDFUNCTION)){
443 if(basbuf[cp]=='\0'){
444 SetError(22,"Function",i2);
445 break;
446 }
447 cp++;
448 }
449 if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break;
450 cp+=2;
451 i2=-1;
452 continue;
453 }
454 if(Command[0]==1&&Command[1]==ESC_MACRO){
455 i2=cp;
456 while(!(basbuf[cp]==1&&basbuf[cp+1]==ESC_ENDMACRO)){
457 if(basbuf[cp]=='\0'){
458 SetError(22,"Macro",i2);
459 break;
460 }
461 cp++;
462 }
463 if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break;
464 cp+=2;
465 i2=-1;
466 continue;
467 }
468 if(Command[0]==1&&Command[1]==ESC_TYPE){
469 i2=cp;
470 while(!(basbuf[cp]==1&&basbuf[cp+1]==ESC_ENDTYPE)){
471 if(basbuf[cp]=='\0'){
472 SetError(22,"Type",i2);
473 break;
474 }
475 cp++;
476 }
477 if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break;
478 cp+=2;
479 i2=-1;
480 continue;
481 }
482 if(Command[0]==1&&Command[1]==ESC_CLASS){
483 i2=cp;
484 while(!(basbuf[cp]==1&&basbuf[cp+1]==ESC_ENDCLASS)){
485 if(basbuf[cp]=='\0'){
486 SetError(22,"Class",i2);
487 break;
488 }
489 cp++;
490 }
491 if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break;
492 cp+=2;
493 i2=-1;
494 continue;
495 }
496 if(Command[0]==1&&Command[1]==ESC_INTERFACE){
497 i2=cp;
498 while(!(basbuf[cp]==1&&basbuf[cp+1]==ESC_ENDINTERFACE)){
499 if(basbuf[cp]=='\0'){
500 SetError(22,"Interface",i2);
501 break;
502 }
503 cp++;
504 }
505 if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break;
506 cp+=2;
507 i2=-1;
508 continue;
509 }
510
511 //DLLのグローバルデータに必要なコマンドだけ
512 if(MAKEWORD(Command[1],Command[0])==COM_DIM)
513 OpcodeDim(Command+2,0);
514
515 if(basbuf[cp]=='\0') break;
516 i2=-1;
517 continue;
518 }
519 Command[i2]=basbuf[cp];
520 }
521 HeapDefaultFree(Command);
522}
523DWORD CompileBuffer(char Return_Sequence,WORD Return_Command){
524 extern char *basbuf;
525 extern HANDLE hHeap;
526 int i,i2,i3,i4,BufferSize,ScopeStart;
527 char *Command,temporary[VN_SIZE],*temp2,temp3[32];
528 DWORD dwRetCode;
529
530 ScopeStart=cp;
531
532 dwRetCode=0;
533 BufferSize=128;
534 Command=(char *)HeapAlloc(hHeap,0,BufferSize);
535
536 for(cp++,i2=0;;cp++,i2++){
537 if(i2>=BufferSize){
538 //バッファ領域が足りなくなった場合はバッファを増量する
539 BufferSize+=128;
540 Command=(char *)HeapReAlloc(hHeap,0,Command,BufferSize);
541 }
542 if(basbuf[cp]=='\"'){
543 Command[i2]=basbuf[cp];
544 for(cp++,i2++;;cp++,i2++){
545 if(i2>=BufferSize){
546 //バッファ領域が足りなくなった場合はバッファを増量する
547 BufferSize+=128;
548 Command=(char *)HeapReAlloc(hHeap,0,Command,BufferSize);
549 }
550 Command[i2]=basbuf[cp];
551 if(basbuf[cp]=='\"') break;
552 }
553 continue;
554 }
555 if(IsCommandDelimitation(basbuf[cp])){
556 Command[i2]=0;
557
558 if(Command[0]==1&&Command[1]==ESC_LINENUM){
559 for(i=2,i2=0;;i++,i2++){
560 if(Command[i]==','){
561 temporary[i2]=0;
562 break;
563 }
564 temporary[i2]=Command[i];
565 }
566 i3=atoi(temporary);
567 i4=i+1;
568
569 //Goto先ラベル
570 compiler.codeGenerator.gotoLabels.push_back( GotoLabel( (long)i3, compiler.codeGenerator.GetNativeCodeSize() ) );
571
572 //書き込みスケジュール
573 GotoLabelSchedules::iterator it = compiler.codeGenerator.gotoLabelSchedules.begin();
574 while( it != compiler.codeGenerator.gotoLabelSchedules.end() )
575 {
576 if( (*it)->GetName().size() == 0 && (*it)->GetLineNum() == i3 )
577 {
578 compiler.codeGenerator.opfix_JmpPertialSchedule( (*it) );
579
580 //詰める
581 it = compiler.codeGenerator.gotoLabelSchedules.erase( it );
582 }
583 else
584 {
585 it++;
586 }
587 }
588
589 temp2=(char *)HeapAlloc(hHeap,0,lstrlen(Command+i4)+1);
590 lstrcpy(temp2,Command+i4);
591 lstrcpy(Command,temp2);
592 HeapDefaultFree(temp2);
593 }
594
595 if(Command[0]==1&&
596 (((Command[1]==ESC_VIRTUAL||Command[1]==ESC_OVERRIDE)&&Command[2]==1&&(Command[3]==ESC_SUB||Command[3]==ESC_FUNCTION))||
597 Command[1]==ESC_SUB||
598 Command[1]==ESC_FUNCTION||
599 Command[1]==ESC_MACRO||
600 Command[1]==ESC_TYPE||
601 Command[1]==ESC_CLASS||
602 Command[1]==ESC_INTERFACE||
603 Command[1]==ESC_ENUM||
604 (Command[1]==ESC_CONST&&Command[2]==1&&Command[3]==ESC_ENUM)
605 )
606 ){
607 if(Command[1]==ESC_VIRTUAL||Command[1]==ESC_OVERRIDE||Command[1]==ESC_CONST){
608 GetDefaultNameFromES(Command[3],temporary);
609 }
610 else{
611 GetDefaultNameFromES(Command[1],temporary);
612 }
613 if(Return_Sequence){
614 SetError(12,temporary,cp);
615 break;
616 }
617
618 if(Command[1]==ESC_CONST) i3=GetEndXXXCommand(Command[3]);
619 else i3=GetEndXXXCommand(Command[1]);
620 for(i2=cp;;cp++){
621 if(basbuf[cp]==1){
622 if(basbuf[cp+1]==i3) break;
623 if(Command[1]==ESC_CLASS||Command[1]==ESC_INTERFACE){
624 //クラス、インターフェイスではSub、Functionの定義を可能にしておく
625 if(basbuf[cp+1]==ESC_MACRO||
626 basbuf[cp+1]==ESC_TYPE||
627 basbuf[cp+1]==ESC_CLASS||
628 basbuf[cp+1]==ESC_INTERFACE||
629 basbuf[cp+1]==ESC_ENUM){
630 GetDefaultNameFromES(basbuf[cp+1],temp3);
631 SetError(12,temp3,cp);
632 }
633 }
634 else{
635 if(basbuf[cp-1]!='*'&&(
636 basbuf[cp+1]==ESC_VIRTUAL||
637 basbuf[cp+1]==ESC_OVERRIDE||
638 basbuf[cp+1]==ESC_SUB||
639 basbuf[cp+1]==ESC_FUNCTION||
640 basbuf[cp+1]==ESC_MACRO||
641 basbuf[cp+1]==ESC_TYPE||
642 basbuf[cp+1]==ESC_CLASS||
643 basbuf[cp+1]==ESC_INTERFACE||
644 basbuf[cp+1]==ESC_ENUM)){
645 GetDefaultNameFromES(basbuf[cp+1],temp3);
646 SetError(12,temp3,cp);
647 }
648 }
649 }
650 if(basbuf[cp]=='\0'){
651 //error
652 //既にエラー発行済みのため、何もせずに抜ける
653 break;
654 }
655 }
656 if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break;
657 cp+=2;
658 i2=-1;
659 continue;
660 }
661
662 if(Command[0]==0x10||Command[0]==0x11){
663 //Wend、Next、Loopなど
664 if(Return_Command==MAKEWORD(Command[1],Command[0])){
665 if(Return_Command==COM_NEXT){
666 //Nextの場合は、パラメータ(省略化)の整合性を判断する必要がある(OpcodeFor関数を参照)
667 extern char szNextVariable[VN_SIZE];
668 if(Command[2]) lstrcpy(szNextVariable,Command+2);
669 else szNextVariable[0]=0;
670 }
671 break;
672 }
673 }
674
675 compiler.codeGenerator.NextSourceLine();
676
677 if(Command[0]==1){
678 if(Return_Sequence==ESC_ENDIF&&Command[1]==ESC_ELSE){
679 dwRetCode=ESC_ELSE;
680 break;
681 }
682
683 if(Command[1]==Return_Sequence){
684 dwRetCode=Command[1];
685 break;
686 }
687 }
688
689 try
690 {
691 ChangeOpcode(Command);
692 }
693 catch( const SmoothieException &smoothieException )
694 {
695 SetError(
696 smoothieException.GetErrorCode(),
697 smoothieException.GetKeyword(),
698 smoothieException.GetNowLine()
699 );
700 }
701
702
703 epi_check();
704
705
706 //コンパイルを中断するとき
707 extern BOOL bStopCompile;
708 if(bStopCompile) return 0;
709
710 if(basbuf[cp]=='\0'){
711 switch(Return_Command){
712 case COM_WEND:
713 SetError(4,"\"While\" - \"Wend\" ",ScopeStart);
714 break;
715 case COM_NEXT:
716 SetError(4,"\"For\" - \"Next\" ",ScopeStart);
717 break;
718 case COM_LOOP:
719 SetError(4,"\"Do\" - \"Loop\" ",ScopeStart);
720 break;
721 }
722 switch(Return_Sequence){
723 case ESC_ENDSUB:
724 SetError(4,"\"Sub\" - \"End Sub\" ",ScopeStart);
725 break;
726 case ESC_ENDFUNCTION:
727 SetError(4,"\"Function\" - \"End Function\" ",ScopeStart);
728 break;
729 case ESC_ENDMACRO:
730 SetError(4,"\"Macro\" - \"End Macro\" ",ScopeStart);
731 break;
732 case ESC_ENDIF:
733 SetError(22,"If",ScopeStart);
734 break;
735 }
736 break;
737 }
738 i2=-1;
739 continue;
740 }
741 Command[i2]=basbuf[cp];
742 }
743 HeapDefaultFree(Command);
744
745 return dwRetCode;
746}
Note: See TracBrowser for help on using the repository browser.