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

Last change on this file since 824 was 750, checked in by イグトランス (egtra), 16 years ago

BOOST_FOREACHを可能なものはVC++ 2005 for eachへ置換(やや速くなる)。

File size: 23.7 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 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 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 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 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.