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

Last change on this file since 288 was 288, checked in by dai_9181, 17 years ago
File size: 15.9 KB
RevLine 
[206]1#include "stdafx.h"
2
[182]3#include <jenga/include/smoothie/Smoothie.h>
4#include <jenga/include/smoothie/LexicalAnalysis.h>
5#include <jenga/include/smoothie/SmoothieException.h>
6
[248]7#include <LexicalScope.h>
[182]8#include <CodeGenerator.h>
[193]9#include <Compiler.h>
[195]10#include <NamespaceSupporter.h>
[182]11
[4]12#include "../BasicCompiler_Common/common.h"
13
14#ifdef _AMD64_
15#include "../BasicCompiler64/opcode.h"
16#else
[5]17#include "../BasicCompiler32/opcode.h"
[4]18#endif
19
[182]20#include <Exception.h>
21
[4]22//With情報
23WITHINFO WithInfo;
24
[263]25//デバッグ用行番号情報
26SourceLines oldSourceLines;
[4]27
[89]28
[263]29
[16]30///////////////////////////////////////////////////
[17]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///////////////////////////////////////////////////
[16]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
[4]80void ChangeOpcode(char *Command){
81 extern HANDLE hHeap;
82
[206]83 if(Command[0]=='\0')
84 {
85 return;
86 }
87
88 trace_for_sourcecodestep( FormatEscapeSequenceStringToDefaultString(Command) );
89
[4]90 if(Command[0]=='*'&&IsVariableTopChar(Command[1])){
91 //Goto先ラベル
[276]92 compiler.codeGenerator.gotoLabels.push_back( GotoLabel( Command + 1, compiler.codeGenerator.GetNativeCodeSize() ) );
[4]93
94 //書き込みスケジュール
[253]95 GotoLabelSchedules::iterator it = compiler.codeGenerator.gotoLabelSchedules.begin();
[246]96 while( it != compiler.codeGenerator.gotoLabelSchedules.end() )
97 {
[253]98 if( (*it)->GetName() == Command+1 )
[246]99 {
[253]100 compiler.codeGenerator.opfix_JmpPertialSchedule( (*it) );
[246]101
[4]102 //詰める
[246]103 it = compiler.codeGenerator.gotoLabelSchedules.erase( it );
[4]104 }
[246]105 else
106 {
107 it++;
108 }
[4]109 }
110 return;
111 }
112 if(Command[0]==1){
113 switch(Command[1]){
114 case ESC_CONST:
[7]115 OpcodeDim(Command+2, DIMFLAG_CONST);
116 break;
117
[4]118 case ESC_TYPEDEF:
[113]119 if( UserProc::IsLocalAreaCompiling() ){
120 // ローカル領域をコンパイルしているとき
121 SetError(65,"TypeDef",cp );
122 }
123
[78]124 //既に収集済み
[4]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:
[182]135 {
[248]136 LexicalScope *pScope = compiler.codeGenerator.lexicalScopes.SearchScope( LexicalScope::SCOPE_TYPE_WHILE );
[182]137 if( !pScope ){
138 SetError(12,"Exit While",cp);
139 return;
140 }
141 pScope->Break();
142 }
[4]143 break;
144 case ESC_EXITFOR:
[182]145 {
[248]146 LexicalScope *pScope = compiler.codeGenerator.lexicalScopes.SearchScope( LexicalScope::SCOPE_TYPE_FOR );
[182]147 if( !pScope ){
148 SetError(12,"Exit For",cp);
149 return;
150 }
151 pScope->Break();
152 }
[4]153 break;
154 case ESC_EXITDO:
[182]155 {
[248]156 LexicalScope *pScope = compiler.codeGenerator.lexicalScopes.SearchScope( LexicalScope::SCOPE_TYPE_DO );
[182]157 if( !pScope ){
158 SetError(12,"Exit Do",cp);
159 return;
160 }
161 pScope->Break();
162 }
[4]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:
[113]203 if( UserProc::IsLocalAreaCompiling() ){
204 // ローカル領域をコンパイルしているとき
205 SetError(65,"Declare",cp );
206 }
[4]207 break;
[26]208
[99]209 case ESC_NAMESPACE:
[199]210 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes().push_back( Command + 2 );
[103]211 break;
[99]212 case ESC_ENDNAMESPACE:
[199]213 if( compiler.GetNamespaceSupporter().GetLivingNamespaceScopes().size() <= 0 ){
[103]214 SetError(12,"End Namespace",cp);
215 }
[199]216 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes().pop_back();
[99]217 break;
[107]218 case ESC_IMPORTS:
[199]219 compiler.GetNamespaceSupporter().ImportsNamespace( Command + 2 );
[107]220 break;
221 case ESC_CLEARNAMESPACEIMPORTED:
[199]222 compiler.GetNamespaceSupporter().GetImportedNamespaces().clear();
[107]223 break;
[99]224
[26]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
[4]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:
[64]255 OpcodeDelete(Command+2, false);
[4]256 break;
[64]257 case COM_SWEEPINGDELETE:
258 OpcodeDelete(Command+2, true);
259 break;
[4]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
[253]303 if(bDebugCompile)
304 {
305 breakpoint;
306 }
307 else
308 {
[263]309//#if defined(_DEBUG)
[253]310 breakpoint;
[263]311//#endif
[253]312 }
[4]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);
[15]465
[4]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先ラベル
[276]500 compiler.codeGenerator.gotoLabels.push_back( GotoLabel( (long)i3, compiler.codeGenerator.GetNativeCodeSize() ) );
[4]501
502 //書き込みスケジュール
[253]503 GotoLabelSchedules::iterator it = compiler.codeGenerator.gotoLabelSchedules.begin();
[246]504 while( it != compiler.codeGenerator.gotoLabelSchedules.end() )
505 {
[253]506 if( (*it)->GetName().size() == 0 && (*it)->GetLineNum() == i3 )
[246]507 {
[253]508 compiler.codeGenerator.opfix_JmpPertialSchedule( (*it) );
509
[4]510 //詰める
[246]511 it = compiler.codeGenerator.gotoLabelSchedules.erase( it );
[4]512 }
[246]513 else
514 {
515 it++;
516 }
[4]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
[263]605 compiler.codeGenerator.NextSourceLine();
[4]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
[182]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 }
[4]631
[232]632
[4]633 epi_check();
634
[232]635
[4]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.