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

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