source: dev/BasicCompiler_Common/VariableOpe.cpp@ 114

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

CClassクラスのインスタンスを全面的にconstにした。
TypeDefされたクラスの静的メソッドを呼び出せるようにした。(静的メンバへの対応はまだ)

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