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

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

Messenger/ErrorMessengerクラスを導入。SetError関数によるエラー生成を廃止した。

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