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

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