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

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

System名前空間をImportsしているときにNew演算子にBlittable型を("System." を省略する形で)指定するとコンパイルエラーになるバグを修正。

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