source: dev/trunk/abdev/BasicCompiler_Common/src/Procedure.cpp@ 415

Last change on this file since 415 was 411, checked in by dai_9181, 17 years ago

-103警告に引き渡す文字列が間違っていたので修正。

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