source: dev/BasicCompiler_Common/VariableOpe.cpp@ 137

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

アクセシビリティ周りをリファクタリングした。

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