source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/src/Procedure.cpp@ 509

Last change on this file since 509 was 509, checked in by dai_9181, 16 years ago

Symbolクラスをab_commonプロジェクトに移動した。

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