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

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