source: dev/trunk/abdev/BasicCompiler_Common/VariableOpe.cpp@ 402

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

UserProc::SetParamsAndReturnTypeメソッドをリファクタリング
LexicalAnalysis.hのインクルードを除去した

File size: 25.8 KB
Line 
1#include "stdafx.h"
2
3#include <jenga/include/smoothie/Smoothie.h>
4
5#include <Compiler.h>
6#include <LexicalScope.h>
7#include <Variable.h>
8#include <NamespaceSupporter.h>
9
10#include "../BasicCompiler_Common/common.h"
11
12#ifdef _AMD64_
13#include "../BasicCompiler64/opcode.h"
14#else
15#include "../BasicCompiler32/opcode.h"
16#endif
17
18BOOL IsPtrType(int type){
19 if(type==-1) return 0;
20
21 if(PTR_LEVEL(type)||type==DEF_PTR_VOID||type==DEF_PTR_PROC||
22 (type&FLAG_PTR) ) return 1;
23
24 return 0;
25}
26BOOL IsSignedType(int type){
27 switch(type){
28 case DEF_SBYTE:
29 case DEF_INTEGER:
30 case DEF_LONG:
31 case DEF_INT64:
32 case DEF_SINGLE:
33 case DEF_DOUBLE:
34 case DEF_CHAR:
35 return 1;
36 default:
37 break;
38 }
39 return 0;
40}
41BOOL IsNaturalWholeNumberType(int type){
42 switch(type){
43 case DEF_SBYTE:
44 case DEF_BYTE:
45 case DEF_INTEGER:
46 case DEF_WORD:
47 case DEF_LONG:
48 case DEF_DWORD:
49 case DEF_INT64:
50 case DEF_QWORD:
51 case DEF_CHAR:
52 return 1;
53 default:
54 break;
55 }
56 return 0;
57}
58BOOL IsWholeNumberType(int type){
59 return (
60 IsNaturalWholeNumberType(type)
61 || IsPtrType(type)
62 || type == DEF_BOOLEAN
63 );
64}
65BOOL IsRealNumberType(int type){
66 switch(type){
67 case DEF_DOUBLE:
68 case DEF_SINGLE:
69 return 1;
70 default:
71 break;
72 }
73 return 0;
74}
75BOOL Is64Type(int type){
76 switch(type){
77 case DEF_INT64:
78 case DEF_QWORD:
79 return 1;
80 default:
81 break;
82 }
83#ifdef _AMD64_
84 return IsPtrType(type);
85#else
86 return 0;
87#endif
88}
89int GetSignedType(int type){
90 switch(type){
91 case DEF_BYTE:
92 return DEF_SBYTE;
93 case DEF_WORD:
94 return DEF_INTEGER;
95 case DEF_DWORD:
96 return DEF_LONG;
97 case DEF_QWORD:
98 return DEF_INT64;
99 default:
100 break;
101 }
102#ifdef _AMD64_
103 if(IsPtrType(type)) return DEF_INT64;
104#else
105 if(IsPtrType(type)) return DEF_LONG;
106#endif
107 return type;
108}
109int GetUnsignedType(int type){
110 switch(type){
111 case DEF_SBYTE:
112 return DEF_BYTE;
113 case DEF_INTEGER:
114 return DEF_WORD;
115 case DEF_LONG:
116 return DEF_DWORD;
117 case DEF_INT64:
118 return DEF_QWORD;
119 case DEF_CHAR:
120 if( Smoothie::IsUnicode() ) return DEF_WORD;
121 return DEF_BYTE;
122 }
123 return type;
124}
125int GetPtrType(int type){
126 return MAKE_PTR_TYPE(NATURAL_TYPE(type),PTR_LEVEL(type)+1);
127}
128BOOL GetTypeName(int type,LONG_PTR lpIndex,char *name){
129 if(PTR_LEVEL(type)){
130 //ポインタ型
131 name[0]='*';
132 return GetTypeName(MAKE_PTR_TYPE(NATURAL_TYPE(type),PTR_LEVEL(type)-1),lpIndex,name+1);
133 }
134
135 //整数型
136 if(type==DEF_SBYTE) lstrcpy(name,"SByte");
137 else if(type==DEF_BYTE) lstrcpy(name,"Byte");
138 else if(type==DEF_INTEGER) lstrcpy(name,"Integer");
139 else if(type==DEF_WORD) lstrcpy(name,"Word");
140 else if(type==DEF_LONG) lstrcpy(name,"Long");
141 else if(type==DEF_DWORD) lstrcpy(name,"DWord");
142 else if(type==DEF_INT64) lstrcpy(name,"Int64");
143 else if(type==DEF_QWORD) lstrcpy(name,"QWord");
144
145 //実数型
146 else if(type==DEF_SINGLE) lstrcpy(name,"Single");
147 else if(type==DEF_DOUBLE) lstrcpy(name,"Double");
148
149 //文字型
150 //else if(type==DEF_CHAR) lstrcpy(name,"Char");
151
152 //bool型
153 else if(type==DEF_BOOLEAN) lstrcpy(name,"Boolean");
154
155 //オブジェクト
156 else if(type==DEF_OBJECT || type==DEF_STRUCT){
157 if(lpIndex==0) lstrcpy(name,"non");
158 else{
159 lstrcpy(name,((CClass *)lpIndex)->GetName().c_str());
160 }
161 }
162
163 //ポインタ型
164 else if(type==DEF_PTR_VOID) lstrcpy(name,"VoidPtr");
165
166 else if(type==DEF_PTR_PROC){
167 if(lpIndex==-1) lstrcpy(name,"VoidPtr");
168 else{
169 if( compiler.GetObjectModule().meta.GetProcPointers()[lpIndex]->ReturnType().IsNull() )
170 lstrcpy(name,"*Sub");
171 else lstrcpy(name,"*Function");
172 }
173 }
174
175 else{
176 extern int cp;
177 SetError(1,NULL,cp);
178 return 0;
179 }
180 return 1;
181}
182
183Type GetStringTypeInfo(){
184 Type type( DEF_OBJECT, *compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr() );
185 return type;
186}
187
188void GetWithName(char *buffer){
189 extern WITHINFO WithInfo;
190 int i;
191
192 buffer[0]=0;
193 for(i=0;i<WithInfo.num;i++)
194 lstrcat(buffer,WithInfo.ppName[i]);
195}
196
197
198void GetArrange(char *variable,char *variAnswer, Subscripts &subscripts ){
199 extern int cp;
200 int i,i2,i4;
201 double dbl;
202 _int64 i64data;
203 BOOL bBracket;
204 char temporary[VN_SIZE];
205
206 for(i=0;;i++){
207 if(variable[i]=='('||variable[i]=='['){
208 if(variable[i]=='[') bBracket=1;
209 else bBracket=0;
210
211 variAnswer[i]=0;
212 for(i++,i2=0;;i++,i2++){
213 if(variable[i]==','){
214 temporary[i2]=0;
215
216 Type resultType;
217 if( !StaticCalculation(true, temporary,0,&i64data,resultType) ){
218 return;
219 }
220 if(resultType.IsReal()){
221 memcpy(&dbl,&i64data,sizeof(double));
222 i64data=(_int64)dbl;
223 }
224
225 if(i64data<0)
226 {
227 //error
228 subscripts.push_back( 0 );
229 }
230 else
231 {
232 subscripts.push_back( (int)i64data );
233 }
234 i2=-1;
235 continue;
236 }
237 if(variable[i]=='('){
238 i4=GetStringInPare(temporary+i2,variable+i);
239 i2+=i4-1;
240 i+=i4-1;
241 continue;
242 }
243 if(variable[i]=='['){
244 i4=GetStringInBracket(temporary+i2,variable+i);
245 i2+=i4-1;
246 i+=i4-1;
247 continue;
248 }
249 if(variable[i]==')'&&bBracket==0||
250 variable[i]==']'&&bBracket){
251 temporary[i2]=0;
252 if(i2==0){
253 subscripts.push_back( -2 );
254 break;
255 }
256
257 Type resultType;
258 if( !StaticCalculation(true, temporary,0,&i64data,resultType) ){
259 return;
260 }
261 if(resultType.IsReal()){
262 memcpy(&dbl,&i64data,sizeof(double));
263 i64data=(_int64)dbl;
264 }
265
266 if(i64data<0){
267 //error
268 subscripts.push_back( 0 );
269 }
270 else
271 {
272 subscripts.push_back( (int)i64data );
273 }
274 break;
275 }
276 if(variable[i]=='\"'){
277 SetError(1,NULL,cp);
278 return;
279 }
280 temporary[i2]=variable[i];
281 }
282 break;
283 }
284 variAnswer[i]=variable[i];
285 if(variable[i]=='\0'){
286 break;
287 }
288 }
289}
290
291
292BOOL GetVarFormatString(char *buffer,char *array,char *array2,char *NestMember,ReferenceKind &refType){
293 extern int cp;
294 int i,i2,i3;
295 char cPare_Open,cPare_Close;
296
297 array[0]=0;
298 array2[0]=0;
299 NestMember[0]=0;
300 for(i=0;;i++){
301 if(buffer[i]=='\"'){
302 for(i++;;i++){
303 if(IsDBCSLeadByte(buffer[i])){
304 i++;
305 continue;
306 }
307 if(buffer[i]=='\"') break;
308 }
309 }
310 if(buffer[i]=='['||buffer[i]=='('){
311 if(buffer[i]=='['){
312 cPare_Open='[';
313 cPare_Close=']';
314 }
315 else{
316 cPare_Open='(';
317 cPare_Close=')';
318 }
319 buffer[i]=0;
320 for(i++,i2=0;;i++,i2++){
321 if(buffer[i]==cPare_Open){
322 if(cPare_Open=='[') i3=GetStringInBracket(array+i2,buffer+i);
323 else i3=GetStringInPare(array+i2,buffer+i);
324 i+=i3-1;
325 i2+=i3-1;
326 continue;
327 }
328 if(buffer[i]==cPare_Close){
329 array[i2]=0;
330 break;
331 }
332 array[i2]=buffer[i];
333 }
334 if(buffer[i+1]==cPare_Open){
335 for(i+=2,i2=0;;i++,i2++){
336 if(buffer[i]==cPare_Open){
337 if(cPare_Open=='[') i3=GetStringInBracket(array2+i2,buffer+i);
338 else i3=GetStringInPare(array2+i2,buffer+i);
339 i+=i3-1;
340 i2+=i3-1;
341 continue;
342 }
343 if(buffer[i]==cPare_Close){
344 array2[i2]=0;
345 break;
346 }
347 array2[i2]=buffer[i];
348 }
349 if(buffer[i+1]==cPare_Open){
350 SetError(14,buffer,cp);
351 return 0;
352 }
353 }
354 continue;
355 }
356 if(buffer[i]=='.'){
357 lstrcpy(NestMember,buffer+i+1);
358 refType = RefDot;
359 buffer[i]=0;
360 break;
361 }
362 if(buffer[i]==1&&buffer[i+1]==ESC_PSMEM){
363 lstrcpy(NestMember,buffer+i+2);
364 refType = RefPointer;
365 buffer[i]=0;
366 break;
367 }
368 if(buffer[i]=='\0') break;
369 }
370 return 1;
371}
372
373void GetArrayElement( const char *buffer,char *variable,char *array_element){
374 array_element[0]=0;
375
376 if(buffer[lstrlen(buffer)-1]!=']'){
377 lstrcpy(variable,buffer);
378 return;
379 }
380
381 int i,i2;
382 for(i=0;;i++){
383 if(buffer[i]=='\0') break;
384 if(buffer[i]=='['){
385 i2=GetStringInBracket(array_element,buffer+i);
386 i+=i2-1;
387 continue;
388 }
389 }
390
391 lstrcpy(variable,buffer);
392 variable[lstrlen(variable)-lstrlen(array_element)]=0;
393
394 RemoveStringBracket(array_element);
395}
396
397BOOL CheckVarNameError(char *name,int nowLine){
398 int i2;
399
400 if(!IsVariableTopChar(name[0])){
401 SetError(1,NULL,nowLine);
402 return 0;
403 }
404 for(i2=1;;i2++){
405 if(name[i2]=='\0') break;
406 if(!IsVariableChar(name[i2])){
407 SetError(1,NULL,nowLine);
408 return 0;
409 }
410 }
411 return 1;
412}
413
414int JumpSubScripts( const Subscripts &subscripts ){
415 //DIMで定義された並んだ配列の数だけアドレスを進める
416 int i, i2;
417 for( i=0,i2=1; i<(int)subscripts.size(); i++ ){
418 i2 *= subscripts[i] + 1;
419 }
420 return i2;
421}
422
423
424bool GetMemberType( const Type &classType, const char *lpszMember, Type &resultType, BOOL bPrivateAccess, bool isErrorEnabled)
425{
426 const CClass &objClass = classType.GetClass();
427
428 extern int cp;
429
430 //クラス、配列の構成要素を解析する
431 char VarName[VN_SIZE]; //変数名
432 char array[VN_SIZE]; //第1次配列
433 char lpPtrOffset[VN_SIZE]; //第2次配列
434 char NestMember[VN_SIZE]; //入れ子メンバ
435 ReferenceKind refType = RefNon;
436 lstrcpy(VarName,lpszMember);
437 if(!GetVarFormatString(VarName,array,lpPtrOffset,NestMember,refType)) return false;
438
439 bool isFound = false;
440 CMember *pMember = NULL;
441 BOOST_FOREACH( pMember, objClass.GetDynamicMembers() ){
442 if( pMember->GetName() == VarName ){
443 isFound = true;
444 break;
445 }
446 }
447 if( !isFound ){
448 if(isErrorEnabled) SetError(103,VarName,cp);
449 return false;
450 }
451
452 //アクセシビリティをチェック
453 if( &objClass == compiler.pCompilingClass ){
454 //同一クラスオブジェクトの場合はプライベートアクセスを容認する
455 if( pMember->IsNoneAccess() ){
456 if(isErrorEnabled) SetError(107,VarName,cp);
457 return false;
458 }
459 }
460 else{
461 if(( bPrivateAccess==0 && pMember->IsPrivate() )||
462 pMember->IsNoneAccess() ){
463 if(isErrorEnabled) SetError(107,VarName,cp);
464 return false;
465 }
466 else if( bPrivateAccess==0 && pMember->IsProtected() ){
467 if(isErrorEnabled) SetError(108,VarName,cp);
468 return false;
469 }
470 }
471
472 resultType = pMember->GetType();
473
474 // 型パラメータを解決
475 ResolveFormalGenericTypeParameter( resultType, classType );
476
477
478 //ポインタ変数の場合
479 if( resultType.IsPointer() ){
480 if( pMember->GetSubscripts().size() == 0 ){
481 lstrcpy(lpPtrOffset,array);
482 array[0]=0;
483 }
484 }
485 else{
486 if(lpPtrOffset[0]){
487 if(isErrorEnabled) SetError(16,lpszMember,cp);
488 return false;
489 }
490 }
491
492 if(array[0]){
493 //配列オフセット
494 if( pMember->GetSubscripts().size() <= 0 )
495 {
496 // 配列ではないメンバに配列指定をした
497 return false;
498 }
499 }
500 else if( pMember->GetSubscripts().size() > 0 ){
501 resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR );
502 }
503
504 if( refType != RefNon ){
505 //入れ子構造の場合
506
507 return GetMemberType( pMember->GetType(),
508 NestMember,
509 resultType,
510 0,
511 isErrorEnabled);
512 }
513
514 if(lpPtrOffset[0]){
515 if( resultType.PtrLevel() ){
516 resultType.PtrLevelDown();
517 }
518 else{
519 //エラー
520 if(isErrorEnabled) SetError(1,NULL,cp);
521 return false;
522 }
523 }
524
525 return true;
526}
527bool GetVarType( const char *nameBuffer, Type &resultType, bool isErrorEnabled){
528 char variable[VN_SIZE];
529
530 if(nameBuffer[0]=='.'){
531 GetWithName(variable);
532 lstrcat(variable,nameBuffer);
533 }
534 else lstrcpy(variable,nameBuffer);
535
536 // 名前空間を分離
537 char namespaceStr[VN_SIZE]="", simpleName[VN_SIZE];
538 compiler.GetObjectModule().meta.GetNamespaces().SplitNamespace( variable, namespaceStr, simpleName );
539
540 // 先頭オブジェクトまたはクラス名と入れ子メンバに分割
541 ReferenceKind refType;
542 char member[VN_SIZE],array[VN_SIZE],lpPtrOffset[VN_SIZE];
543 GetVarFormatString(simpleName,array,lpPtrOffset,member,refType);
544
545 // 名前空間を分離していた場合は結合
546 char VarName[VN_SIZE];
547 if( namespaceStr[0] ){
548 sprintf( VarName, "%s.%s", namespaceStr, simpleName );
549 }
550 else{
551 lstrcpy( VarName, simpleName );
552 }
553
554 const Variable *pVar = NULL;
555
556 if( UserProc::IsLocalAreaCompiling() ){
557 /////////////////
558 // ローカル変数
559 /////////////////
560
561 pVar = UserProc::CompilingUserProc().GetLocalVars().BackSearch( Symbol( VarName ) );
562 if( pVar ){
563 goto ok;
564 }
565 }
566
567 if(compiler.pCompilingClass){
568 ///////////////////////
569 // クラスメンバの参照
570 ///////////////////////
571
572 if(lstrcmpi(variable,"This")==0){
573 //Thisオブジェクト
574 resultType.SetType( DEF_OBJECT, compiler.pCompilingClass );
575 return true;
576 }
577
578 if(memicmp(variable,"This.",5)==0){
579 //Thisオブジェクトのメンバを参照するとき
580 SlideString(variable+5,-5);
581 lstrcpy(VarName,variable);
582 }
583 else{
584 //クラス内メンバを参照するとき(通常)
585
586 bool isFound = false;
587 BOOST_FOREACH( CMember *pMember, compiler.pCompilingClass->GetDynamicMembers() ){
588 if( pMember->GetName() == VarName ){
589 isFound = true;
590 break;
591 }
592 }
593 if( !isFound ) goto NonClassMember;
594 }
595
596 return GetMemberType(
597 Type( DEF_OBJECT, *compiler.pCompilingClass ),
598 variable,
599 resultType,
600 1,
601 isErrorEnabled
602 );
603 }
604
605NonClassMember:
606
607 //////////////////////////
608 // 静的ローカル変数
609 // ※"Static.Object.Method.Variable"
610 //////////////////////////
611
612 char temporary[VN_SIZE];
613 if( UserProc::IsLocalAreaCompiling() ){
614 GetNowStaticVarFullName(VarName,temporary);
615
616 pVar = compiler.GetObjectModule().meta.GetGlobalVars().Find( Symbol( temporary ) );
617 if( pVar ){
618 goto ok;
619 }
620 }
621
622
623 //////////////////////////
624 // クラスの静的メンバ
625 //////////////////////////
626
627 if(member[0]){
628 lstrcpy(temporary,member);
629 char tempMember[VN_SIZE];
630 char tempArray[VN_SIZE];
631 {
632 ReferenceKind refType;
633 GetVarFormatString(temporary,tempArray,lpPtrOffset,tempMember,refType);
634 }
635
636 int typeDefIndex = compiler.GetObjectModule().meta.GetTypeDefs().GetIndex( VarName );
637 if( typeDefIndex != -1 ){
638 // TypeDef後の型名だったとき
639 lstrcpy( VarName, compiler.GetObjectModule().meta.GetTypeDefs()[typeDefIndex].GetBaseName().c_str() );
640 }
641
642 char temp2[VN_SIZE];
643 sprintf(temp2,"%s.%s",VarName,temporary);
644
645 pVar = compiler.GetObjectModule().meta.GetGlobalVars().Find( Symbol( temp2 ) );
646 if( pVar ){
647 lstrcpy(member,tempMember);
648 lstrcpy(array,tempArray);
649 goto ok;
650 }
651 }
652
653 if(compiler.pCompilingClass){
654 //自身のクラスから静的メンバを参照する場合
655 char temp2[VN_SIZE];
656 sprintf(temp2,"%s.%s",compiler.pCompilingClass->GetName().c_str(),VarName);
657
658 pVar = compiler.GetObjectModule().meta.GetGlobalVars().Find( Symbol( temp2 ) );
659 if( pVar ){
660 goto ok;
661 }
662 }
663
664
665 ////////////////////
666 // グローバル変数
667 ////////////////////
668
669 pVar = compiler.GetObjectModule().meta.GetGlobalVars().BackSearch( Symbol( VarName ) );
670 if( pVar ){
671 goto ok;
672 }
673
674 //変数として見つからなかったとき
675 if(isErrorEnabled) SetError(3,variable,cp);
676 return false;
677
678ok:
679
680 //ポインタ変数の場合
681 if( pVar->GetType().IsPointer() ){
682 if( !pVar->IsArray() ){
683 lstrcpy(lpPtrOffset,array);
684 array[0]=0;
685 }
686 }
687 else{
688 if(lpPtrOffset[0]){
689 if(isErrorEnabled) SetError(16,variable,cp);
690 return false;
691 }
692 }
693
694 resultType = pVar->GetType();
695
696 if(member[0]){
697 if( NATURAL_TYPE( resultType.GetBasicType() )==DEF_OBJECT
698 || NATURAL_TYPE( resultType.GetBasicType() )==DEF_STRUCT)
699 {
700 return GetMemberType(resultType,member,resultType,0,isErrorEnabled);
701 }
702 }
703
704 if( array[0] == 0 && pVar->GetSubscripts().size() > 0 ){
705 //配列の先頭ポインタを示す場合
706 resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR );
707 }
708
709 if(lpPtrOffset[0]){
710 if( resultType.PtrLevel() ){
711 resultType.PtrLevelDown();
712 }
713 else{
714 //エラー
715 if(isErrorEnabled) SetError(1,NULL,cp);
716 return false;
717 }
718 }
719
720 return true;
721}
722
723bool GetVarOffsetReadOnly(const char *NameBuffer,RELATIVE_VAR *pRelativeVar,Type &resultType, Subscripts *pResultSubscripts )
724{
725 //読み取り専用で変数へアクセス
726 return GetVarOffset(
727 true, //エラー表示有効
728 false, //書き込みアクセスは無し
729 NameBuffer,
730 pRelativeVar,
731 resultType,
732 pResultSubscripts
733 );
734}
735bool GetVarOffsetReadWrite(const char *NameBuffer,RELATIVE_VAR *pRelativeVar,Type &resultType, Subscripts *pResultSubscripts )
736{
737 //読み書き両用で変数へアクセス
738 return GetVarOffset(
739 true, //エラー表示有効
740 true, //書き込みアクセス
741 NameBuffer,
742 pRelativeVar,
743 resultType,
744 pResultSubscripts
745 );
746}
747
748
749
750bool GetDimentionFormat( const char *buffer,
751 char *VarName,
752 Subscripts &subscripts,
753 Type &type,
754 char *InitBuf,
755 char *ConstractParameter ){
756 int i,i2,i3,IsStr;
757 char variable[VN_SIZE],temporary[8192];
758
759 for(i=0;;i++){
760 if((buffer[i]==1&&buffer[i+1]==ESC_AS)||
761 buffer[i]=='='||
762 buffer[i]=='\0'){
763 variable[i]=0;
764 break;
765 }
766 variable[i]=buffer[i];
767 }
768
769 if(buffer[i]=='='){
770 ////////////////////////////////////
771 // 初期化データが指定されいるとき
772 ////////////////////////////////////
773 i++;
774
775 if( buffer[i]=='[' ){
776 // 構造初期データの場合
777
778 i3=GetStringInBracket(InitBuf,buffer+i);
779 i+=i3;
780 }
781 else{
782 // 代入初期データの場合
783
784 for(i2=0,IsStr=0;;i++,i2++){
785 if(buffer[i]=='\"') IsStr^=1;
786 if(buffer[i]=='('&&IsStr==0){
787 i3=GetStringInPare(InitBuf+i2,buffer+i);
788 i+=i3-1;
789 i2+=i3-1;
790 continue;
791 }
792 if(buffer[i]=='['&&IsStr==0){
793 i3=GetStringInBracket(InitBuf+i2,buffer+i);
794 i+=i3-1;
795 i2+=i3-1;
796 continue;
797 }
798 if((buffer[i]==','&&IsStr==0)||
799 buffer[i]=='\0'){
800 InitBuf[i2]=0;
801 break;
802 }
803 InitBuf[i2]=buffer[i];
804 }
805 }
806 }
807 else{
808 //初期化データなし
809 InitBuf[0]=0;
810 }
811
812 ConstractParameter[0]=0;
813 if(buffer[i]==1&&buffer[i+1]==ESC_AS){
814 /////////////////////////////
815 // "As ~" による型指定あり
816 /////////////////////////////
817
818 for(i+=2,i2=0;;i++,i2++){
819 if(buffer[i]=='('||buffer[i]=='\0'){
820 temporary[i2]=0;
821 break;
822 }
823 temporary[i2]=buffer[i];
824 }
825 if(temporary[0]=='*'&&
826 temporary[1]==1&&
827 (temporary[2]==ESC_FUNCTION||temporary[2]==ESC_SUB)){
828 if(buffer[i]!='('){
829 SetError(10,temporary,cp);
830 return false;
831 }
832 i3=GetStringInPare(temporary+3,buffer+i);
833 i+=i3;
834 i2+=i3;
835
836 if(temporary[2]==ESC_FUNCTION&&buffer[i]==1&&buffer[i+1]==ESC_AS){
837 temporary[i2++]=buffer[i++];
838 temporary[i2++]=buffer[i++];
839 for(;;i++,i2++){
840 if(!IsVariableChar(buffer[i])){
841 temporary[i2]=0;
842 break;
843 }
844 temporary[i2]=buffer[i];
845 }
846 }
847 }
848
849 if( !compiler.StringToType( temporary, type ) ){
850 SetError(3,temporary,cp);
851 return false;
852 }
853
854 if(buffer[i]=='('){
855 //コンストラクタに渡すパラメータを取得
856 i2=GetStringInPare(ConstractParameter,buffer+i);
857 i+=i2;
858 RemoveStringPare(ConstractParameter);
859
860 if( !type.IsObject() ){
861 SetError(112,variable,cp);
862 return false;
863 }
864 }
865 }
866 else{
867 /////////////////
868 // As指定なし
869 /////////////////
870
871 if( InitBuf[0] == '\0' ){
872 //As指定も、初期値指定もない場合
873 type.SetBasicType( Type::GetBasicTypeFromSimpleName(variable) );
874
875 i2=lstrlen(variable)-1;
876 if(i2>=0){
877 if(!(variable[i2]=='#'||variable[i2]=='!'||variable[i2]=='%'||variable[i2]=='$'))
878 SetError(-103,variable,cp);
879 }
880 }
881 else{
882 //初期値の型を判別して自動的に型情報を付加する
883 if( !NumOpe_GetType( InitBuf, GetStringTypeInfo(), type ) ){
884 // エラーの場合
885 return false;
886 }
887
888 if( IS_LITERAL( type.GetIndex() ) ){
889 type.SetIndex( -1 );
890 }
891 }
892
893 }
894
895 if( InitBuf[0] != '\0' && ConstractParameter[0] != '\0' ){
896 //初期値とコンストラクタパラメータが同時に呼び出されているとき
897 SetError(132, NULL, cp);
898 }
899
900 GetArrange(variable,VarName,subscripts);
901 return true;
902}
903
904BOOL GetNowStaticVarFullName(char *VarName,char *FullName){
905 if( UserProc::IsGlobalAreaCompiling() ){
906 // グローバル領域をコンパイル中のとき
907 return 0;
908 }
909
910 const UserProc &proc = UserProc::CompilingUserProc();
911
912 //Static識別
913 lstrcpy(FullName,"Static%");
914
915 //クラス名
916 if(compiler.pCompilingClass){
917 lstrcat(FullName,compiler.pCompilingClass->GetName().c_str());
918 lstrcat(FullName,"%");
919 }
920
921 //関数(またはメソッド)名
922 lstrcat(FullName,proc.GetName().c_str());
923 lstrcat(FullName,"%");
924
925 //ID
926 char temp[255];
927 sprintf(temp,"%x",proc.GetId());
928 lstrcat(FullName,temp);
929 lstrcat(FullName,"%");
930
931 //変数名
932 lstrcat(FullName,VarName);
933
934 return 1;
935}
936
937
938void AddGlobalVariable( const char *name, const Subscripts &subscripts, const Type &type,const char *InitBuf,const char *ConstractParameter,DWORD dwFlag){
939 /////////////////////////
940 // グローバル変数を追加
941 /////////////////////////
942
943 if( compiler.GetObjectModule().meta.GetGlobalVars().DuplicateCheck( Symbol( name ) ) ){
944 //2重定義のエラー
945 SetError(15,name,cp);
946 return;
947 }
948
949 bool isConst = ( dwFlag & DIMFLAG_CONST ) ? true:false;
950
951 Variable *pVar = new Variable(
952 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes(),
953 name,
954 type,
955 isConst,
956 false,
957 ConstractParameter,
958 ( InitBuf[0] != 0 || dwFlag == DIMFLAG_INITDEBUGVAR )
959 );
960
961 if( subscripts.size() > 0 ){
962 //配列あり
963 pVar->SetArray( subscripts );
964 }
965
966 //レキシカルスコープ
967 pVar->SetScopeLevel( compiler.codeGenerator.lexicalScopes.GetNowLevel() );
968 pVar->SetScopeStartAddress( compiler.codeGenerator.lexicalScopes.GetStartAddress() );
969 pVar->isLiving = true;
970
971 //エラー用
972 pVar->source_code_address=cp;
973
974 // 変数を追加
975 compiler.GetObjectModule().meta.GetGlobalVars().Add( pVar );
976
977 if(InitBuf[0]){
978 int result = 0;
979 if( !pVar->GetType().IsObject() ){
980 result = SetInitGlobalData(pVar->GetOffsetAddress(),
981 pVar->GetType(),
982 pVar->GetSubscripts(),
983 InitBuf);
984 }
985
986 if(!result){
987 //動的な式だった場合は代入演算を行う
988
989 //初期代入時のみ、書き込みアクセスを許可する
990 if( isConst ){
991 pVar->ConstOff();
992 }
993
994 //代入
995 char temporary[8192];
996 sprintf(temporary,"%s=%s",name,InitBuf);
997 OpcodeCalc(temporary);
998
999 //アクセス制限を元に戻す
1000 if( isConst ){
1001 pVar->ConstOn();
1002 }
1003 }
1004 }
1005
1006
1007 if( type.IsObject() ){
1008 //デストラクタの利用フラグをオンにする
1009 const CMethod *method = type.GetClass().GetDestructorMethod();
1010 if( method ){
1011 method->GetUserProc().Using();
1012 }
1013 }
1014}
1015
1016void dim(char *Parameter,DWORD dwFlags){
1017 extern HANDLE hHeap;
1018 int i2;
1019 char VarName[VN_SIZE];
1020
1021 i2 = 0;
1022
1023 if( Parameter[i2] == 1 && Parameter[i2+1] == ESC_BYREF ){
1024 //参照型
1025 SetError();
1026 Parameter += 2;
1027 }
1028
1029 if(dwFlags & DIMFLAG_CONST){
1030
1031 //////////////////////////////////
1032 // 定数変数の場合を考慮
1033 //////////////////////////////////
1034 for(;;i2++){
1035 if(Parameter[i2] == '=' ||
1036 Parameter[i2] == 1 && Parameter[i2] == ESC_AS ||
1037 Parameter[i2] =='('){
1038 VarName[i2] = 0;
1039 break;
1040 }
1041 VarName[i2] = Parameter[i2];
1042 }
1043
1044 //定数と2重定義されていないる場合は抜け出す
1045 if(compiler.GetObjectModule().meta.GetGlobalConsts().GetBasicType(VarName)){
1046 return;
1047 }
1048
1049 //定数マクロとして定義されている場合は抜け出す
1050 if( compiler.GetObjectModule().meta.GetGlobalConstMacros().IsExist( VarName ) )
1051 {
1052 return;
1053 }
1054 }
1055
1056
1057 //構文を解析
1058 Type type;
1059 char InitBuf[8192];
1060 char ConstractParameter[VN_SIZE];
1061 Subscripts subscripts;
1062 if(!GetDimentionFormat(Parameter, VarName,subscripts,type,InitBuf,ConstractParameter))
1063 return;
1064
1065
1066 //定数と2重定義されていないかを調べる
1067 if(compiler.GetObjectModule().meta.GetGlobalConsts().GetBasicType(VarName)){
1068 SetError(15,VarName,cp);
1069 return;
1070 }
1071
1072 //定数マクロとして定義されている場合
1073 if( compiler.GetObjectModule().meta.GetGlobalConstMacros().IsExist( VarName ) ){
1074 SetError(15,VarName,cp);
1075 return;
1076 }
1077
1078 if( type.IsObject() ){
1079 if( type.GetClass().IsBlittableType() ){
1080 // Blittable型のときは基本型として扱う
1081 // ※ただし、コンパイル中のメソッドがBlittable型クラスに属していないこと
1082 if( UserProc::IsLocalAreaCompiling()
1083 && UserProc::CompilingUserProc().HasParentClass()
1084 && UserProc::CompilingUserProc().GetParentClass().IsBlittableType() )
1085 {
1086 // コンパイル中のメソッドがBlittable型クラスに属している
1087 }
1088 else{
1089 type = type.GetClass().GetBlittableType();
1090 }
1091 }
1092 }
1093
1094 if(dwFlags&DIMFLAG_STATIC){
1095 if( UserProc::IsGlobalAreaCompiling() ){
1096 SetError(60,NULL,cp);
1097 return;
1098 }
1099
1100 /////////////////////
1101 // Static変数
1102 // ※"Static.Object.Method.Variable"
1103 /////////////////////
1104
1105 char temporary[VN_SIZE];
1106 GetNowStaticVarFullName(VarName,temporary);
1107
1108 dim( temporary,subscripts,type,InitBuf,ConstractParameter,dwFlags );
1109
1110 /*
1111 Note: 静的変数のコンストラクタ呼び出しは
1112 _System_InitStaticLocalVariables関数内で一括して行う
1113 */
1114 }
1115 else{
1116 dim( VarName,subscripts,type,InitBuf,ConstractParameter,dwFlags );
1117 }
1118}
1119void OpcodeDim(char *Parameter,DWORD dwFlags){
1120 int i,i2,i3,IsStr=0;
1121 char temporary[8192];
1122
1123 for(i=0,i2=0;;i++,i2++){
1124 if(Parameter[i]=='\"') IsStr^=1;
1125 if(Parameter[i]=='('&&IsStr==0){
1126 i3=GetStringInPare(temporary+i2,Parameter+i);
1127 i+=i3-1;
1128 i2+=i3-1;
1129 continue;
1130 }
1131 if(Parameter[i]=='['&&IsStr==0){
1132 i3=GetStringInBracket(temporary+i2,Parameter+i);
1133 i+=i3-1;
1134 i2+=i3-1;
1135 continue;
1136 }
1137 if( Parameter[i] == '<' && IsStr == 0 )
1138 {
1139 if( IsGenericTypeSourcePart( Parameter + i ) )
1140 {
1141 // ジェネリクス構文
1142 i3=GetStringInGenericBracket(temporary+i2,Parameter+i);
1143 i+=i3-1;
1144 i2+=i3-1;
1145 continue;
1146 }
1147 else
1148 {
1149 // 一般構文
1150 }
1151 }
1152 if((Parameter[i]==','&&IsStr==0)||
1153 Parameter[i]=='\0'){
1154 temporary[i2]=0;
1155
1156 dim(temporary,dwFlags);
1157
1158 if(Parameter[i]=='\0') break;
1159 i2=-1;
1160 continue;
1161 }
1162 temporary[i2]=Parameter[i];
1163 }
1164}
1165
1166void DebugVariable(void)
1167{
1168 char temporary[255];
1169 if( compiler.GetObjectModule().meta.GetGlobalVars().Find( Symbol( "_DebugSys_dwThreadID" ) ) == NULL )
1170 {
1171 // 未定義の場合は定義する
1172 sprintf(temporary,"_DebugSys_dwThreadID[255]%c%cDWord",1,ESC_AS);
1173 OpcodeDim(temporary,DIMFLAG_INITDEBUGVAR);
1174 sprintf(temporary,"_DebugSys_ProcNum[255]%c%cDWord",1,ESC_AS);
1175 OpcodeDim(temporary,DIMFLAG_INITDEBUGVAR);
1176 sprintf(temporary,"_DebugSys_lplpObp[255]%c%c*ULONG_PTR",1,ESC_AS);
1177 OpcodeDim(temporary,DIMFLAG_INITDEBUGVAR);
1178 sprintf(temporary,"_DebugSys_lplpSpBase[255]%c%c*ULONG_PTR",1,ESC_AS);
1179 OpcodeDim(temporary,DIMFLAG_INITDEBUGVAR);
1180 }
1181}
Note: See TracBrowser for help on using the repository browser.