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

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