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

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