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

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

UserProc/DllProc/ProcPointerクラスをSymbolクラスからの派生にした

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