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

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

静的メソッドのデリゲートに対応

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