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

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