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

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

ジェネリクスのベースを実装

File size: 25.3 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 /////////////////////////////////////////////////////////
477 // ☆★☆ ジェネリクスサポート ☆★☆
478
479 if( resultType.IsTypeParameter() )
480 {
481 // 型パラメータだったとき
482 if( classType.HasActualGenericType() )
483 {
484 // TODO: GetDummyActualGenericTypeを適切な形に実装し直す
485 resultType = classType.GetDummyActualGenericType();
486 }
487 else
488 {
489 // TODO: ベースオブジェクト(指定されていないときはObjectクラス)にセットする
490 resultType.SetBasicType( DEF_OBJECT );
491 }
492 }
493
494 //
495 /////////////////////////////////////////////////////////
496
497
498 //ポインタ変数の場合
499 if( resultType.IsPointer() ){
500 if( pMember->GetSubscripts().size() == 0 ){
501 lstrcpy(lpPtrOffset,array);
502 array[0]=0;
503 }
504 }
505 else{
506 if(lpPtrOffset[0]){
507 if(isErrorEnabled) SetError(16,lpszMember,cp);
508 return false;
509 }
510 }
511
512 if( refType != RefNon ){
513 //入れ子構造の場合
514
515 return GetMemberType( pMember->GetType(),
516 NestMember,
517 resultType,
518 0,
519 isErrorEnabled);
520 }
521
522 if( array[0] == 0 && pMember->GetSubscripts().size() > 0 ){
523 resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR );
524 return true;
525 }
526
527 if(lpPtrOffset[0]){
528 if( resultType.PtrLevel() ){
529 resultType.PtrLevelDown();
530 }
531 else{
532 //エラー
533 if(isErrorEnabled) SetError(1,NULL,cp);
534 return false;
535 }
536 }
537
538 return true;
539}
540bool GetVarType( const char *nameBuffer, Type &resultType, bool isErrorEnabled){
541 char variable[VN_SIZE];
542
543 if(nameBuffer[0]=='.'){
544 GetWithName(variable);
545 lstrcat(variable,nameBuffer);
546 }
547 else lstrcpy(variable,nameBuffer);
548
549 // 名前空間を分離
550 char namespaceStr[VN_SIZE]="", simpleName[VN_SIZE];
551 compiler.GetObjectModule().meta.GetNamespaces().SplitNamespace( variable, namespaceStr, simpleName );
552
553 // 先頭オブジェクトまたはクラス名と入れ子メンバに分割
554 ReferenceKind refType;
555 char member[VN_SIZE],array[VN_SIZE],lpPtrOffset[VN_SIZE];
556 GetVarFormatString(simpleName,array,lpPtrOffset,member,refType);
557
558 // 名前空間を分離していた場合は結合
559 char VarName[VN_SIZE];
560 if( namespaceStr[0] ){
561 sprintf( VarName, "%s.%s", namespaceStr, simpleName );
562 }
563 else{
564 lstrcpy( VarName, simpleName );
565 }
566
567 const Variable *pVar = NULL;
568
569 if( UserProc::IsLocalAreaCompiling() ){
570 /////////////////
571 // ローカル変数
572 /////////////////
573
574 pVar = UserProc::CompilingUserProc().GetLocalVars().BackSearch( Symbol( VarName ) );
575 if( pVar ){
576 goto ok;
577 }
578 }
579
580 if(compiler.pCompilingClass){
581 ///////////////////////
582 // クラスメンバの参照
583 ///////////////////////
584
585 if(lstrcmpi(variable,"This")==0){
586 //Thisオブジェクト
587 resultType.SetType( DEF_OBJECT, compiler.pCompilingClass );
588 return true;
589 }
590
591 if(memicmp(variable,"This.",5)==0){
592 //Thisオブジェクトのメンバを参照するとき
593 SlideString(variable+5,-5);
594 lstrcpy(VarName,variable);
595 }
596 else{
597 //クラス内メンバを参照するとき(通常)
598
599 bool isFound = false;
600 BOOST_FOREACH( CMember *pMember, compiler.pCompilingClass->GetDynamicMembers() ){
601 if( pMember->GetName() == VarName ){
602 isFound = true;
603 break;
604 }
605 }
606 if( !isFound ) goto NonClassMember;
607 }
608
609 return GetMemberType(
610 Type( DEF_OBJECT, *compiler.pCompilingClass ),
611 variable,
612 resultType,
613 1,
614 isErrorEnabled
615 );
616 }
617
618NonClassMember:
619
620 //////////////////////////
621 // 静的ローカル変数
622 // ※"Static.Object.Method.Variable"
623 //////////////////////////
624
625 char temporary[VN_SIZE];
626 if( UserProc::IsLocalAreaCompiling() ){
627 GetNowStaticVarFullName(VarName,temporary);
628
629 pVar = compiler.GetObjectModule().meta.GetGlobalVars().Find( Symbol( temporary ) );
630 if( pVar ){
631 goto ok;
632 }
633 }
634
635
636 //////////////////////////
637 // クラスの静的メンバ
638 //////////////////////////
639
640 if(member[0]){
641 lstrcpy(temporary,member);
642 char tempMember[VN_SIZE];
643 char tempArray[VN_SIZE];
644 {
645 ReferenceKind refType;
646 GetVarFormatString(temporary,tempArray,lpPtrOffset,tempMember,refType);
647 }
648
649 int typeDefIndex = compiler.GetObjectModule().meta.GetTypeDefs().GetIndex( VarName );
650 if( typeDefIndex != -1 ){
651 // TypeDef後の型名だったとき
652 lstrcpy( VarName, compiler.GetObjectModule().meta.GetTypeDefs()[typeDefIndex].GetBaseName().c_str() );
653 }
654
655 char temp2[VN_SIZE];
656 sprintf(temp2,"%s.%s",VarName,temporary);
657
658 pVar = compiler.GetObjectModule().meta.GetGlobalVars().Find( Symbol( temp2 ) );
659 if( pVar ){
660 lstrcpy(member,tempMember);
661 lstrcpy(array,tempArray);
662 goto ok;
663 }
664 }
665
666 if(compiler.pCompilingClass){
667 //自身のクラスから静的メンバを参照する場合
668 char temp2[VN_SIZE];
669 sprintf(temp2,"%s.%s",compiler.pCompilingClass->GetName().c_str(),VarName);
670
671 pVar = compiler.GetObjectModule().meta.GetGlobalVars().Find( Symbol( temp2 ) );
672 if( pVar ){
673 goto ok;
674 }
675 }
676
677
678 ////////////////////
679 // グローバル変数
680 ////////////////////
681
682 pVar = compiler.GetObjectModule().meta.GetGlobalVars().BackSearch( Symbol( VarName ) );
683 if( pVar ){
684 goto ok;
685 }
686
687 //変数として見つからなかったとき
688 if(isErrorEnabled) SetError(3,variable,cp);
689 return false;
690
691ok:
692
693 //ポインタ変数の場合
694 if( pVar->GetType().IsPointer() ){
695 if( !pVar->IsArray() ){
696 lstrcpy(lpPtrOffset,array);
697 array[0]=0;
698 }
699 }
700 else{
701 if(lpPtrOffset[0]){
702 if(isErrorEnabled) SetError(16,variable,cp);
703 return false;
704 }
705 }
706
707 resultType = pVar->GetType();
708
709 if(member[0]){
710 if( NATURAL_TYPE( resultType.GetBasicType() )==DEF_OBJECT
711 || NATURAL_TYPE( resultType.GetBasicType() )==DEF_STRUCT)
712 {
713 return GetMemberType(resultType,member,resultType,0,isErrorEnabled);
714 }
715 }
716
717 if( array[0] == 0 && pVar->GetSubscripts().size() > 0 ){
718 //配列の先頭ポインタを示す場合
719 resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR );
720 }
721
722 if(lpPtrOffset[0]){
723 if( resultType.PtrLevel() ){
724 resultType.PtrLevelDown();
725 }
726 else{
727 //エラー
728 if(isErrorEnabled) SetError(1,NULL,cp);
729 return false;
730 }
731 }
732
733 return true;
734}
735
736bool GetVarOffsetReadOnly(const char *NameBuffer,RELATIVE_VAR *pRelativeVar,Type &resultType, Subscripts *pResultSubscripts )
737{
738 //読み取り専用で変数へアクセス
739 return GetVarOffset(
740 true, //エラー表示有効
741 false, //書き込みアクセスは無し
742 NameBuffer,
743 pRelativeVar,
744 resultType,
745 pResultSubscripts
746 );
747}
748bool GetVarOffsetReadWrite(const char *NameBuffer,RELATIVE_VAR *pRelativeVar,Type &resultType, Subscripts *pResultSubscripts )
749{
750 //読み書き両用で変数へアクセス
751 return GetVarOffset(
752 true, //エラー表示有効
753 true, //書き込みアクセス
754 NameBuffer,
755 pRelativeVar,
756 resultType,
757 pResultSubscripts
758 );
759}
760
761
762
763bool GetDimentionFormat( const char *buffer,
764 char *VarName,
765 Subscripts &subscripts,
766 Type &type,
767 char *InitBuf,
768 char *ConstractParameter ){
769 int i,i2,i3,IsStr;
770 char variable[VN_SIZE],temporary[8192];
771
772 for(i=0;;i++){
773 if((buffer[i]==1&&buffer[i+1]==ESC_AS)||
774 buffer[i]=='='||
775 buffer[i]=='\0'){
776 variable[i]=0;
777 break;
778 }
779 variable[i]=buffer[i];
780 }
781
782 if(buffer[i]=='='){
783 ////////////////////////////////////
784 // 初期化データが指定されいるとき
785 ////////////////////////////////////
786 i++;
787
788 if( buffer[i]=='[' ){
789 // 構造初期データの場合
790
791 i3=GetStringInBracket(InitBuf,buffer+i);
792 i+=i3;
793 }
794 else{
795 // 代入初期データの場合
796
797 for(i2=0,IsStr=0;;i++,i2++){
798 if(buffer[i]=='\"') IsStr^=1;
799 if(buffer[i]=='('&&IsStr==0){
800 i3=GetStringInPare(InitBuf+i2,buffer+i);
801 i+=i3-1;
802 i2+=i3-1;
803 continue;
804 }
805 if(buffer[i]=='['&&IsStr==0){
806 i3=GetStringInBracket(InitBuf+i2,buffer+i);
807 i+=i3-1;
808 i2+=i3-1;
809 continue;
810 }
811 if((buffer[i]==','&&IsStr==0)||
812 buffer[i]=='\0'){
813 InitBuf[i2]=0;
814 break;
815 }
816 InitBuf[i2]=buffer[i];
817 }
818 }
819 }
820 else{
821 //初期化データなし
822 InitBuf[0]=0;
823 }
824
825 ConstractParameter[0]=0;
826 if(buffer[i]==1&&buffer[i+1]==ESC_AS){
827 /////////////////////////////
828 // "As ~" による型指定あり
829 /////////////////////////////
830
831 for(i+=2,i2=0;;i++,i2++){
832 if(buffer[i]==','||buffer[i]=='('||buffer[i]=='\0'){
833 temporary[i2]=0;
834 break;
835 }
836 temporary[i2]=buffer[i];
837 }
838 if(temporary[0]=='*'&&
839 temporary[1]==1&&
840 (temporary[2]==ESC_FUNCTION||temporary[2]==ESC_SUB)){
841 if(buffer[i]!='('){
842 SetError(10,temporary,cp);
843 return false;
844 }
845 i3=GetStringInPare(temporary+3,buffer+i);
846 i+=i3;
847 i2+=i3;
848
849 if(temporary[2]==ESC_FUNCTION&&buffer[i]==1&&buffer[i+1]==ESC_AS){
850 temporary[i2++]=buffer[i++];
851 temporary[i2++]=buffer[i++];
852 for(;;i++,i2++){
853 if(!IsVariableChar(buffer[i])){
854 temporary[i2]=0;
855 break;
856 }
857 temporary[i2]=buffer[i];
858 }
859 }
860 }
861
862 if( !compiler.StringToType( temporary, type ) ){
863 SetError(3,temporary,cp);
864 type.SetBasicType( DEF_LONG );
865 }
866
867 if(buffer[i]=='('){
868 //コンストラクタに渡すパラメータを取得
869 i2=GetStringInPare(ConstractParameter,buffer+i);
870 i+=i2;
871 RemoveStringPare(ConstractParameter);
872
873 if( !type.IsObject() ){
874 SetError(112,variable,cp);
875 return false;
876 }
877 }
878 }
879 else{
880 /////////////////
881 // As指定なし
882 /////////////////
883
884 if( InitBuf[0] == '\0' ){
885 //As指定も、初期値指定もない場合
886 type.SetBasicType( Type::GetBasicTypeFromSimpleName(variable) );
887
888 i2=lstrlen(variable)-1;
889 if(i2>=0){
890 if(!(variable[i2]=='#'||variable[i2]=='!'||variable[i2]=='%'||variable[i2]=='$'))
891 SetError(-103,variable,cp);
892 }
893 }
894 else{
895 //初期値の型を判別して自動的に型情報を付加する
896 if( !NumOpe_GetType( InitBuf, GetStringTypeInfo(), type ) ){
897 // エラーの場合
898 return false;
899 }
900
901 if( IS_LITERAL( type.GetIndex() ) ){
902 type.SetIndex( -1 );
903 }
904 }
905
906 }
907
908 if( InitBuf[0] != '\0' && ConstractParameter[0] != '\0' ){
909 //初期値とコンストラクタパラメータが同時に呼び出されているとき
910 SetError(132, NULL, cp);
911 }
912
913 GetArrange(variable,VarName,subscripts);
914 return true;
915}
916
917BOOL GetNowStaticVarFullName(char *VarName,char *FullName){
918 if( UserProc::IsGlobalAreaCompiling() ){
919 // グローバル領域をコンパイル中のとき
920 return 0;
921 }
922
923 const UserProc &proc = UserProc::CompilingUserProc();
924
925 //Static識別
926 lstrcpy(FullName,"Static%");
927
928 //クラス名
929 if(compiler.pCompilingClass){
930 lstrcat(FullName,compiler.pCompilingClass->GetName().c_str());
931 lstrcat(FullName,"%");
932 }
933
934 //関数(またはメソッド)名
935 lstrcat(FullName,proc.GetName().c_str());
936 lstrcat(FullName,"%");
937
938 //ID
939 char temp[255];
940 sprintf(temp,"%x",proc.GetId());
941 lstrcat(FullName,temp);
942 lstrcat(FullName,"%");
943
944 //変数名
945 lstrcat(FullName,VarName);
946
947 return 1;
948}
949
950
951void AddGlobalVariable( const char *name, const Subscripts &subscripts, const Type &type,const char *InitBuf,const char *ConstractParameter,DWORD dwFlag){
952 /////////////////////////
953 // グローバル変数を追加
954 /////////////////////////
955
956 if( compiler.GetObjectModule().meta.GetGlobalVars().DuplicateCheck( Symbol( name ) ) ){
957 //2重定義のエラー
958 SetError(15,name,cp);
959 return;
960 }
961
962 bool isConst = ( dwFlag & DIMFLAG_CONST ) ? true:false;
963
964 Variable *pVar = new Variable(
965 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes(),
966 name,
967 type,
968 isConst,
969 false,
970 ConstractParameter,
971 ( InitBuf[0] != 0 || dwFlag == DIMFLAG_INITDEBUGVAR )
972 );
973
974 if( subscripts.size() > 0 ){
975 //配列あり
976 pVar->SetArray( subscripts );
977 }
978
979 //レキシカルスコープ
980 pVar->SetScopeLevel( compiler.codeGenerator.lexicalScopes.GetNowLevel() );
981 pVar->SetScopeStartAddress( compiler.codeGenerator.lexicalScopes.GetStartAddress() );
982 pVar->bLiving=TRUE;
983
984 //エラー用
985 pVar->source_code_address=cp;
986
987 // 変数を追加
988 compiler.GetObjectModule().meta.GetGlobalVars().Add( pVar );
989
990 if(InitBuf[0]){
991 int result = 0;
992 if( !pVar->GetType().IsObject() ){
993 result = SetInitGlobalData(pVar->GetOffsetAddress(),
994 pVar->GetType(),
995 pVar->GetSubscripts(),
996 InitBuf);
997 }
998
999 if(!result){
1000 //動的な式だった場合は代入演算を行う
1001
1002 //初期代入時のみ、書き込みアクセスを許可する
1003 if( isConst ){
1004 pVar->ConstOff();
1005 }
1006
1007 //代入
1008 char temporary[8192];
1009 sprintf(temporary,"%s=%s",name,InitBuf);
1010 OpcodeCalc(temporary);
1011
1012 //アクセス制限を元に戻す
1013 if( isConst ){
1014 pVar->ConstOn();
1015 }
1016 }
1017 }
1018
1019
1020 if( type.IsObject() ){
1021 //デストラクタの利用フラグをオンにする
1022 const CMethod *method = type.GetClass().GetDestructorMethod();
1023 if( method ){
1024 method->GetUserProc().Using();
1025 }
1026 }
1027}
1028
1029void dim(char *Parameter,DWORD dwFlags){
1030 extern HANDLE hHeap;
1031 int i2;
1032 char VarName[VN_SIZE];
1033
1034 i2 = 0;
1035
1036 if( Parameter[i2] == 1 && Parameter[i2+1] == ESC_BYREF ){
1037 //参照型
1038 SetError();
1039 Parameter += 2;
1040 }
1041
1042 if(dwFlags & DIMFLAG_CONST){
1043
1044 //////////////////////////////////
1045 // 定数変数の場合を考慮
1046 //////////////////////////////////
1047 for(;;i2++){
1048 if(Parameter[i2] == '=' ||
1049 Parameter[i2] == 1 && Parameter[i2] == ESC_AS ||
1050 Parameter[i2] =='('){
1051 VarName[i2] = 0;
1052 break;
1053 }
1054 VarName[i2] = Parameter[i2];
1055 }
1056
1057 //定数と2重定義されていないる場合は抜け出す
1058 if(compiler.GetObjectModule().meta.GetGlobalConsts().GetBasicType(VarName)){
1059 return;
1060 }
1061
1062 //定数マクロとして定義されている場合は抜け出す
1063 if( compiler.GetObjectModule().meta.GetGlobalConstMacros().IsExist( VarName ) )
1064 {
1065 return;
1066 }
1067 }
1068
1069 //構文を解析
1070 Type type;
1071 char InitBuf[8192];
1072 char ConstractParameter[VN_SIZE];
1073 Subscripts subscripts;
1074 if(!GetDimentionFormat(Parameter, VarName,subscripts,type,InitBuf,ConstractParameter))
1075 return;
1076
1077
1078 //定数と2重定義されていないかを調べる
1079 if(compiler.GetObjectModule().meta.GetGlobalConsts().GetBasicType(VarName)){
1080 SetError(15,VarName,cp);
1081 return;
1082 }
1083
1084 //定数マクロとして定義されている場合
1085 if( compiler.GetObjectModule().meta.GetGlobalConstMacros().IsExist( VarName ) ){
1086 SetError(15,VarName,cp);
1087 return;
1088 }
1089
1090 if( type.IsObject() ){
1091 if( type.GetClass().IsBlittableType() ){
1092 // Blittable型のときは基本型として扱う
1093 // ※ただし、コンパイル中のメソッドがBlittable型クラスに属していないこと
1094 if( UserProc::IsLocalAreaCompiling()
1095 && UserProc::CompilingUserProc().HasParentClass()
1096 && UserProc::CompilingUserProc().GetParentClass().IsBlittableType() )
1097 {
1098 // コンパイル中のメソッドがBlittable型クラスに属している
1099 }
1100 else{
1101 type = type.GetClass().GetBlittableType();
1102 }
1103 }
1104 }
1105
1106 if(dwFlags&DIMFLAG_STATIC){
1107 if( UserProc::IsGlobalAreaCompiling() ){
1108 SetError(60,NULL,cp);
1109 return;
1110 }
1111
1112 /////////////////////
1113 // Static変数
1114 // ※"Static.Object.Method.Variable"
1115 /////////////////////
1116
1117 char temporary[VN_SIZE];
1118 GetNowStaticVarFullName(VarName,temporary);
1119
1120 dim( temporary,subscripts,type,InitBuf,ConstractParameter,dwFlags );
1121
1122 /*
1123 Note: 静的変数のコンストラクタ呼び出しは
1124 _System_InitStaticLocalVariables関数内で一括して行う
1125 */
1126 }
1127 else{
1128 dim( VarName,subscripts,type,InitBuf,ConstractParameter,dwFlags );
1129 }
1130}
1131void OpcodeDim(char *Parameter,DWORD dwFlags){
1132 int i,i2,i3,IsStr=0;
1133 char temporary[8192];
1134
1135 for(i=0,i2=0;;i++,i2++){
1136 if(Parameter[i]=='\"') IsStr^=1;
1137 if(Parameter[i]=='('&&IsStr==0){
1138 i3=GetStringInPare(temporary+i2,Parameter+i);
1139 i+=i3-1;
1140 i2+=i3-1;
1141 continue;
1142 }
1143 if(Parameter[i]=='['&&IsStr==0){
1144 i3=GetStringInBracket(temporary+i2,Parameter+i);
1145 i+=i3-1;
1146 i2+=i3-1;
1147 continue;
1148 }
1149 if((Parameter[i]==','&&IsStr==0)||
1150 Parameter[i]=='\0'){
1151 temporary[i2]=0;
1152
1153 dim(temporary,dwFlags);
1154
1155 if(Parameter[i]=='\0') break;
1156 i2=-1;
1157 continue;
1158 }
1159 temporary[i2]=Parameter[i];
1160 }
1161}
Note: See TracBrowser for help on using the repository browser.