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

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

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