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

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

プロパティ値として返ってきたオブジェクトインスタンスのインデクサを呼び出す処理をきちんと対応した。

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