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

Last change on this file since 400 was 400, checked in by dai_9181, 16 years ago

LexicalAnalysis.cppを除去した

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