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

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

Protectedメソッドを派生クラス内のメソッドでSuperと指定するとエラーになるバグを修正。
クラスメソッド内で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(!IsVariableChar(sourceOfParams[i2])){
360 temporary[i3]=0;
361 break;
362 }
363 temporary[i3]=sourceOfParams[i2];
364 }
365 compiler.StringToType( temporary, this->returnType );
366 if( this->returnType.IsNull() ) SmoothieException::Throw(3,temporary,nowLine);
367
368 sw_as=1;
369 break;
370 }
371 }
372
373 if(!sw_as){
374 SmoothieException::Throw(-104,this->GetName().c_str(),nowLine);
375
376 this->returnType.SetBasicType( DEF_DOUBLE );
377 }
378 }
379 else{
380 //戻り値なしのSub定義
381 this->returnType.SetNull();
382 }
383
384 //リアルパラメータ領域を取得(_System_LocalThisを考慮して2つだけ多く確保する場合がある)
385
386 if( this->pParentClass && isStatic == false ){
387 //オブジェクトメンバの場合は、第一パラメータを_System_LocalThis引き渡し用として利用
388 string name = "_System_LocalThis";
389 Type type( DEF_PTR_VOID );
390 this->realParams.push_back( new Parameter( name, type ) );
391 }
392
393 if( this->returnType.IsStruct() ){
394 //構造体を戻り値として持つ場合
395 //※第一パラメータ(Thisポインタありの場合は第二パラメータ)を戻り値用の参照宣言にする
396
397 string name = this->GetName();
398 if(name[0]==1&&name[1]==ESC_OPERATOR){
399 name="_System_ReturnValue";
400 }
401 Type type( DEF_STRUCT, this->returnType.GetIndex() );
402 this->realParams.push_back( new Parameter( name, type, true ) );
403 }
404
405 //パラメータをコピー
406 BOOST_FOREACH( Parameter *pParam, params ){
407 this->realParams.push_back( new Parameter( *pParam ) );
408 }
409
410 return true;
411}
412
413const UserProc *UserProc::pCompilingUserProc = NULL;
414
415
416bool UserProcs::Insert( UserProc *pUserProc, int nowLine )
417{
418 /////////////////////////////////
419 // ハッシュデータに追加
420 /////////////////////////////////
421
422 if( !Put( pUserProc ) )
423 {
424 // 重複しているため、失敗
425 SetError(15,pUserProc->GetName().c_str(),nowLine);
426 return false;
427 }
428
429 return true;
430}
431UserProc *UserProcs::Add( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, char *buffer,int nowLine,bool isVirtual,CClass *pobj_c, bool isStatic)
432{
433 int i2,i3;
434 char temporary[8192];
435
436 int i=1;
437
438 Procedure::Kind kind = Procedure::Sub;
439 bool isMacro = false;
440 if(buffer[i]==ESC_FUNCTION) kind = Procedure::Function;
441 if(buffer[i]==ESC_MACRO){
442 isMacro = true;
443 }
444
445 i++;
446
447 bool isCdecl = false;
448 bool isExport = false;
449 while(1){
450 if(buffer[i]==1&&buffer[i+1]==ESC_CDECL&& isCdecl == false ){
451 isCdecl = true;
452
453 i+=2;
454 }
455 else if(buffer[i]==1&&buffer[i+1]==ESC_EXPORT&& isExport == false ){
456 isExport = true;
457
458 i+=2;
459 }
460 else break;
461 }
462
463 i2=0;
464 if(buffer[i]==1&&buffer[i+1]==ESC_OPERATOR){
465 if(!pobj_c){
466 SetError(126,NULL,nowLine);
467 return 0;
468 }
469
470 //オペレータの場合
471 temporary[i2++]=buffer[i++];
472 temporary[i2++]=buffer[i++];
473
474 int iCalcId;
475 if(buffer[i]=='='&&buffer[i+1]=='='){
476 iCalcId=CALC_EQUAL;
477 i3=2;
478 }
479 else if(buffer[i]=='='){
480 iCalcId=CALC_SUBSITUATION;
481 i3=1;
482 }
483 else if(buffer[i]=='('){
484 iCalcId=CALC_AS;
485 i3=0;
486 }
487 else if(buffer[i]=='['&&buffer[i+1]==']'&&buffer[i+2]=='='){
488 iCalcId=CALC_ARRAY_SET;
489 i3=3;
490 }
491 else if(buffer[i]=='['&&buffer[i+1]==']'){
492 iCalcId=CALC_ARRAY_GET;
493 i3=2;
494 }
495 else{
496 iCalcId=GetCalcId(buffer+i,&i3);
497 i3++;
498 }
499 if(!iCalcId){
500 SetError(1,NULL,nowLine);
501 return 0;
502 }
503 temporary[i2++]=iCalcId;
504 temporary[i2]=0;
505
506 i+=i3;
507 }
508 else{
509 if(pobj_c){
510 //クラスメンバの場合、デストラクタには~が付くことを考慮
511 if(buffer[i]=='~'){
512 temporary[i2]='~';
513 i++;
514 i2++;
515 }
516 }
517
518 for(;;i++,i2++){
519 if(!IsVariableChar(buffer[i])){
520 temporary[i2]=0;
521 break;
522 }
523 temporary[i2]=buffer[i];
524 }
525 }
526
527 if( isMacro ){
528 //大文字に変換
529 CharUpper(temporary);
530
531 //マクロ関数の場合は名前リストに追加
532 macroNames.push_back( temporary );
533 }
534
535 if(!pobj_c){
536 //クラスメンバ以外の場合のみ
537 //重複チェック
538
539 if(GetDeclareHash(temporary)){
540 SetError(15,temporary,nowLine);
541 return 0;
542 }
543 }
544
545 // 識別ID
546 static int id_base=0;
547
548 UserProc *pUserProc = new UserProc( namespaceScopes, importedNamespaces, temporary, kind, isMacro, isCdecl, isExport, (id_base++) );
549 pUserProc->SetParentClass( pobj_c );
550 if( Smoothie::isFullCompile ){
551 // すべての関数・メソッドをコンパイルする
552 pUserProc->Using();
553 }
554
555 if(isExport){
556 pUserProc->Using();
557 }
558
559 // パラメータを解析
560 // ※第1パラメータにに指定するデータの例:"( s As String ) As String"
561 pUserProc->SetParamsAndReturnType( buffer + i, nowLine, isStatic );
562
563 pUserProc->_paramStr = buffer + i;
564
565 // ハッシュに追加
566 if( !Insert( pUserProc, nowLine ) )
567 {
568 return NULL;
569 }
570
571 return pUserProc;
572}
573void UserProcs::EnumGlobalProcs( const char *simpleName, const char *localName, std::vector<const UserProc *> &subs )
574{
575 ///////////////////////////
576 // グローバル関数を検索
577 ///////////////////////////
578
579 // ハッシュ値を取得
580 UserProc *pUserProc = GetHashArrayElement( simpleName );
581 while(pUserProc){
582 if( pUserProc->IsGlobalProcedure() ){
583 if( pUserProc->IsEqualSymbol( localName ) ){
584 subs.push_back( pUserProc );
585 }
586 }
587
588 pUserProc=pUserProc->GetChainNext();
589 }
590}
591
592bool DllProc::SetParamsAndReturnType( const char *sourceOfParams, int nowLine ){
593 int i = 0;
594 int i2,i3,sw;
595 char temporary[8192],temp2[VN_SIZE];
596
597 //ソースコードの位置
598 this->codePos = nowLine;
599
600 //パラメータ
601 if(sourceOfParams[i]!='('){
602 SmoothieException::Throw(1,NULL,nowLine);
603 return 0;
604 }
605 i++;
606
607 while(1){
608 if(sourceOfParams[i]==')') break;
609
610 //ByRef
611 bool isRef;
612 if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYVAL){
613 isRef = false;
614 i+=2;
615 }
616 else if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYREF){
617 isRef = true;
618 i+=2;
619 }
620 else isRef = false;
621
622 //パラメータ名
623 bool isArray = false;
624 Subscripts subscripts;
625 char name[VN_SIZE];
626 sw=0;
627 for(i2=0;;i++,i2++){
628 if(sourceOfParams[i]=='('){
629 if(!sw) sw=1;
630
631 i3=GetStringInPare(name+i2,sourceOfParams+i);
632 i2+=i3-1;
633 i+=i3-1;
634 continue;
635 }
636 if(sourceOfParams[i]=='['){
637 if(!sw) sw=1;
638
639 i3=GetStringInBracket(name+i2,sourceOfParams+i);
640 i2+=i3-1;
641 i+=i3-1;
642 continue;
643 }
644 if(!IsVariableChar(sourceOfParams[i])){
645 name[i2]=0;
646 break;
647 }
648 name[i2]=sourceOfParams[i];
649 }
650 if(sw){
651 //配列パラメータ
652 if( isRef == false ) SmoothieException::Throw(29,NULL,nowLine);
653 isArray = true;
654
655 if((name[i2-2]=='('&&name[i2-1]==')')||
656 (name[i2-2]=='['&&name[i2-1]==']'))
657 {
658 subscripts.push_back( LONG_MAX );
659
660 name[i2-2]=0;
661 }
662 else{
663 GetArrange(name,temp2,subscripts);
664 lstrcpy(name,temp2);
665 }
666
667 i2=lstrlen(name);
668 }
669
670 //型
671 Type type( DEF_NON );
672 if(lstrcmp(name,"...")==0) type.SetBasicType( DEF_ELLIPSE );
673 else if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_AS){
674 i+=2;
675
676 i2=0;
677 while(sourceOfParams[i]=='*'){
678 temporary[i2]=sourceOfParams[i];
679 i++;
680 i2++;
681 }
682 for(;;i++,i2++){
683 if(!IsVariableChar(sourceOfParams[i])){
684 if(sourceOfParams[i]==1&&(sourceOfParams[i+1]==ESC_FUNCTION||sourceOfParams[i+1]==ESC_SUB)){
685 temporary[i2++]=sourceOfParams[i++];
686 temporary[i2]=sourceOfParams[i];
687 continue;
688 }
689 temporary[i2]=0;
690 break;
691 }
692 temporary[i2]=sourceOfParams[i];
693 }
694
695 compiler.StringToType( temporary, type );
696
697 if( type.IsNull() ){
698 SmoothieException::Throw(3,temporary,nowLine);
699 type.SetBasicType( DEF_PTR_VOID );
700 }
701 }
702 else{
703 type.SetBasicType( Type::GetBasicTypeFromSimpleName(temporary) );
704 SmoothieException::Throw(-103,temporary,nowLine);
705 }
706
707 Parameter *pParam = new Parameter( name, type, isRef );
708 if( isArray ){
709 pParam->SetArray( subscripts );
710 }
711
712 //パラメータを追加
713 this->params.push_back( pParam );
714
715 if(sourceOfParams[i]==','){
716 i++;
717 continue;
718 }
719 else if(sourceOfParams[i]==')') continue;
720 else{
721 SmoothieException::Throw(1,NULL,nowLine);
722 break;
723 }
724 }
725 i++;
726
727 if(sourceOfParams[i]){
728 ///////////////////
729 // 戻り値を取得
730 ///////////////////
731
732 i2=lstrlen(sourceOfParams)-2;
733
734 int sw_as=0;
735 for(;i2>0;i2--){
736 if(sourceOfParams[i2]==')') break;
737
738 if(sourceOfParams[i2]==1&&sourceOfParams[i2+1]==ESC_AS){
739 i2+=2;
740 i3=0;
741 while(sourceOfParams[i2]=='*') temporary[i3++]=sourceOfParams[i2++];
742 for(;;i2++,i3++){
743 if(!IsVariableChar(sourceOfParams[i2])){
744 temporary[i3]=0;
745 break;
746 }
747 temporary[i3]=sourceOfParams[i2];
748 }
749 compiler.StringToType( temporary, this->returnType );
750 if( this->returnType.IsNull() ) SmoothieException::Throw(3,temporary,nowLine);
751
752 sw_as=1;
753 break;
754 }
755 }
756 }
757 else{
758 //戻り値なしのSub定義
759 this->returnType.SetNull();
760 }
761
762 return true;
763}
764
765void DllProcs::Add(const NamespaceScopes &namespaceScopes, char *buffer,int nowLine){
766 int i2;
767
768 int i=0;
769
770 //Sub/Function
771 Procedure::Kind kind = Procedure::Sub;
772 if(buffer[i]==ESC_SUB){
773 }
774 else if(buffer[i]==ESC_FUNCTION){
775 kind = Procedure::Function;
776 }
777 else{
778 SetError(1,NULL,nowLine);
779 return;
780 }
781 i++;
782
783 //プロシージャ名
784 char procName[VN_SIZE];
785 bool isCdecl = false;
786 for(i2=0;;i++,i2++){
787 if(buffer[i]==1&&buffer[i+1]==ESC_CDECL){
788 isCdecl = true;
789
790 i+=2;
791 procName[i2]=0;
792 break;
793 }
794 if(buffer[i]==','){
795 procName[i2]=0;
796 break;
797 }
798 if(buffer[i]=='\0'){
799 SetError(1,NULL,nowLine);
800 return;
801 }
802 procName[i2]=buffer[i];
803 }
804 i++;
805
806 //ユーザー定義関数との重複チェック
807 if(GetSubHash(procName)){
808 SetError(15,procName,nowLine);
809 return;
810 }
811
812
813 //ライブラリ
814 char dllFileName[MAX_PATH];
815 i = GetOneParameter( buffer, i, dllFileName );
816 Type resultType;
817 _int64 i64data;
818 if( !StaticCalculation( true, dllFileName, 0, &i64data, resultType ) ){
819 return;
820 }
821 if( resultType.GetBasicType() != typeOfPtrChar ){
822 SetError(1,NULL,nowLine);
823 return;
824 }
825 lstrcpy( dllFileName, (char *)i64data );
826 CharUpper(dllFileName);
827 if(!strstr(dllFileName,".")){
828 lstrcat(dllFileName,".DLL");
829 if(lstrlen(dllFileName)>=16){
830 SetError(7,NULL,nowLine);
831 return;
832 }
833 }
834
835 //エイリアス
836 char alias[VN_SIZE];
837 i = GetOneParameter( buffer, i, alias );
838 if( alias[0] ){
839 if( !StaticCalculation( true, alias, 0, &i64data, resultType ) ){
840 return;
841 }
842 if( resultType.GetBasicType() != typeOfPtrChar ){
843 SetError(1,NULL,nowLine);
844 return;
845 }
846 lstrcpy( alias, (char *)i64data );
847 }
848 else{
849 //省略されたときは関数名
850 lstrcpy( alias, procName );
851 }
852
853
854 // オブジェクトを生成
855 DllProc *pDllProc = new DllProc( namespaceScopes, procName, kind, isCdecl, dllFileName, alias );
856
857 // パラメータを解析
858 // ※第1パラメータにに指定するデータの例:"( s As String ) As String"
859 pDllProc->SetParamsAndReturnType( buffer + i, nowLine );
860
861 // パラメータのエラーチェック
862 BOOST_FOREACH( const Parameter *pParam, pDllProc->Params() ){
863 if( pParam->IsObject() ){
864 SetError(25,pParam->GetVarName(),nowLine);
865 }
866 if( !pParam->IsRef() ){
867 if( pParam->IsStruct() ){
868 SetError(28,pParam->GetVarName(),nowLine);
869 }
870 }
871 }
872
873 //戻り値のエラーチェック
874 if( pDllProc->IsFunction() ){
875 // Function定義
876
877 if( pDllProc->ReturnType().IsObject() ){
878 // DLL関数ではオブジェクトを戻り値にできない
879 SetError(40,pDllProc->GetName(),nowLine);
880 }
881 }
882
883 // ハッシュマップに追加
884 this->Put( pDllProc );
885}
886
887bool ProcPointer::SetParamsAndReturnType( const char *sourceOfParams, int nowLine ){
888 int i = 0;
889 int i2,i3,sw;
890 char temporary[8192],temp2[VN_SIZE];
891
892 //ソースコードの位置
893 this->codePos = nowLine;
894
895 //パラメータ
896 if(sourceOfParams[i]!='('){
897 SmoothieException::Throw(1,NULL,nowLine);
898 return 0;
899 }
900 i++;
901 while(1){
902 if(sourceOfParams[i]==')') break;
903
904 //ByRef
905 bool isRef;
906 if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYVAL){
907 isRef = false;
908 i+=2;
909 }
910 else if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYREF){
911 isRef = true;
912 i+=2;
913 }
914 else isRef = false;
915
916 //パラメータ名
917 bool isArray = false;
918 Subscripts subscripts;
919 char name[VN_SIZE];
920 sw=0;
921 for(i2=0;;i++,i2++){
922 if(sourceOfParams[i]=='('){
923 if(!sw) sw=1;
924
925 i3=GetStringInPare(name+i2,sourceOfParams+i);
926 i2+=i3-1;
927 i+=i3-1;
928 continue;
929 }
930 if(sourceOfParams[i]=='['){
931 if(!sw) sw=1;
932
933 i3=GetStringInBracket(name+i2,sourceOfParams+i);
934 i2+=i3-1;
935 i+=i3-1;
936 continue;
937 }
938 if(!IsVariableChar(sourceOfParams[i])){
939 name[i2]=0;
940 break;
941 }
942 name[i2]=sourceOfParams[i];
943 }
944 if(sw){
945 //配列パラメータ
946 if( isRef == false ) SmoothieException::Throw(29,NULL,nowLine);
947 isArray = true;
948
949 if((name[i2-2]=='('&&name[i2-1]==')')||
950 (name[i2-2]=='['&&name[i2-1]==']'))
951 {
952 subscripts.push_back( LONG_MAX );
953
954 name[i2-2]=0;
955 }
956 else{
957 GetArrange(name,temp2,subscripts);
958 lstrcpy(name,temp2);
959 }
960
961 i2=lstrlen(name);
962 }
963
964 //型
965 Type type( DEF_NON );
966 if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_AS){
967 i+=2;
968
969 i2=0;
970 while(sourceOfParams[i]=='*'){
971 temporary[i2]=sourceOfParams[i];
972 i++;
973 i2++;
974 }
975 for(;;i++,i2++){
976 if(!IsVariableChar(sourceOfParams[i])){
977 if(sourceOfParams[i]==1&&(sourceOfParams[i+1]==ESC_FUNCTION||sourceOfParams[i+1]==ESC_SUB)){
978 temporary[i2++]=sourceOfParams[i++];
979 temporary[i2]=sourceOfParams[i];
980 continue;
981 }
982 temporary[i2]=0;
983 break;
984 }
985 temporary[i2]=sourceOfParams[i];
986 }
987
988 compiler.StringToType( temporary, type );
989
990 if( type.IsNull() ){
991 SmoothieException::Throw(3,temporary,nowLine);
992 type.SetBasicType( DEF_PTR_VOID );
993 }
994 }
995 else{
996 type.SetBasicType( Type::GetBasicTypeFromSimpleName(temporary) );
997 SmoothieException::Throw(-103,temporary,nowLine);
998 }
999
1000 Parameter *pParam = new Parameter( name, type, isRef );
1001 if( isArray ){
1002 pParam->SetArray( subscripts );
1003 }
1004
1005 //パラメータを追加
1006 this->params.push_back( pParam );
1007
1008 if(sourceOfParams[i]==','){
1009 i++;
1010 continue;
1011 }
1012 else if(sourceOfParams[i]==')') continue;
1013 else{
1014 SmoothieException::Throw(1,NULL,nowLine);
1015 break;
1016 }
1017 }
1018 i++;
1019
1020 if(sourceOfParams[i]){
1021 ///////////////////
1022 // 戻り値を取得
1023 ///////////////////
1024
1025 i2=lstrlen(sourceOfParams)-2;
1026
1027 int sw_as=0;
1028 for(;i2>0;i2--){
1029 if(sourceOfParams[i2]==')') break;
1030
1031 if(sourceOfParams[i2]==1&&sourceOfParams[i2+1]==ESC_AS){
1032 i2+=2;
1033 i3=0;
1034 while(sourceOfParams[i2]=='*') temporary[i3++]=sourceOfParams[i2++];
1035 for(;;i2++,i3++){
1036 if(!IsVariableChar(sourceOfParams[i2])){
1037 temporary[i3]=0;
1038 break;
1039 }
1040 temporary[i3]=sourceOfParams[i2];
1041 }
1042 compiler.StringToType( temporary, this->returnType );
1043 if( this->returnType.IsNull() ) SmoothieException::Throw(3,temporary,nowLine);
1044
1045 sw_as=1;
1046 break;
1047 }
1048 }
1049 }
1050 else{
1051 //戻り値なしのSub定義
1052 this->returnType.SetNull();
1053 }
1054
1055 //戻り値のエラーチェック
1056 if( IsFunction() ){
1057 // Function定義
1058
1059 if( this->ReturnType().IsNull() ){
1060 // 戻り値がない
1061 SmoothieException::Throw(26,this->GetName(),nowLine);
1062 }
1063 }
1064 else{
1065 if( !this->ReturnType().IsNull() ){
1066 // Sub定義なのに、戻り値がある
1067 SmoothieException::Throw(38,this->GetName(),nowLine);
1068 }
1069 }
1070
1071 return true;
1072}
1073
1074int ProcPointers::Add( const string &typeExpression )
1075{
1076 DWORD dwProcType = (DWORD)typeExpression[2];
1077 const string &paramStr = typeExpression.substr( 3 );
1078
1079 Procedure::Kind kind = Procedure::Sub;
1080 if( dwProcType == ESC_FUNCTION ){
1081 kind = Procedure::Function;
1082 }
1083
1084 ProcPointer *pProcPointer = new ProcPointer( kind );
1085
1086 //buffer[0]は'('となっている
1087 extern int cp;
1088 pProcPointer->SetParamsAndReturnType( paramStr.c_str(), cp );
1089
1090 this->push_back( pProcPointer );
1091
1092 return (int)this->size()-1;
1093}
1094
1095void ProcPointers::Clear()
1096{
1097 ProcPointers &procPointers = *this;
1098 BOOST_FOREACH( ProcPointer *pProcPointer, procPointers ){
1099 delete pProcPointer;
1100 }
1101 this->clear();
1102}
Note: See TracBrowser for help on using the repository browser.