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

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