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

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