source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/VariableOpe.cpp@ 759

Last change on this file since 759 was 750, checked in by イグトランス (egtra), 16 years ago

BOOST_FOREACHを可能なものはVC++ 2005 for eachへ置換(やや速くなる)。

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