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

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

コード全体のリファクタリングを実施

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