source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/src/LexicalAnalyzer_Procedure.cpp@ 710

Last change on this file since 710 was 710, checked in by dai_9181, 16 years ago
  • #182への対応。シンボル名として使えない文字列を含んだファイル名のビルドができない不具合を修正。
File size: 23.8 KB
Line 
1#include "stdafx.h"
2
3using namespace ActiveBasic::Compiler;
4
5bool LexicalAnalyzer::ExtractParameterVarNames( const char *sourceOfParams, Jenga::Common::Strings &paramVarNames, int nowLine )
6{
7 int i = 0;
8 int i2,i3,sw;
9 char temporary[8192],temp2[VN_SIZE];
10
11 while(1){
12 if(sourceOfParams[i]=='\0') break;
13
14 //ByRef
15 bool isRef;
16 if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYVAL){
17 isRef = false;
18 i+=2;
19 }
20 else if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYREF){
21 isRef = true;
22 i+=2;
23 }
24 else isRef = false;
25
26 //パラメータ名
27 bool isArray = false;
28 Subscripts subscripts;
29 char name[VN_SIZE];
30 sw=0;
31 for(i2=0;;i++,i2++){
32 if(sourceOfParams[i]=='('){
33 if(!sw) sw=1;
34
35 i3=GetStringInPare(name+i2,sourceOfParams+i);
36 i2+=i3-1;
37 i+=i3-1;
38 continue;
39 }
40 if(sourceOfParams[i]=='['){
41 if(!sw) sw=1;
42
43 i3=GetStringInBracket(name+i2,sourceOfParams+i);
44 i2+=i3-1;
45 i+=i3-1;
46 continue;
47 }
48 if(!IsVariableChar(sourceOfParams[i])){
49 name[i2]=0;
50 break;
51 }
52 name[i2]=sourceOfParams[i];
53 }
54 if(sw){
55 //配列パラメータ
56 if( isRef == false ) compiler.errorMessenger.Output(29,NULL,nowLine);
57 isArray = true;
58
59 if((name[i2-2]=='('&&name[i2-1]==')')||
60 (name[i2-2]=='['&&name[i2-1]==']'))
61 {
62 subscripts.push_back( LONG_MAX );
63
64 name[i2-2]=0;
65 }
66 else{
67 GetArrange(name,temp2,subscripts);
68 lstrcpy(name,temp2);
69 }
70
71 i2=lstrlen(name);
72 }
73
74 paramVarNames.push_back( name );
75
76 //型
77 Type type( DEF_NON );
78 if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_AS)
79 {
80 i+=2;
81
82 i2=0;
83 while(sourceOfParams[i]=='*'){
84 temporary[i2]=sourceOfParams[i];
85 i++;
86 i2++;
87 }
88 for(;;i++,i2++){
89 if(!IsVariableChar(sourceOfParams[i], true)){
90 if(sourceOfParams[i]==1&&(sourceOfParams[i+1]==ESC_FUNCTION||sourceOfParams[i+1]==ESC_SUB)){
91 temporary[i2++]=sourceOfParams[i++];
92 temporary[i2]=sourceOfParams[i];
93 continue;
94 }
95 temporary[i2]=0;
96 break;
97 }
98 temporary[i2]=sourceOfParams[i];
99 }
100 }
101
102 if(sourceOfParams[i]==','){
103 i++;
104 continue;
105 }
106 else if(sourceOfParams[i]=='\0') break;
107 else{
108 compiler.errorMessenger.Output(1,NULL,nowLine);
109 break;
110 }
111 }
112
113 return true;
114}
115
116bool LexicalAnalyzer::AnalyzeParameter( Parameters &params, const Jenga::Common::Strings &parameterStrings, int nowLine )
117{
118 int i2,i3,sw;
119 char temporary[8192],temp2[VN_SIZE];
120
121 //パラメータ
122 BOOST_FOREACH( const std::string &paramStr, parameterStrings )
123 {
124 int i = 0;
125
126 if( paramStr[i] == '\0' )
127 {
128 break;
129 }
130
131 //ByRef
132 bool isRef;
133 if(paramStr[i]==1&&paramStr[i+1]==ESC_BYVAL){
134 isRef = false;
135 i+=2;
136 }
137 else if(paramStr[i]==1&&paramStr[i+1]==ESC_BYREF){
138 isRef = true;
139 i+=2;
140 }
141 else isRef = false;
142
143 //パラメータ名
144 bool isArray = false;
145 Subscripts subscripts;
146 char name[VN_SIZE];
147 sw=0;
148 for(i2=0;;i++,i2++){
149 if(paramStr[i]=='('){
150 if(!sw) sw=1;
151
152 i3=GetStringInPare(name+i2,paramStr.c_str()+i);
153 i2+=i3-1;
154 i+=i3-1;
155 continue;
156 }
157 if(paramStr[i]=='['){
158 if(!sw) sw=1;
159
160 i3=GetStringInBracket(name+i2,paramStr.c_str()+i);
161 i2+=i3-1;
162 i+=i3-1;
163 continue;
164 }
165 if(!IsVariableChar(paramStr[i])){
166 name[i2]=0;
167 break;
168 }
169 name[i2]=paramStr[i];
170 }
171 if(sw){
172 //配列パラメータ
173 if( isRef == false )
174 {
175 compiler.errorMessenger.Output(29,NULL,nowLine);
176 }
177 isArray = true;
178
179 if((name[i2-2]=='('&&name[i2-1]==')')||
180 (name[i2-2]=='['&&name[i2-1]==']'))
181 {
182 subscripts.push_back( LONG_MAX );
183
184 name[i2-2]=0;
185 }
186 else{
187 GetArrange(name,temp2,subscripts);
188 lstrcpy(name,temp2);
189 }
190
191 i2=lstrlen(name);
192 }
193
194 Type type( DEF_NON );
195 char initValue[8192] = "";
196 if( paramStr[i] == '=' ){
197 i++;
198 i = GetOneParameter( paramStr.c_str(), i, initValue );
199
200 // TODO: エラー用 fix me!!!
201 //cp = nowLine;
202
203 NumOpe_GetType( initValue, GetStringTypeInfo(), type );
204
205 if( IS_LITERAL(type.GetIndex()) )
206 {
207 type.SetIndex( -1 );
208 }
209 }
210 else if(paramStr[i]==1&&paramStr[i+1]==ESC_AS){
211 // As指定
212 i+=2;
213
214 i2=0;
215 while(paramStr[i]=='*'){
216 temporary[i2]=paramStr[i];
217 i++;
218 i2++;
219 }
220 for(;;i++,i2++){
221 if(!IsVariableChar(paramStr[i], true)){
222 if(paramStr[i]==1&&(paramStr[i+1]==ESC_FUNCTION||paramStr[i+1]==ESC_SUB)){
223 temporary[i2++]=paramStr[i++];
224 temporary[i2]=paramStr[i];
225 continue;
226 }
227 temporary[i2]=0;
228 break;
229 }
230 temporary[i2]=paramStr[i];
231 }
232
233 compiler.StringToType( temporary, type );
234
235 if( type.IsNull() ){
236 compiler.errorMessenger.Output(3,temporary,nowLine);
237 type.SetBasicType( DEF_PTR_VOID );
238 }
239
240 if( type.IsObject() ){
241 if( type.GetClass().IsBlittableType() ){
242 // Blittable型のときは基本型として扱う
243 type = type.GetClass().GetBlittableType();
244 }
245 }
246 }
247 else{
248 type.SetBasicType( Type::GetBasicTypeFromSimpleName(temporary) );
249 compiler.errorMessenger.Output(-103,temporary,nowLine);
250 }
251
252 Parameter *pParam = new Parameter( name, type, isRef, initValue );
253 if( isArray ){
254 pParam->SetArray( subscripts );
255 }
256
257 //パラメータを追加
258 params.push_back( pParam );
259 }
260
261 return true;
262}
263
264bool LexicalAnalyzer::SetParamsAndReturnTypeForUserProc( UserProc &userProc, const char *sourceOfParams, int nowLine, bool isStatic )
265{
266 int i = 0;
267
268 //ソースコードの位置
269 userProc.SetSourceCodePosition( SourceCodePosition( compiler.GetCurrentRelationalObjectModuleIndexForSource(), nowLine ) );
270
271 //パラメータ
272 if(sourceOfParams[i]!='('){
273 compiler.errorMessenger.Output(1,NULL,nowLine);
274 return false;
275 }
276 if(sourceOfParams[i + 1]!=')'&& userProc.HasParentClass() ){
277 //クラスのメンバ関数の場合のみ、デストラクタにパラメータがある場合にエラーをだす
278 if(userProc.GetName()[0]=='~'){
279 compiler.errorMessenger.Output(114,NULL,nowLine);
280 return false;
281 }
282 }
283
284 // カッコ内のパラメータ文字列を取得
285 char parametersStr1[8192];
286 char parametersStr2[8192] = "";
287 i += GetStringInPare( parametersStr1, sourceOfParams + i, true );
288 if( sourceOfParams[i] == '(' )
289 {
290 i += GetStringInPare( parametersStr2, sourceOfParams + i, true );
291 }
292
293 // 戻り値文字列を取得
294 char returnTypeStr[VN_SIZE] = "";
295 if( sourceOfParams[i] )
296 {
297 if( sourceOfParams[i] == 1 && sourceOfParams[i+1] == ESC_AS )
298 {
299 if( !userProc.IsFunction() ){
300 // Sub/Macroの場合
301 compiler.errorMessenger.Output(38,userProc.GetName(),nowLine);
302 }
303
304 lstrcpy( returnTypeStr, sourceOfParams + i + 2 );
305 }
306 else
307 {
308 compiler.errorMessenger.Output(1,NULL,nowLine);
309 return false;
310 }
311 }
312
313 Jenga::Common::Strings parameters;
314
315 // パラメータ
316 SplitParameter( parametersStr1, parameters );
317 ActiveBasic::Compiler::LexicalAnalyzer::AnalyzeParameter( userProc.GetParameters(), parameters, nowLine );
318
319 // 省略可能パラメータ(古い仕様。非推奨)
320 userProc.SetSecondParmNum( (int)userProc.GetParameters().size() );
321 SplitParameter( parametersStr2, parameters );
322 ActiveBasic::Compiler::LexicalAnalyzer::AnalyzeParameter( userProc.GetParameters(), parameters, nowLine );
323
324
325 if(returnTypeStr[0]){
326 ///////////////////
327 // 戻り値を取得
328 ///////////////////
329
330 if( !userProc.IsFunction() ){
331 // Sub/Macroの場合
332 compiler.errorMessenger.Output(38,userProc.GetName(),nowLine);
333 }
334
335 if( userProc.HasParentClass() ){
336 if( userProc.GetName() == userProc.GetParentClassPtr()->GetName() ||
337 userProc.GetName()[0]=='~'){
338 //クラスのコンストラクタ、デストラクタがFunction定義の場合はエラーをだす
339 compiler.errorMessenger.Output(115,NULL,nowLine);
340 }
341 }
342
343 compiler.StringToType( returnTypeStr, userProc.ReturnType() );
344 if( userProc.ReturnType().IsNull() )
345 {
346 compiler.errorMessenger.Output(3,returnTypeStr,nowLine);
347 }
348 }
349 else{
350 if( userProc.IsFunction() )
351 {
352 // Function定義なのに、戻り値の型がセットされていない
353 compiler.errorMessenger.Output(-104,userProc.GetName().c_str(),nowLine);
354
355 userProc.ReturnType().SetBasicType( DEF_DOUBLE );
356 }
357 else
358 {
359 //戻り値なしのSub定義
360 userProc.ReturnType().SetNull();
361 }
362 }
363
364 //リアルパラメータ領域を取得(_System_LocalThisを考慮して2つだけ多く確保する場合がある)
365
366 if( userProc.HasParentClass() && isStatic == false ){
367 //オブジェクトメンバの場合は、第一パラメータを_System_LocalThis引き渡し用として利用
368 std::string name = "_System_LocalThis";
369 Type type( DEF_PTR_VOID );
370 userProc.RealParams().push_back( new Parameter( name, type ) );
371 }
372
373 if( userProc.ReturnType().IsStruct() ){
374 //構造体を戻り値として持つ場合
375 //※第一パラメータ(Thisポインタありの場合は第二パラメータ)を戻り値用の参照宣言にする
376
377 std::string name = userProc.GetName();
378 if(name[0]==1&&name[1]==ESC_OPERATOR){
379 name="_System_ReturnValue";
380 }
381 Type type( DEF_STRUCT, userProc.ReturnType().GetIndex() );
382 userProc.RealParams().push_back( new Parameter( name, type, true ) );
383 }
384
385 //パラメータをコピー
386 BOOST_FOREACH( Parameter *pParam, userProc.GetParameters() ){
387 userProc.RealParams().push_back( new Parameter( *pParam ) );
388 }
389
390 return true;
391}
392
393bool LexicalAnalyzer::SetParamsAndReturnType( Procedure *pProc, const char *sourceOfParams, bool isSupportEllipse, int nowLine ){
394 int i = 0;
395 int i2,i3,sw;
396 char temporary[8192],temp2[VN_SIZE];
397
398 //ソースコードの位置
399 pProc->SetSourceCodePosition( SourceCodePosition( compiler.GetCurrentRelationalObjectModuleIndexForSource(), nowLine ) );
400
401 //パラメータ
402 if(sourceOfParams[i]!='('){
403 compiler.errorMessenger.Output(1,NULL,nowLine);
404 return 0;
405 }
406 i++;
407 while(1){
408 if(sourceOfParams[i]==')') break;
409
410 //ByRef
411 bool isRef;
412 if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYVAL){
413 isRef = false;
414 i+=2;
415 }
416 else if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYREF){
417 isRef = true;
418 i+=2;
419 }
420 else isRef = false;
421
422 //パラメータ名
423 bool isArray = false;
424 Subscripts subscripts;
425 char name[VN_SIZE];
426 sw=0;
427 for(i2=0;;i++,i2++){
428 if(sourceOfParams[i]=='('){
429 if(!sw) sw=1;
430
431 i3=GetStringInPare(name+i2,sourceOfParams+i);
432 i2+=i3-1;
433 i+=i3-1;
434 continue;
435 }
436 if(sourceOfParams[i]=='['){
437 if(!sw) sw=1;
438
439 i3=GetStringInBracket(name+i2,sourceOfParams+i);
440 i2+=i3-1;
441 i+=i3-1;
442 continue;
443 }
444 if(!IsVariableChar(sourceOfParams[i])){
445 name[i2]=0;
446 break;
447 }
448 name[i2]=sourceOfParams[i];
449 }
450 if(sw){
451 //配列パラメータ
452 if( isRef == false ) compiler.errorMessenger.Output(29,NULL,nowLine);
453 isArray = true;
454
455 if((name[i2-2]=='('&&name[i2-1]==')')||
456 (name[i2-2]=='['&&name[i2-1]==']'))
457 {
458 subscripts.push_back( LONG_MAX );
459
460 name[i2-2]=0;
461 }
462 else{
463 GetArrange(name,temp2,subscripts);
464 lstrcpy(name,temp2);
465 }
466
467 i2=lstrlen(name);
468 }
469
470 //型
471 Type type( DEF_NON );
472 if( isSupportEllipse && lstrcmp(name,"...")==0 )
473 {
474 type.SetBasicType( DEF_ELLIPSE );
475 }
476 else if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_AS)
477 {
478 i+=2;
479
480 i2=0;
481 while(sourceOfParams[i]=='*'){
482 temporary[i2]=sourceOfParams[i];
483 i++;
484 i2++;
485 }
486 for(;;i++,i2++){
487 if(!IsVariableChar(sourceOfParams[i], true)){
488 if(sourceOfParams[i]==1&&(sourceOfParams[i+1]==ESC_FUNCTION||sourceOfParams[i+1]==ESC_SUB)){
489 temporary[i2++]=sourceOfParams[i++];
490 temporary[i2]=sourceOfParams[i];
491 continue;
492 }
493 temporary[i2]=0;
494 break;
495 }
496 temporary[i2]=sourceOfParams[i];
497 }
498
499 compiler.StringToType( temporary, type );
500
501 if( type.IsNull() ){
502 compiler.errorMessenger.Output(3,temporary,nowLine);
503 type.SetBasicType( DEF_PTR_VOID );
504 }
505 }
506 else{
507 type.SetBasicType( Type::GetBasicTypeFromSimpleName(temporary) );
508 compiler.errorMessenger.Output(-103,temporary,nowLine);
509 }
510
511 Parameter *pParam = new Parameter( name, type, isRef );
512 if( isArray ){
513 pParam->SetArray( subscripts );
514 }
515
516 //パラメータを追加
517 pProc->GetParameters().push_back( pParam );
518
519 if(sourceOfParams[i]==','){
520 i++;
521 continue;
522 }
523 else if(sourceOfParams[i]==')') continue;
524 else{
525 compiler.errorMessenger.Output(1,NULL,nowLine);
526 break;
527 }
528 }
529 i++;
530
531 if(sourceOfParams[i]){
532 ///////////////////
533 // 戻り値を取得
534 ///////////////////
535
536 i2=lstrlen(sourceOfParams)-2;
537
538 int sw_as=0;
539 for(;i2>0;i2--){
540 if(sourceOfParams[i2]==')') break;
541
542 if(sourceOfParams[i2]==1&&sourceOfParams[i2+1]==ESC_AS){
543 i2+=2;
544 i3=0;
545 while(sourceOfParams[i2]=='*') temporary[i3++]=sourceOfParams[i2++];
546 for(;;i2++,i3++){
547 if(!IsVariableChar(sourceOfParams[i2], true)){
548 temporary[i3]=0;
549 break;
550 }
551 temporary[i3]=sourceOfParams[i2];
552 }
553 compiler.StringToType( temporary, pProc->ReturnType() );
554 if( pProc->ReturnType().IsNull() ) compiler.errorMessenger.Output(3,temporary,nowLine);
555
556 sw_as=1;
557 break;
558 }
559 }
560 }
561 else{
562 //戻り値なしのSub定義
563 pProc->ReturnType().SetNull();
564 }
565
566 //戻り値のエラーチェック
567 if( pProc->IsFunction() ){
568 // Function定義
569
570 if( pProc->ReturnType().IsNull() ){
571 // 戻り値がない
572 compiler.errorMessenger.Output(26,pProc->GetName(),nowLine);
573 }
574 }
575 else{
576 if( !pProc->ReturnType().IsNull() ){
577 // Sub定義なのに、戻り値がある
578 compiler.errorMessenger.Output(38,pProc->GetName(),nowLine);
579 }
580 }
581
582 return true;
583}
584
585UserProc* LexicalAnalyzer::ParseUserProc( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, char *buffer,int nowLine,bool isVirtual,CClass *pobj_c, bool isStatic, char *interfaceName )
586{
587 int i2,i3;
588 char temporary[8192];
589
590 int i=1;
591
592 Procedure::Kind kind = Procedure::Sub;
593 bool isMacro = false;
594 if(buffer[i]==ESC_FUNCTION) kind = Procedure::Function;
595 if(buffer[i]==ESC_MACRO){
596 isMacro = true;
597 }
598
599 i++;
600
601 bool isCdecl = false;
602 bool isExport = false;
603 while(1){
604 if(buffer[i]==1&&buffer[i+1]==ESC_CDECL&& isCdecl == false ){
605 isCdecl = true;
606
607 i+=2;
608 }
609 else if(buffer[i]==1&&buffer[i+1]==ESC_EXPORT&& isExport == false ){
610 isExport = true;
611
612 i+=2;
613 }
614 else break;
615 }
616
617 i2=0;
618 if(buffer[i]==1&&buffer[i+1]==ESC_OPERATOR){
619 if(!pobj_c){
620 compiler.errorMessenger.Output(126,NULL,nowLine);
621 return 0;
622 }
623
624 //オペレータの場合
625 temporary[i2++]=buffer[i++];
626 temporary[i2++]=buffer[i++];
627
628 int iCalcId;
629 if(buffer[i]=='='&&buffer[i+1]=='='){
630 iCalcId=CALC_EQUAL;
631 i3=2;
632 }
633 else if(buffer[i]=='='){
634 iCalcId=CALC_SUBSITUATION;
635 i3=1;
636 }
637 else if(buffer[i]=='('){
638 iCalcId=CALC_AS;
639 i3=0;
640 }
641 else if(buffer[i]=='['&&buffer[i+1]==']'&&buffer[i+2]=='='){
642 iCalcId=CALC_ARRAY_SET;
643 i3=3;
644 }
645 else if(buffer[i]=='['&&buffer[i+1]==']'){
646 iCalcId=CALC_ARRAY_GET;
647 i3=2;
648 }
649 else{
650 iCalcId=GetCalcId(buffer+i,&i3);
651 i3++;
652 }
653 if(!iCalcId){
654 compiler.errorMessenger.Output(1,NULL,nowLine);
655 return 0;
656 }
657 temporary[i2++]=iCalcId;
658 temporary[i2]=0;
659
660 i+=i3;
661 }
662 else{
663 if(pobj_c){
664 //クラスメンバの場合、デストラクタには~が付くことを考慮
665 if(buffer[i]=='~'){
666 temporary[i2]='~';
667 i++;
668 i2++;
669 }
670 }
671
672 for(;;i++,i2++){
673 if(!IsVariableChar(buffer[i])){
674 temporary[i2]=0;
675 break;
676 }
677 temporary[i2]=buffer[i];
678 }
679
680 char parentName[VN_SIZE], memberName[VN_SIZE];
681 ReferenceKind refKind;
682 if( SplitMemberName( temporary, parentName, memberName, refKind ) )
683 {
684 if( pobj_c )
685 {
686 if( interfaceName )
687 {
688 lstrcpy( interfaceName, parentName );
689 }
690 else
691 {
692 compiler.errorMessenger.OutputFatalError();
693 return NULL;
694 }
695
696 char dummyMemberName[VN_SIZE];
697 if( SplitMemberName( memberName, parentName, dummyMemberName, refKind ) )
698 {
699 compiler.errorMessenger.Output(69,temporary,nowLine);
700 return NULL;
701 }
702 }
703 else
704 {
705 compiler.errorMessenger.Output(68,temporary,nowLine);
706 return NULL;
707 }
708
709 lstrcpy( temporary, memberName );
710 }
711 }
712
713 if( isMacro ){
714 //大文字に変換
715 CharUpper(temporary);
716 }
717
718 if(!pobj_c){
719 //クラスメンバ以外の場合のみ
720 //重複チェック
721
722 if(GetDeclareHash(temporary)){
723 compiler.errorMessenger.Output(15,temporary,nowLine);
724 return 0;
725 }
726 }
727
728 UserProc *pUserProc = new UserProc( Symbol( namespaceScopes, temporary ), importedNamespaces, kind, isMacro, isCdecl, isExport );
729 pUserProc->SetParentClass( pobj_c );
730
731 // 親インターフェイスをセット
732 if( interfaceName && interfaceName[0] )
733 {
734 ::Interface *pTargetInterface = NULL;
735 BOOST_FOREACH( ::Interface *pInterface, pobj_c->GetInterfaces() )
736 {
737 if( pInterface->GetClass().GetName() == interfaceName )
738 {
739 pTargetInterface = pInterface;
740 break;
741 }
742 }
743 pUserProc->SetInterface( pTargetInterface );
744 }
745
746 if(isExport){
747 pUserProc->Using();
748 }
749
750 // パラメータを解析
751 // ※第1パラメータにに指定するデータの例:"( s As String ) As String"
752 SetParamsAndReturnTypeForUserProc( *pUserProc, buffer + i, nowLine, isStatic );
753
754 pUserProc->_paramStr = buffer + i;
755
756 return pUserProc;
757}
758
759DllProc *LexicalAnalyzer::ParseDllProc(const NamespaceScopes &namespaceScopes, char *buffer,int nowLine)
760{
761 int i2;
762
763 int i=0;
764
765 //Sub/Function
766 Procedure::Kind kind = Procedure::Sub;
767 if(buffer[i]==ESC_SUB){
768 }
769 else if(buffer[i]==ESC_FUNCTION){
770 kind = Procedure::Function;
771 }
772 else{
773 compiler.errorMessenger.Output(1,NULL,nowLine);
774 return NULL;
775 }
776 i++;
777
778 //プロシージャ名
779 char procName[VN_SIZE];
780 bool isCdecl = false;
781 for(i2=0;;i++,i2++){
782 if(buffer[i]==1&&buffer[i+1]==ESC_CDECL){
783 isCdecl = true;
784
785 i+=2;
786 procName[i2]=0;
787 break;
788 }
789 if(buffer[i]==','){
790 procName[i2]=0;
791 break;
792 }
793 if(buffer[i]=='\0'){
794 compiler.errorMessenger.Output(1,NULL,nowLine);
795 return NULL;
796 }
797 procName[i2]=buffer[i];
798 }
799 i++;
800
801 //ユーザー定義関数との重複チェック
802 if(GetSubHash(procName)){
803 compiler.errorMessenger.Output(15,procName,nowLine);
804 return NULL;
805 }
806
807
808 //ライブラリ
809 char dllFileName[MAX_PATH];
810 i = GetOneParameter( buffer, i, dllFileName );
811 Type resultType;
812 _int64 i64data;
813 if( !StaticCalculation( true, dllFileName, 0, &i64data, resultType ) ){
814 return NULL;
815 }
816 if( resultType.GetBasicType() != typeOfPtrChar ){
817 compiler.errorMessenger.Output(1,NULL,nowLine);
818 return NULL;
819 }
820 lstrcpy( dllFileName, (char *)i64data );
821 CharUpper(dllFileName);
822 if(!strstr(dllFileName,".")){
823 lstrcat(dllFileName,".DLL");
824 if(lstrlen(dllFileName)>=16){
825 compiler.errorMessenger.Output(7,NULL,nowLine);
826 return NULL;
827 }
828 }
829
830 //エイリアス
831 char alias[VN_SIZE];
832 i = GetOneParameter( buffer, i, alias );
833 if( alias[0] ){
834 if( !StaticCalculation( true, alias, 0, &i64data, resultType ) ){
835 return NULL;
836 }
837 if( resultType.GetBasicType() != typeOfPtrChar ){
838 compiler.errorMessenger.Output(1,NULL,nowLine);
839 return NULL;
840 }
841 lstrcpy( alias, (char *)i64data );
842 }
843 else{
844 //省略されたときは関数名
845 lstrcpy( alias, procName );
846 }
847
848
849 // オブジェクトを生成
850 DllProc *pDllProc = new DllProc( Symbol( namespaceScopes, procName ), kind, isCdecl, dllFileName, alias );
851
852 // パラメータを解析
853 // ※第1パラメータにに指定するデータの例:"( s As String ) As String"
854 LexicalAnalyzer::SetParamsAndReturnType( pDllProc, buffer + i, true, nowLine );
855
856 // パラメータのエラーチェック
857 BOOST_FOREACH( const Parameter *pParam, pDllProc->Params() ){
858 if( pParam->IsObject() ){
859 compiler.errorMessenger.Output(25,pParam->GetVarName(),nowLine);
860 }
861 if( !pParam->IsRef() ){
862 if( pParam->IsStruct() ){
863 compiler.errorMessenger.Output(28,pParam->GetVarName(),nowLine);
864 }
865 }
866 }
867
868 //戻り値のエラーチェック
869 if( pDllProc->IsFunction() ){
870 // Function定義
871
872 if( pDllProc->ReturnType().IsObject() ){
873 // DLL関数ではオブジェクトを戻り値にできない
874 compiler.errorMessenger.Output(40,pDllProc->GetName(),nowLine);
875 }
876 }
877
878 return pDllProc;
879}
880
881void LexicalAnalyzer::CollectProcedures( const char *source, UserProcs &userProcs, DllProcs &dllProcs )
882{
883 extern HANDLE hHeap;
884 int i,i2,i3;
885 char temporary[8192];
886
887 // 名前空間管理
888 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
889 namespaceScopes.clear();
890
891 // Imports情報のクリア
892 compiler.GetNamespaceSupporter().ClearImportedNamespaces();
893
894 i=-1;
895 while(1){
896 i++;
897
898 if(source[i]==1&&(source[i+1]==ESC_CLASS||source[i+1]==ESC_INTERFACE)){
899 /* Class ~ End Class
900 Interface ~ End Interface
901 を飛び越す */
902 i3=GetEndXXXCommand(source[i+1]);
903 for(i+=2,i2=0;;i++,i2++){
904 if(source[i]=='\0') break;
905 if(source[i]==1&&source[i+1]==(char)i3){
906 i++;
907 break;
908 }
909 }
910 if(source[i]=='\0') break;
911 continue;
912 }
913
914 if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
915 for(i+=2,i2=0;;i2++,i++){
916 if( IsCommandDelimitation( source[i] ) ){
917 temporary[i2]=0;
918 break;
919 }
920 temporary[i2]=source[i];
921 }
922 namespaceScopes.push_back( temporary );
923
924 continue;
925 }
926 else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
927 if( namespaceScopes.size() <= 0 ){
928 compiler.errorMessenger.Output(12, "End Namespace", i );
929 }
930 else{
931 namespaceScopes.pop_back();
932 }
933
934 i += 2;
935 continue;
936 }
937 else if( source[i] == 1 && source[i+1] == ESC_IMPORTS ){
938 for(i+=2,i2=0;;i2++,i++){
939 if( IsCommandDelimitation( source[i] ) ){
940 temporary[i2]=0;
941 break;
942 }
943 temporary[i2]=source[i];
944 }
945 if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
946 {
947 compiler.errorMessenger.Output(64,temporary,cp );
948 }
949
950 continue;
951 }
952 else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED )
953 {
954 // Imports情報のクリア
955 compiler.GetNamespaceSupporter().ClearImportedNamespaces();
956 continue;
957 }
958
959 if(source[i]==1&&source[i+1]==ESC_DECLARE){
960 for(i+=2,i2=0;;i2++,i++){
961 if(source[i]=='\n'){
962 temporary[i2]=0;
963 break;
964 }
965 temporary[i2]=source[i];
966 if(source[i]=='\0') break;
967 }
968 DllProc *pDllProc = ParseDllProc( namespaceScopes, temporary, i );
969 dllProcs.Put( pDllProc );
970
971 continue;
972 }
973 if(source[i]==1&&(source[i+1]==ESC_SUB||source[i+1]==ESC_FUNCTION||source[i+1]==ESC_MACRO)){
974 char statementChar = source[i+1];
975
976 for(i2=0;;i2++,i++){
977 if(IsCommandDelimitation(source[i])){
978 temporary[i2]=0;
979 break;
980 }
981 temporary[i2]=source[i];
982 if(source[i]=='\0') break;
983 }
984
985 UserProc *pUserProc = ParseUserProc( namespaceScopes, compiler.GetNamespaceSupporter().GetImportedNamespaces(), temporary, i, false, NULL, false );
986
987 // 関数を追加
988 if( userProcs.IsExist( pUserProc ) )
989 {
990 // 既に存在している
991 compiler.errorMessenger.Output(15,pUserProc->GetName(),i);
992
993 delete pUserProc;
994 }
995 else
996 {
997 userProcs.Put( pUserProc );
998 }
999
1000 /* Sub ~ End Sub
1001 Function ~ End Function
1002 Macro ~ End Macro
1003 を飛び越す */
1004 char endStatementChar = GetEndXXXCommand( statementChar );
1005 for(i2=0;;i++,i2++){
1006 if( source[i] == '\0' ) break;
1007 if( source[i] == 1 && source[i+1] == endStatementChar ){
1008 i++;
1009 break;
1010 }
1011 }
1012 if(source[i]=='\0') break;
1013 continue;
1014 }
1015
1016 //次の行
1017 for(;;i++){
1018 if(IsCommandDelimitation(source[i])) break;
1019 }
1020 if(source[i]=='\0') break;
1021 }
1022
1023 ////////////
1024 // 特殊関数
1025 ////////////
1026 namespaceScopes.clear();
1027 compiler.GetNamespaceSupporter().ClearImportedNamespaces();
1028
1029 sprintf(temporary,"%c%c%s()",1,ESC_SUB,compiler.GetGlobalAreaProcName().c_str());
1030 UserProc *pUserProc = ParseUserProc( namespaceScopes, compiler.GetNamespaceSupporter().GetImportedNamespaces(), temporary, 0, false, NULL, false );
1031
1032 // 関数を追加
1033 if( userProcs.IsExist( pUserProc ) )
1034 {
1035 // 既に存在している
1036 compiler.errorMessenger.Output(15,pUserProc->GetName(),i);
1037
1038 delete pUserProc;
1039 }
1040 else
1041 {
1042 userProcs.Put( pUserProc );
1043 }
1044}
Note: See TracBrowser for help on using the repository browser.