source: dev/BasicCompiler_Common/Procedure.cpp@ 79

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

バージョンをβ17にした。
#strictをデフォルトの状態で適用するようにした(#90)。
Dimステートメントにおいて、初期値式とAsが同時に指定されていたとき、As以降も初期値式の一部として捉えるよう、変更(#91)。
GetTypeDef関数を完全廃止。

File size: 15.2 KB
Line 
1#include "common.h"
2
3bool UserProc::SetParamsAndReturnType( const char *sourceOfParams, int nowLine, bool isStatic ){
4 int i = 0;
5 int i2,i3,sw;
6 char temporary[8192],temp2[VN_SIZE];
7
8 //ソースコードの位置
9 this->codePos = nowLine;
10
11 //パラメータ
12 if(sourceOfParams[i]!='('){
13 SetError(1,NULL,nowLine);
14 return 0;
15 }
16 i++;
17 if(sourceOfParams[i]!=')'&& this->pParentClass ){
18 //クラスのメンバ関数の場合のみ、デストラクタにパラメータがある場合にエラーをだす
19 if(this->GetName()[0]=='~'){
20 SetError(114,NULL,nowLine);
21 i=JumpStringInPare(sourceOfParams,i);
22 }
23 }
24 while(1){
25 if(sourceOfParams[i]==')') break;
26
27 //ByRef
28 bool isRef;
29 if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYVAL){
30 isRef = false;
31 i+=2;
32 }
33 else if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYREF){
34 isRef = true;
35 i+=2;
36 }
37 else isRef = false;
38
39 //パラメータ名
40 bool isArray = false;
41 int subScripts[MAX_ARRAYDIM];
42 char name[VN_SIZE];
43 sw=0;
44 for(i2=0;;i++,i2++){
45 if(sourceOfParams[i]=='('){
46 if(!sw) sw=1;
47
48 i3=GetStringInPare(name+i2,sourceOfParams+i);
49 i2+=i3-1;
50 i+=i3-1;
51 continue;
52 }
53 if(sourceOfParams[i]=='['){
54 if(!sw) sw=1;
55
56 i3=GetStringInBracket(name+i2,sourceOfParams+i);
57 i2+=i3-1;
58 i+=i3-1;
59 continue;
60 }
61 if(!IsVariableChar(sourceOfParams[i])){
62 name[i2]=0;
63 break;
64 }
65 name[i2]=sourceOfParams[i];
66 }
67 if(sw){
68 //配列パラメータ
69 if( isRef == false ) SetError(29,NULL,nowLine);
70 isArray = true;
71
72 if((name[i2-2]=='('&&name[i2-1]==')')||
73 (name[i2-2]=='['&&name[i2-1]==']')){
74 subScripts[0]=LONG_MAX;
75 subScripts[1]=-1;
76
77 name[i2-2]=0;
78 }
79 else{
80 GetArrange(name,temp2,subScripts);
81 lstrcpy(name,temp2);
82 }
83
84 i2=lstrlen(name);
85 }
86
87 Type type( DEF_NON );
88 char initValue[8192] = "";
89 if( sourceOfParams[i] == '=' ){
90 i++;
91 i = GetOneParameter( sourceOfParams, i, initValue );
92
93 //エラー用
94 cp = nowLine;
95
96 NumOpe_GetType( initValue, Type::String(), type );
97 }
98 else if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_AS){
99 i+=2;
100
101 i2=0;
102 while(sourceOfParams[i]=='*'){
103 temporary[i2]=sourceOfParams[i];
104 i++;
105 i2++;
106 }
107 for(;;i++,i2++){
108 if(!IsVariableChar(sourceOfParams[i])){
109 if(sourceOfParams[i]==1&&(sourceOfParams[i+1]==ESC_FUNCTION||sourceOfParams[i+1]==ESC_SUB)){
110 temporary[i2++]=sourceOfParams[i++];
111 temporary[i2]=sourceOfParams[i];
112 continue;
113 }
114 temporary[i2]=0;
115 break;
116 }
117 temporary[i2]=sourceOfParams[i];
118 }
119
120 Type::StringToType( temporary, type );
121
122 if( type.IsNull() ){
123 SetError(3,temporary,nowLine);
124 type.SetBasicType( DEF_PTR_VOID );
125 }
126 }
127 else{
128 type.SetBasicType( GetTypeFromSimpleName(temporary) );
129 SetError(-103,temporary,nowLine);
130 }
131
132 Parameter *pParam = new Parameter( name, type, isRef, initValue );
133 if( isArray ){
134 pParam->SetArray( subScripts );
135 }
136
137 //パラメータを追加
138 this->params.push_back( pParam );
139
140 if(sourceOfParams[i]==','){
141 i++;
142 continue;
143 }
144 else if(sourceOfParams[i]==')') continue;
145 else{
146 SetError(1,NULL,nowLine);
147 break;
148 }
149 }
150 this->secondParmNum = (int)this->params.size();
151 i++;
152 if(sourceOfParams[i]=='('){
153 i++;
154 while(1){
155 if(sourceOfParams[i]==')') break;
156
157 //ByRef
158 bool isRef;
159 if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYVAL){
160 isRef = false;
161 i+=2;
162 }
163 else if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYREF){
164 isRef = true;
165 i+=2;
166 }
167 else isRef = false;
168
169 //パラメータ名
170 bool isArray = false;
171 int subScripts[MAX_ARRAYDIM];
172 char name[VN_SIZE];
173 sw=0;
174 for(i2=0;;i++,i2++){
175 if(sourceOfParams[i]=='('){
176 if(!sw) sw=1;
177
178 i3=GetStringInPare(name+i2,sourceOfParams+i);
179 i2+=i3-1;
180 i+=i3-1;
181 continue;
182 }
183 if(sourceOfParams[i]=='['){
184 if(!sw) sw=1;
185
186 i3=GetStringInBracket(name+i2,sourceOfParams+i);
187 i2+=i3-1;
188 i+=i3-1;
189 continue;
190 }
191 if(!IsVariableChar(sourceOfParams[i])){
192 name[i2]=0;
193 break;
194 }
195 name[i2]=sourceOfParams[i];
196 }
197 if(sw){
198 //配列パラメータ
199 if( isRef == false ) SetError(29,NULL,nowLine);
200 isArray = true;
201
202 if((name[i2-2]=='('&&name[i2-1]==')')||
203 (name[i2-2]=='['&&name[i2-1]==']')){
204 subScripts[0]=LONG_MAX;
205 subScripts[1]=-1;
206
207 name[i2-2]=0;
208 }
209 else{
210 GetArrange(name,temp2,subScripts);
211 lstrcpy(name,temp2);
212 }
213
214 i2=lstrlen(name);
215 }
216
217 //型
218 Type type( DEF_NON );
219 if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_AS){
220 i+=2;
221
222 i2=0;
223 while(sourceOfParams[i]=='*'){
224 temporary[i2]=sourceOfParams[i];
225 i++;
226 i2++;
227 }
228 for(;;i++,i2++){
229 if(!IsVariableChar(sourceOfParams[i])){
230 if(sourceOfParams[i]==1&&(sourceOfParams[i+1]==ESC_FUNCTION||sourceOfParams[i+1]==ESC_SUB)){
231 temporary[i2++]=sourceOfParams[i++];
232 temporary[i2]=sourceOfParams[i];
233 continue;
234 }
235 temporary[i2]=0;
236 break;
237 }
238 temporary[i2]=sourceOfParams[i];
239 }
240
241 Type::StringToType( temporary, type );
242
243 if( type.IsNull() ){
244 SetError(3,temporary,nowLine);
245 type.SetBasicType( DEF_PTR_VOID );
246 }
247 }
248 else{
249 type.SetBasicType( GetTypeFromSimpleName(temporary) );
250 SetError(-103,temporary,nowLine);
251 }
252
253 Parameter *pParam = new Parameter( name, type, isRef );
254 if( isArray ){
255 pParam->SetArray( subScripts );
256 }
257
258 //パラメータを追加
259 this->params.push_back( pParam );
260
261 if(sourceOfParams[i]==','){
262 i++;
263 continue;
264 }
265 else if(sourceOfParams[i]==')') continue;
266 else{
267 SetError(1,NULL,nowLine);
268 break;
269 }
270 }
271 i++;
272 }
273
274 if(sourceOfParams[i]){
275 ///////////////////
276 // 戻り値を取得
277 ///////////////////
278
279 if( !this->IsFunction() ){
280 // Sub/Macroの場合
281 SetError(38,this->GetName(),nowLine);
282 }
283
284 if( this->pParentClass ){
285 if( this->GetName() == this->pParentClass->name ||
286 this->GetName()[0]=='~'){
287 //クラスのコンストラクタ、デストラクタがFunction定義の場合はエラーをだす
288 SetError(115,NULL,nowLine);
289 }
290 }
291
292
293 i2=lstrlen(sourceOfParams)-2;
294
295 int sw_as=0;
296 for(;i2>0;i2--){
297 if(sourceOfParams[i2]==')') break;
298
299 if(sourceOfParams[i2]==1&&sourceOfParams[i2+1]==ESC_AS){
300 i2+=2;
301 i3=0;
302 while(sourceOfParams[i2]=='*') temporary[i3++]=sourceOfParams[i2++];
303 for(;;i2++,i3++){
304 if(!IsVariableChar(sourceOfParams[i2])){
305 temporary[i3]=0;
306 break;
307 }
308 temporary[i3]=sourceOfParams[i2];
309 }
310 Type::StringToType( temporary, this->returnType );
311 if( this->returnType.IsNull() ) SetError(3,temporary,nowLine);
312
313 sw_as=1;
314 break;
315 }
316 }
317
318 if(!sw_as){
319 SetError(-104,this->GetName().c_str(),nowLine);
320
321 this->returnType.SetBasicType( DEF_DOUBLE );
322 }
323 }
324 else{
325 //戻り値なしのSub定義
326 this->returnType.SetNull();
327 }
328
329 //リアルパラメータ領域を取得(_System_LocalThisを考慮して2つだけ多く確保する場合がある)
330
331 if( this->pParentClass && isStatic == false ){
332 //オブジェクトメンバの場合は、第一パラメータを_System_LocalThis引き渡し用として利用
333 string name = "_System_LocalThis";
334 Type type( DEF_PTR_VOID );
335 this->realParams.push_back( new Parameter( name, type ) );
336 }
337
338 if( this->returnType.IsStruct() ){
339 //構造体を戻り値として持つ場合
340 //※第一パラメータ(Thisポインタありの場合は第二パラメータ)を戻り値用の参照宣言にする
341
342 string name = this->GetName();
343 if(name[0]==1&&name[1]==ESC_OPERATOR){
344 name="_System_ReturnValue";
345 }
346 Type type( DEF_STRUCT, this->returnType.GetIndex() );
347 this->realParams.push_back( new Parameter( name, type, true ) );
348 }
349
350 //パラメータをコピー
351 foreach( Parameter *pParam, params ){
352 this->realParams.push_back( new Parameter( *pParam ) );
353 }
354
355 return true;
356}
357
358bool DllProc::SetParamsAndReturnType( const char *sourceOfParams, int nowLine ){
359 int i = 0;
360 int i2,i3,sw;
361 char temporary[8192],temp2[VN_SIZE];
362
363 //ソースコードの位置
364 this->codePos = nowLine;
365
366 //パラメータ
367 if(sourceOfParams[i]!='('){
368 SetError(1,NULL,nowLine);
369 return 0;
370 }
371 i++;
372
373 while(1){
374 if(sourceOfParams[i]==')') break;
375
376 //ByRef
377 bool isRef;
378 if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYVAL){
379 isRef = false;
380 i+=2;
381 }
382 else if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYREF){
383 isRef = true;
384 i+=2;
385 }
386 else isRef = false;
387
388 //パラメータ名
389 bool isArray = false;
390 int subScripts[MAX_ARRAYDIM];
391 char name[VN_SIZE];
392 sw=0;
393 for(i2=0;;i++,i2++){
394 if(sourceOfParams[i]=='('){
395 if(!sw) sw=1;
396
397 i3=GetStringInPare(name+i2,sourceOfParams+i);
398 i2+=i3-1;
399 i+=i3-1;
400 continue;
401 }
402 if(sourceOfParams[i]=='['){
403 if(!sw) sw=1;
404
405 i3=GetStringInBracket(name+i2,sourceOfParams+i);
406 i2+=i3-1;
407 i+=i3-1;
408 continue;
409 }
410 if(!IsVariableChar(sourceOfParams[i])){
411 name[i2]=0;
412 break;
413 }
414 name[i2]=sourceOfParams[i];
415 }
416 if(sw){
417 //配列パラメータ
418 if( isRef == false ) SetError(29,NULL,nowLine);
419 isArray = true;
420
421 if((name[i2-2]=='('&&name[i2-1]==')')||
422 (name[i2-2]=='['&&name[i2-1]==']')){
423 subScripts[0]=LONG_MAX;
424 subScripts[1]=-1;
425
426 name[i2-2]=0;
427 }
428 else{
429 GetArrange(name,temp2,subScripts);
430 lstrcpy(name,temp2);
431 }
432
433 i2=lstrlen(name);
434 }
435
436 //型
437 Type type( DEF_NON );
438 if(lstrcmp(name,"...")==0) type.SetBasicType( DEF_ELLIPSE );
439 else if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_AS){
440 i+=2;
441
442 i2=0;
443 while(sourceOfParams[i]=='*'){
444 temporary[i2]=sourceOfParams[i];
445 i++;
446 i2++;
447 }
448 for(;;i++,i2++){
449 if(!IsVariableChar(sourceOfParams[i])){
450 if(sourceOfParams[i]==1&&(sourceOfParams[i+1]==ESC_FUNCTION||sourceOfParams[i+1]==ESC_SUB)){
451 temporary[i2++]=sourceOfParams[i++];
452 temporary[i2]=sourceOfParams[i];
453 continue;
454 }
455 temporary[i2]=0;
456 break;
457 }
458 temporary[i2]=sourceOfParams[i];
459 }
460
461 Type::StringToType( temporary, type );
462
463 if( type.IsNull() ){
464 SetError(3,temporary,nowLine);
465 type.SetBasicType( DEF_PTR_VOID );
466 }
467 }
468 else{
469 type.SetBasicType( GetTypeFromSimpleName(temporary) );
470 SetError(-103,temporary,nowLine);
471 }
472
473 Parameter *pParam = new Parameter( name, type, isRef );
474 if( isArray ){
475 pParam->SetArray( subScripts );
476 }
477
478 //パラメータを追加
479 this->params.push_back( pParam );
480
481 if(sourceOfParams[i]==','){
482 i++;
483 continue;
484 }
485 else if(sourceOfParams[i]==')') continue;
486 else{
487 SetError(1,NULL,nowLine);
488 break;
489 }
490 }
491 i++;
492
493 if(sourceOfParams[i]){
494 ///////////////////
495 // 戻り値を取得
496 ///////////////////
497
498 i2=lstrlen(sourceOfParams)-2;
499
500 int sw_as=0;
501 for(;i2>0;i2--){
502 if(sourceOfParams[i2]==')') break;
503
504 if(sourceOfParams[i2]==1&&sourceOfParams[i2+1]==ESC_AS){
505 i2+=2;
506 i3=0;
507 while(sourceOfParams[i2]=='*') temporary[i3++]=sourceOfParams[i2++];
508 for(;;i2++,i3++){
509 if(!IsVariableChar(sourceOfParams[i2])){
510 temporary[i3]=0;
511 break;
512 }
513 temporary[i3]=sourceOfParams[i2];
514 }
515 Type::StringToType( temporary, this->returnType );
516 if( this->returnType.IsNull() ) SetError(3,temporary,nowLine);
517
518 sw_as=1;
519 break;
520 }
521 }
522 }
523 else{
524 //戻り値なしのSub定義
525 this->returnType.SetNull();
526 }
527
528 return true;
529}
530
531bool ProcPointer::SetParamsAndReturnType( const char *sourceOfParams, int nowLine ){
532 int i = 0;
533 int i2,i3,sw;
534 char temporary[8192],temp2[VN_SIZE];
535
536 //ソースコードの位置
537 this->codePos = nowLine;
538
539 //パラメータ
540 if(sourceOfParams[i]!='('){
541 SetError(1,NULL,nowLine);
542 return 0;
543 }
544 i++;
545 while(1){
546 if(sourceOfParams[i]==')') break;
547
548 //ByRef
549 bool isRef;
550 if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYVAL){
551 isRef = false;
552 i+=2;
553 }
554 else if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYREF){
555 isRef = true;
556 i+=2;
557 }
558 else isRef = false;
559
560 //パラメータ名
561 bool isArray = false;
562 int subScripts[MAX_ARRAYDIM];
563 char name[VN_SIZE];
564 sw=0;
565 for(i2=0;;i++,i2++){
566 if(sourceOfParams[i]=='('){
567 if(!sw) sw=1;
568
569 i3=GetStringInPare(name+i2,sourceOfParams+i);
570 i2+=i3-1;
571 i+=i3-1;
572 continue;
573 }
574 if(sourceOfParams[i]=='['){
575 if(!sw) sw=1;
576
577 i3=GetStringInBracket(name+i2,sourceOfParams+i);
578 i2+=i3-1;
579 i+=i3-1;
580 continue;
581 }
582 if(!IsVariableChar(sourceOfParams[i])){
583 name[i2]=0;
584 break;
585 }
586 name[i2]=sourceOfParams[i];
587 }
588 if(sw){
589 //配列パラメータ
590 if( isRef == false ) SetError(29,NULL,nowLine);
591 isArray = true;
592
593 if((name[i2-2]=='('&&name[i2-1]==')')||
594 (name[i2-2]=='['&&name[i2-1]==']')){
595 subScripts[0]=LONG_MAX;
596 subScripts[1]=-1;
597
598 name[i2-2]=0;
599 }
600 else{
601 GetArrange(name,temp2,subScripts);
602 lstrcpy(name,temp2);
603 }
604
605 i2=lstrlen(name);
606 }
607
608 //型
609 Type type( DEF_NON );
610 if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_AS){
611 i+=2;
612
613 i2=0;
614 while(sourceOfParams[i]=='*'){
615 temporary[i2]=sourceOfParams[i];
616 i++;
617 i2++;
618 }
619 for(;;i++,i2++){
620 if(!IsVariableChar(sourceOfParams[i])){
621 if(sourceOfParams[i]==1&&(sourceOfParams[i+1]==ESC_FUNCTION||sourceOfParams[i+1]==ESC_SUB)){
622 temporary[i2++]=sourceOfParams[i++];
623 temporary[i2]=sourceOfParams[i];
624 continue;
625 }
626 temporary[i2]=0;
627 break;
628 }
629 temporary[i2]=sourceOfParams[i];
630 }
631
632 Type::StringToType( temporary, type );
633
634 if( type.IsNull() ){
635 SetError(3,temporary,nowLine);
636 type.SetBasicType( DEF_PTR_VOID );
637 }
638 }
639 else{
640 type.SetBasicType( GetTypeFromSimpleName(temporary) );
641 SetError(-103,temporary,nowLine);
642 }
643
644 Parameter *pParam = new Parameter( name, type, isRef );
645 if( isArray ){
646 pParam->SetArray( subScripts );
647 }
648
649 //パラメータを追加
650 this->params.push_back( pParam );
651
652 if(sourceOfParams[i]==','){
653 i++;
654 continue;
655 }
656 else if(sourceOfParams[i]==')') continue;
657 else{
658 SetError(1,NULL,nowLine);
659 break;
660 }
661 }
662 i++;
663
664 if(sourceOfParams[i]){
665 ///////////////////
666 // 戻り値を取得
667 ///////////////////
668
669 i2=lstrlen(sourceOfParams)-2;
670
671 int sw_as=0;
672 for(;i2>0;i2--){
673 if(sourceOfParams[i2]==')') break;
674
675 if(sourceOfParams[i2]==1&&sourceOfParams[i2+1]==ESC_AS){
676 i2+=2;
677 i3=0;
678 while(sourceOfParams[i2]=='*') temporary[i3++]=sourceOfParams[i2++];
679 for(;;i2++,i3++){
680 if(!IsVariableChar(sourceOfParams[i2])){
681 temporary[i3]=0;
682 break;
683 }
684 temporary[i3]=sourceOfParams[i2];
685 }
686 Type::StringToType( temporary, this->returnType );
687 if( this->returnType.IsNull() ) SetError(3,temporary,nowLine);
688
689 sw_as=1;
690 break;
691 }
692 }
693 }
694 else{
695 //戻り値なしのSub定義
696 this->returnType.SetNull();
697 }
698
699 //戻り値のエラーチェック
700 if( IsFunction() ){
701 // Function定義
702
703 if( this->ReturnType().IsNull() ){
704 // 戻り値がない
705 SetError(26,this->GetName(),nowLine);
706 }
707 }
708 else{
709 if( !this->ReturnType().IsNull() ){
710 // Sub定義なのに、戻り値がある
711 SetError(38,this->GetName(),nowLine);
712 }
713 }
714
715 return true;
716}
717
718UserProc *UserProc::pCompilingUserProc = NULL;
Note: See TracBrowser for help on using the repository browser.