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

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

GetClass_recurメソッド内でImportsされた名前空間情報が適用されていなかったので適用した。

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