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

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