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

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