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

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

DllProcsクラスを追加。

File size: 23.6 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
761void DllProcs::Add(const NamespaceScopes &namespaceScopes, char *buffer,int nowLine){
762 int i2;
763
764 int i=0;
765
766 //Sub/Function
767 Procedure::Kind kind = Procedure::Sub;
768 if(buffer[i]==ESC_SUB){
769 }
770 else if(buffer[i]==ESC_FUNCTION){
771 kind = Procedure::Function;
772 }
773 else{
774 SetError(1,NULL,nowLine);
775 return;
776 }
777 i++;
778
779 //プロシージャ名
780 char procName[VN_SIZE];
781 bool isCdecl = false;
782 for(i2=0;;i++,i2++){
783 if(buffer[i]==1&&buffer[i+1]==ESC_CDECL){
784 isCdecl = true;
785
786 i+=2;
787 procName[i2]=0;
788 break;
789 }
790 if(buffer[i]==','){
791 procName[i2]=0;
792 break;
793 }
794 if(buffer[i]=='\0'){
795 SetError(1,NULL,nowLine);
796 return;
797 }
798 procName[i2]=buffer[i];
799 }
800 i++;
801
802 //ユーザー定義関数との重複チェック
803 if(GetSubHash(procName)){
804 SetError(15,procName,nowLine);
805 return;
806 }
807
808
809 //ライブラリ
810 char dllFileName[MAX_PATH];
811 i = GetOneParameter( buffer, i, dllFileName );
812 Type resultType;
813 _int64 i64data;
814 if( !StaticCalculation( true, dllFileName, 0, &i64data, resultType ) ){
815 return;
816 }
817 if( resultType.GetBasicType() != typeOfPtrChar ){
818 SetError(1,NULL,nowLine);
819 return;
820 }
821 lstrcpy( dllFileName, (char *)i64data );
822 CharUpper(dllFileName);
823 if(!strstr(dllFileName,".")){
824 lstrcat(dllFileName,".DLL");
825 if(lstrlen(dllFileName)>=16){
826 SetError(7,NULL,nowLine);
827 return;
828 }
829 }
830
831 //エイリアス
832 char alias[VN_SIZE];
833 i = GetOneParameter( buffer, i, alias );
834 if( alias[0] ){
835 if( !StaticCalculation( true, alias, 0, &i64data, resultType ) ){
836 return;
837 }
838 if( resultType.GetBasicType() != typeOfPtrChar ){
839 SetError(1,NULL,nowLine);
840 return;
841 }
842 lstrcpy( alias, (char *)i64data );
843 }
844 else{
845 //省略されたときは関数名
846 lstrcpy( alias, procName );
847 }
848
849
850 // オブジェクトを生成
851 DllProc *pDllProc = new DllProc( namespaceScopes, procName, kind, isCdecl, dllFileName, alias );
852
853 // パラメータを解析
854 // ※第1パラメータにに指定するデータの例:"( s As String ) As String"
855 pDllProc->SetParamsAndReturnType( buffer + i, nowLine );
856
857 // パラメータのエラーチェック
858 BOOST_FOREACH( const Parameter *pParam, pDllProc->Params() ){
859 if( pParam->IsObject() ){
860 SetError(25,pParam->GetVarName(),nowLine);
861 }
862 if( !pParam->IsRef() ){
863 if( pParam->IsStruct() ){
864 SetError(28,pParam->GetVarName(),nowLine);
865 }
866 }
867 }
868
869 //戻り値のエラーチェック
870 if( pDllProc->IsFunction() ){
871 // Function定義
872
873 if( pDllProc->ReturnType().IsObject() ){
874 // DLL関数ではオブジェクトを戻り値にできない
875 SetError(40,pDllProc->GetName(),nowLine);
876 }
877 }
878
879 // ハッシュマップに追加
880 this->Put( pDllProc );
881}
882
883bool ProcPointer::SetParamsAndReturnType( const char *sourceOfParams, int nowLine ){
884 int i = 0;
885 int i2,i3,sw;
886 char temporary[8192],temp2[VN_SIZE];
887
888 //ソースコードの位置
889 this->codePos = nowLine;
890
891 //パラメータ
892 if(sourceOfParams[i]!='('){
893 SmoothieException::Throw(1,NULL,nowLine);
894 return 0;
895 }
896 i++;
897 while(1){
898 if(sourceOfParams[i]==')') break;
899
900 //ByRef
901 bool isRef;
902 if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYVAL){
903 isRef = false;
904 i+=2;
905 }
906 else if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYREF){
907 isRef = true;
908 i+=2;
909 }
910 else isRef = false;
911
912 //パラメータ名
913 bool isArray = false;
914 Subscripts subscripts;
915 char name[VN_SIZE];
916 sw=0;
917 for(i2=0;;i++,i2++){
918 if(sourceOfParams[i]=='('){
919 if(!sw) sw=1;
920
921 i3=GetStringInPare(name+i2,sourceOfParams+i);
922 i2+=i3-1;
923 i+=i3-1;
924 continue;
925 }
926 if(sourceOfParams[i]=='['){
927 if(!sw) sw=1;
928
929 i3=GetStringInBracket(name+i2,sourceOfParams+i);
930 i2+=i3-1;
931 i+=i3-1;
932 continue;
933 }
934 if(!IsVariableChar(sourceOfParams[i])){
935 name[i2]=0;
936 break;
937 }
938 name[i2]=sourceOfParams[i];
939 }
940 if(sw){
941 //配列パラメータ
942 if( isRef == false ) SmoothieException::Throw(29,NULL,nowLine);
943 isArray = true;
944
945 if((name[i2-2]=='('&&name[i2-1]==')')||
946 (name[i2-2]=='['&&name[i2-1]==']'))
947 {
948 subscripts.push_back( LONG_MAX );
949
950 name[i2-2]=0;
951 }
952 else{
953 GetArrange(name,temp2,subscripts);
954 lstrcpy(name,temp2);
955 }
956
957 i2=lstrlen(name);
958 }
959
960 //型
961 Type type( DEF_NON );
962 if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_AS){
963 i+=2;
964
965 i2=0;
966 while(sourceOfParams[i]=='*'){
967 temporary[i2]=sourceOfParams[i];
968 i++;
969 i2++;
970 }
971 for(;;i++,i2++){
972 if(!IsVariableChar(sourceOfParams[i])){
973 if(sourceOfParams[i]==1&&(sourceOfParams[i+1]==ESC_FUNCTION||sourceOfParams[i+1]==ESC_SUB)){
974 temporary[i2++]=sourceOfParams[i++];
975 temporary[i2]=sourceOfParams[i];
976 continue;
977 }
978 temporary[i2]=0;
979 break;
980 }
981 temporary[i2]=sourceOfParams[i];
982 }
983
984 compiler.StringToType( temporary, type );
985
986 if( type.IsNull() ){
987 SmoothieException::Throw(3,temporary,nowLine);
988 type.SetBasicType( DEF_PTR_VOID );
989 }
990 }
991 else{
992 type.SetBasicType( Type::GetBasicTypeFromSimpleName(temporary) );
993 SmoothieException::Throw(-103,temporary,nowLine);
994 }
995
996 Parameter *pParam = new Parameter( name, type, isRef );
997 if( isArray ){
998 pParam->SetArray( subscripts );
999 }
1000
1001 //パラメータを追加
1002 this->params.push_back( pParam );
1003
1004 if(sourceOfParams[i]==','){
1005 i++;
1006 continue;
1007 }
1008 else if(sourceOfParams[i]==')') continue;
1009 else{
1010 SmoothieException::Throw(1,NULL,nowLine);
1011 break;
1012 }
1013 }
1014 i++;
1015
1016 if(sourceOfParams[i]){
1017 ///////////////////
1018 // 戻り値を取得
1019 ///////////////////
1020
1021 i2=lstrlen(sourceOfParams)-2;
1022
1023 int sw_as=0;
1024 for(;i2>0;i2--){
1025 if(sourceOfParams[i2]==')') break;
1026
1027 if(sourceOfParams[i2]==1&&sourceOfParams[i2+1]==ESC_AS){
1028 i2+=2;
1029 i3=0;
1030 while(sourceOfParams[i2]=='*') temporary[i3++]=sourceOfParams[i2++];
1031 for(;;i2++,i3++){
1032 if(!IsVariableChar(sourceOfParams[i2])){
1033 temporary[i3]=0;
1034 break;
1035 }
1036 temporary[i3]=sourceOfParams[i2];
1037 }
1038 compiler.StringToType( temporary, this->returnType );
1039 if( this->returnType.IsNull() ) SmoothieException::Throw(3,temporary,nowLine);
1040
1041 sw_as=1;
1042 break;
1043 }
1044 }
1045 }
1046 else{
1047 //戻り値なしのSub定義
1048 this->returnType.SetNull();
1049 }
1050
1051 //戻り値のエラーチェック
1052 if( IsFunction() ){
1053 // Function定義
1054
1055 if( this->ReturnType().IsNull() ){
1056 // 戻り値がない
1057 SmoothieException::Throw(26,this->GetName(),nowLine);
1058 }
1059 }
1060 else{
1061 if( !this->ReturnType().IsNull() ){
1062 // Sub定義なのに、戻り値がある
1063 SmoothieException::Throw(38,this->GetName(),nowLine);
1064 }
1065 }
1066
1067 return true;
1068}
1069
1070int ProcPointers::Add( const string &typeExpression )
1071{
1072 DWORD dwProcType = (DWORD)typeExpression[2];
1073 const string &paramStr = typeExpression.substr( 3 );
1074
1075 Procedure::Kind kind = Procedure::Sub;
1076 if( dwProcType == ESC_FUNCTION ){
1077 kind = Procedure::Function;
1078 }
1079
1080 ProcPointer *pProcPointer = new ProcPointer( kind );
1081
1082 //buffer[0]は'('となっている
1083 extern int cp;
1084 pProcPointer->SetParamsAndReturnType( paramStr.c_str(), cp );
1085
1086 this->push_back( pProcPointer );
1087
1088 return (int)this->size()-1;
1089}
1090
1091void ProcPointers::Clear()
1092{
1093 ProcPointers &procPointers = *this;
1094 BOOST_FOREACH( ProcPointer *pProcPointer, procPointers ){
1095 delete pProcPointer;
1096 }
1097 this->clear();
1098}
Note: See TracBrowser for help on using the repository browser.