source: dev/BasicCompiler_Common/VariableOpe.cpp@ 99

Last change on this file since 99 was 97, checked in by dai_9181, 18 years ago

関数の戻り値オブジェクトのメンバ・メソッドを一時オブジェクトを介さずに参照できるようにした。

File size: 26.7 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 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
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(lstrcmp(objClass.ppobj_Member[i]->name,VarName)==0) break;
562 }
563 if(i==objClass.iMemberNum){
564 if(isErrorEnabled) SetError(103,VarName,cp);
565 return false;
566 }
567
568 //アクセシビリティをチェック
569 if( &objClass == pobj_CompilingClass ){
570 //同一クラスオブジェクトの場合はプライベートアクセスを容認する
571 if(objClass.ppobj_Member[i]->dwAccess==ACCESS_NON){
572 if(isErrorEnabled) SetError(107,VarName,cp);
573 return false;
574 }
575 }
576 else{
577 if((bPrivateAccess==0&&objClass.ppobj_Member[i]->dwAccess==ACCESS_PRIVATE)||
578 objClass.ppobj_Member[i]->dwAccess==ACCESS_NON){
579 if(isErrorEnabled) SetError(107,VarName,cp);
580 return false;
581 }
582 else if(bPrivateAccess==0&&objClass.ppobj_Member[i]->dwAccess==ACCESS_PROTECTED){
583 if(isErrorEnabled) SetError(108,VarName,cp);
584 return false;
585 }
586 }
587
588 resultType = *objClass.ppobj_Member[i];
589
590 //ポインタ変数の場合
591 if( resultType.IsPointer() ){
592 if(objClass.ppobj_Member[i]->SubScripts[0]==-1){
593 lstrcpy(lpPtrOffset,array);
594 array[0]=0;
595 }
596 }
597 else{
598 if(lpPtrOffset[0]){
599 if(isErrorEnabled) SetError(16,lpszMember,cp);
600 return false;
601 }
602 }
603
604 if( refType != CClass::Non ){
605 //入れ子構造の場合
606
607 return GetMemberType( objClass.ppobj_Member[i]->GetClass(),
608 NestMember,
609 resultType,
610 0,
611 isErrorEnabled);
612 }
613
614 if(array[0]==0&&objClass.ppobj_Member[i]->SubScripts[0]!=-1){
615 resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR );
616 return true;
617 }
618
619 if(lpPtrOffset[0]){
620 if( resultType.PtrLevel() ){
621 resultType.PtrLevelDown();
622 }
623 else{
624 //エラー
625 if(isErrorEnabled) SetError(1,NULL,cp);
626 return false;
627 }
628 }
629
630 return true;
631}
632bool GetVarType( const char *nameBuffer, Type &resultType, bool isErrorEnabled){
633 int i;
634 char variable[VN_SIZE],member[VN_SIZE],VarName[VN_SIZE],array[VN_SIZE],lpPtrOffset[VN_SIZE];
635
636 if(nameBuffer[0]=='.'){
637 GetWithName(variable);
638 lstrcat(variable,nameBuffer);
639 }
640 else lstrcpy(variable,nameBuffer);
641
642
643 CClass::RefType refType;
644 if( FormatUseProcReturnObject( variable, VarName, array, refType, member ) ){
645 // 戻り値オブジェクトのメンバを直接参照しているとき
646 //例: func().member
647
648 void *pProc;
649 int idProc=GetProc(VarName,(void **)&pProc);
650
651 if(idProc){
652 Type type;
653 if( !CallProc( idProc, pProc, VarName, array,type, false) ){
654 return false;
655 }
656
657 return GetMemberType( type.GetClass() ,member,resultType,1,isErrorEnabled);
658 }
659 }
660
661
662
663 lstrcpy(VarName,variable);
664 GetVarFormatString(VarName,array,lpPtrOffset,member,refType);
665
666 const Variable *pVar = NULL;
667 const int *pSubScripts;
668
669 if( UserProc::IsLocalAreaCompiling() ){
670 /////////////////
671 // ローカル変数
672 /////////////////
673
674 pVar = UserProc::CompilingUserProc().localVars.BackSearch( VarName );
675 if( pVar ){
676 goto ok;
677 }
678 }
679
680 if(pobj_CompilingClass){
681 ///////////////////////
682 // クラスメンバの参照
683 ///////////////////////
684
685 if(lstrcmpi(variable,"This")==0){
686 //Thisオブジェクト
687 resultType.SetType( DEF_OBJECT, pobj_CompilingClass );
688 return true;
689 }
690
691 if(memicmp(variable,"This.",5)==0){
692 //Thisオブジェクトのメンバを参照するとき
693 SlideString(variable+5,-5);
694 lstrcpy(VarName,variable);
695 }
696 else{
697 //クラス内メンバを参照するとき(通常)
698
699 for(i=0;i<pobj_CompilingClass->iMemberNum;i++){
700 if(lstrcmp(VarName,pobj_CompilingClass->ppobj_Member[i]->name)==0) break;
701 }
702 if(i==pobj_CompilingClass->iMemberNum) goto NonClassMember;
703 }
704
705 return GetMemberType(*pobj_CompilingClass,variable,resultType,1,isErrorEnabled);
706 }
707
708NonClassMember:
709
710 //////////////////////////
711 // 静的ローカル変数
712 // ※"Static.Object.Method.Variable"
713 //////////////////////////
714
715 char temporary[VN_SIZE];
716 if( UserProc::IsLocalAreaCompiling() ){
717 GetNowStaticVarFullName(VarName,temporary);
718
719 pVar = globalVars.Find( temporary );
720 if( pVar ){
721 goto ok;
722 }
723 }
724
725
726 //////////////////////////
727 // クラスの静的メンバ
728 //////////////////////////
729
730 if(member[0]){
731 lstrcpy(temporary,member);
732 char tempMember[VN_SIZE];
733 char tempArray[VN_SIZE];
734 {
735 CClass::RefType refType;
736 GetVarFormatString(temporary,tempArray,lpPtrOffset,tempMember,refType);
737 }
738
739 char temp2[VN_SIZE];
740 sprintf(temp2,"%s.%s",VarName,temporary);
741
742 pVar = globalVars.Find( temp2 );
743 if( pVar ){
744 lstrcpy(member,tempMember);
745 lstrcpy(array,tempArray);
746 goto ok;
747 }
748 }
749
750 if(pobj_CompilingClass){
751 //自身のクラスから静的メンバを参照する場合
752 char temp2[VN_SIZE];
753 sprintf(temp2,"%s.%s",pobj_CompilingClass->name,VarName);
754
755 pVar = globalVars.Find( temp2 );
756 if( pVar ){
757 goto ok;
758 }
759 }
760
761
762 ////////////////////
763 // グローバル変数
764 ////////////////////
765
766 pVar = globalVars.BackSearch( VarName );
767 if( pVar ){
768 goto ok;
769 }
770
771 //変数として見つからなかったとき
772 if(isErrorEnabled) SetError(3,variable,cp);
773 return false;
774
775ok:
776
777 //ポインタ変数の場合
778 if( pVar->IsPointer() ){
779 if( !pVar->IsArray() ){
780 lstrcpy(lpPtrOffset,array);
781 array[0]=0;
782 }
783 }
784 else{
785 if(lpPtrOffset[0]){
786 if(isErrorEnabled) SetError(16,variable,cp);
787 return false;
788 }
789 }
790
791 resultType = (*pVar);
792 pSubScripts=pVar->GetSubScriptsPtr();
793
794
795 if(member[0]){
796 if( NATURAL_TYPE( resultType.GetBasicType() )==DEF_OBJECT
797 || NATURAL_TYPE( resultType.GetBasicType() )==DEF_STRUCT){
798 return GetMemberType(resultType.GetClass(),member,resultType,0,isErrorEnabled);
799 }
800 }
801
802 if(array[0]==0&&pSubScripts[0]!=-1){
803 //配列の先頭ポインタを示す場合
804 resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR );
805 }
806
807 if(lpPtrOffset[0]){
808 if( resultType.PtrLevel() ){
809 resultType.PtrLevelDown();
810 }
811 else{
812 //エラー
813 if(isErrorEnabled) SetError(1,NULL,cp);
814 return false;
815 }
816 }
817
818 return true;
819}
820
821bool GetVarOffsetReadOnly(const char *NameBuffer,RELATIVE_VAR *pRelativeVar,Type &resultType,int *pss ){
822 //読み取り専用で変数へアクセス
823 return GetVarOffset(
824 true, //エラー表示有効
825 false, //書き込みアクセスは無し
826 NameBuffer,
827 pRelativeVar,
828 resultType,
829 pss);
830}
831bool GetVarOffsetReadWrite(const char *NameBuffer,RELATIVE_VAR *pRelativeVar,Type &resultType,int *pss ){
832 //読み書き両用で変数へアクセス
833 return GetVarOffset(
834 true, //エラー表示有効
835 true, //書き込みアクセス
836 NameBuffer,
837 pRelativeVar,
838 resultType,
839 pss);
840}
841
842
843
844bool GetDimentionFormat( const char *buffer,
845 char *VarName,
846 int *SubScripts,
847 Type &type,
848 char *InitBuf,
849 char *ConstractParameter ){
850 int i,i2,i3,IsStr;
851 char variable[VN_SIZE],temporary[8192];
852
853 for(i=0;;i++){
854 if((buffer[i]==1&&buffer[i+1]==ESC_AS)||
855 buffer[i]=='='||
856 buffer[i]=='\0'){
857 variable[i]=0;
858 break;
859 }
860 variable[i]=buffer[i];
861 }
862
863 if(buffer[i]=='='){
864 ////////////////////////////////////
865 // 初期化データが指定されいるとき
866 ////////////////////////////////////
867 i++;
868
869 if( buffer[i]=='[' ){
870 // 構造初期データの場合
871
872 i3=GetStringInBracket(InitBuf,buffer+i);
873 i+=i3;
874 }
875 else{
876 // 代入初期データの場合
877
878 for(i2=0,IsStr=0;;i++,i2++){
879 if(buffer[i]=='\"') IsStr^=1;
880 if(buffer[i]=='('&&IsStr==0){
881 i3=GetStringInPare(InitBuf+i2,buffer+i);
882 i+=i3-1;
883 i2+=i3-1;
884 continue;
885 }
886 if(buffer[i]=='['&&IsStr==0){
887 i3=GetStringInBracket(InitBuf+i2,buffer+i);
888 i+=i3-1;
889 i2+=i3-1;
890 continue;
891 }
892 if((buffer[i]==','&&IsStr==0)||
893 buffer[i]=='\0'){
894 InitBuf[i2]=0;
895 break;
896 }
897 InitBuf[i2]=buffer[i];
898 }
899 }
900 }
901 else{
902 //初期化データなし
903 InitBuf[0]=0;
904 }
905
906 ConstractParameter[0]=0;
907 if(buffer[i]==1&&buffer[i+1]==ESC_AS){
908 /////////////////////////////
909 // "As ~" による型指定あり
910 /////////////////////////////
911
912 for(i+=2,i2=0;;i++,i2++){
913 if(buffer[i]==','||buffer[i]=='('||buffer[i]=='\0'){
914 temporary[i2]=0;
915 break;
916 }
917 temporary[i2]=buffer[i];
918 }
919 if(temporary[0]=='*'&&
920 temporary[1]==1&&
921 (temporary[2]==ESC_FUNCTION||temporary[2]==ESC_SUB)){
922 if(buffer[i]!='('){
923 SetError(10,temporary,cp);
924 return false;
925 }
926 i3=GetStringInPare(temporary+3,buffer+i);
927 i+=i3;
928 i2+=i3;
929
930 if(temporary[2]==ESC_FUNCTION&&buffer[i]==1&&buffer[i+1]==ESC_AS){
931 temporary[i2++]=buffer[i++];
932 temporary[i2++]=buffer[i++];
933 for(;;i++,i2++){
934 if(!IsVariableChar(buffer[i])){
935 temporary[i2]=0;
936 break;
937 }
938 temporary[i2]=buffer[i];
939 }
940 }
941 }
942
943 if( !Type::StringToType( temporary, type ) ){
944 SetError(3,temporary,cp);
945 type.SetBasicType( DEF_LONG );
946 }
947
948 if(buffer[i]=='('){
949 //コンストラクタに渡すパラメータを取得
950 i2=GetStringInPare(ConstractParameter,buffer+i);
951 i+=i2;
952 RemoveStringPare(ConstractParameter);
953
954 if( !type.IsObject() ){
955 SetError(112,variable,cp);
956 return false;
957 }
958 }
959 }
960 else{
961 /////////////////
962 // As指定なし
963 /////////////////
964
965 if( InitBuf[0] == '\0' ){
966 //As指定も、初期値指定もない場合
967 type.SetBasicType( GetTypeFromSimpleName(variable) );
968
969 i2=lstrlen(variable)-1;
970 if(i2>=0){
971 if(!(variable[i2]=='#'||variable[i2]=='!'||variable[i2]=='%'||variable[i2]=='$'))
972 SetError(-103,variable,cp);
973 }
974 }
975 else{
976 //初期値の型を判別して自動的に型情報を付加する
977 if( !NumOpe_GetType( InitBuf, GetStringTypeInfo(), type ) ){
978 // エラーの場合
979 return false;
980 }
981
982 if( IS_LITERAL( type.GetIndex() ) ){
983 type.SetIndex( -1 );
984 }
985 }
986
987 }
988
989 if( InitBuf[0] != '\0' && ConstractParameter[0] != '\0' ){
990 //初期値とコンストラクタパラメータが同時に呼び出されているとき
991 SetError(132, NULL, cp);
992 }
993
994 GetArrange(variable,VarName,SubScripts);
995 return true;
996}
997
998BOOL GetNowStaticVarFullName(char *VarName,char *FullName){
999 if( UserProc::IsGlobalAreaCompiling() ){
1000 // グローバル領域をコンパイル中のとき
1001 return 0;
1002 }
1003
1004 UserProc &proc = UserProc::CompilingUserProc();
1005
1006 //Static識別
1007 lstrcpy(FullName,"Static%");
1008
1009 //クラス名
1010 if(pobj_CompilingClass){
1011 lstrcat(FullName,pobj_CompilingClass->name);
1012 lstrcat(FullName,"%");
1013 }
1014
1015 //関数(またはメソッド)名
1016 lstrcat(FullName,proc.GetName().c_str());
1017 lstrcat(FullName,"%");
1018
1019 //ID
1020 char temp[255];
1021 sprintf(temp,"%x",proc.id);
1022 lstrcat(FullName,temp);
1023 lstrcat(FullName,"%");
1024
1025 //変数名
1026 lstrcat(FullName,VarName);
1027
1028 return 1;
1029}
1030
1031
1032void AddGlobalVariable( const char *name,int *SubScripts, const Type &type,char *InitBuf,char *ConstractParameter,DWORD dwFlag){
1033 /////////////////////////
1034 // グローバル変数を追加
1035 /////////////////////////
1036 extern int AllInitGlobalVarSize;
1037 extern int AllGlobalVarSize;
1038
1039 if( globalVars.DuplicateCheck( name ) ){
1040 //2重定義のエラー
1041 SetError(15,name,cp);
1042 return;
1043 }
1044
1045 bool isConst = ( dwFlag & DIMFLAG_CONST ) ? true:false;
1046
1047 Variable *pVar = new Variable( name, type, isConst );
1048
1049 if( SubScripts[0] != -1 ){
1050 //配列あり
1051 pVar->SetArray( SubScripts );
1052 }
1053
1054 //コンストラクタ用パラメータ
1055 pVar->paramStrForConstructor = ConstractParameter;
1056
1057 //レキシカルスコープ
1058 pVar->ScopeLevel=obj_LexScopes.GetNowLevel();
1059 pVar->ScopeStartAddress=obj_LexScopes.GetStartAddress();
1060 pVar->bLiving=TRUE;
1061
1062 //エラー用
1063 pVar->source_code_address=cp;
1064
1065 // 変数を追加
1066 globalVars.push_back( pVar );
1067
1068 //アラインメントを考慮
1069 int alignment = 0;
1070 if( pVar->IsStruct() ){
1071 alignment = pVar->GetClass().iAlign;
1072 }
1073
1074 if(InitBuf[0]||dwFlag==DIMFLAG_INITDEBUGVAR){
1075 //初期バッファがあるとき
1076
1077 if( alignment ){
1078 if( AllInitGlobalVarSize % alignment ){
1079 AllInitGlobalVarSize += alignment - (AllInitGlobalVarSize % alignment);
1080 }
1081 }
1082
1083 pVar->offset=AllInitGlobalVarSize;
1084 AllInitGlobalVarSize += pVar->GetMemorySize();
1085 }
1086 else{
1087 //初期バッファがないとき
1088
1089 if( alignment ){
1090 if( AllGlobalVarSize % alignment ){
1091 AllGlobalVarSize += alignment - (AllGlobalVarSize % alignment);
1092 }
1093 }
1094
1095 pVar->offset=AllGlobalVarSize | 0x80000000;
1096 AllGlobalVarSize += pVar->GetMemorySize();
1097 }
1098
1099 if(InitBuf[0]){
1100 int result = 0;
1101 if( !pVar->IsObject() ){
1102 //初期バッファにデータをセット
1103 extern BYTE *initGlobalBuf;
1104 initGlobalBuf=(BYTE *)HeapReAlloc(hHeap,
1105 HEAP_ZERO_MEMORY,
1106 initGlobalBuf,
1107 AllInitGlobalVarSize);
1108
1109 result = SetInitGlobalData(pVar->offset,
1110 *pVar,
1111 pVar->GetSubScriptsPtr(),
1112 InitBuf);
1113 }
1114
1115 if(!result){
1116 //動的な式だった場合は代入演算を行う
1117
1118 //初期代入時のみ、書き込みアクセスを許可する
1119 if( isConst ){
1120 pVar->ConstOff();
1121 }
1122
1123 //代入
1124 char temporary[8192];
1125 sprintf(temporary,"%s=%s",name,InitBuf);
1126 OpcodeCalc(temporary);
1127
1128 //アクセス制限を元に戻す
1129 if( isConst ){
1130 pVar->ConstOn();
1131 }
1132 }
1133 }
1134
1135
1136 if( type.IsObject() ){
1137 //デストラクタの利用フラグをオンにする
1138 CMethod *method = type.GetClass().GetDestructorMethod();
1139 if( method ){
1140 method->pUserProc->Using();
1141 }
1142 }
1143}
1144
1145void dim(char *Parameter,DWORD dwFlags){
1146 extern HANDLE hHeap;
1147 int i2;
1148 char VarName[VN_SIZE];
1149
1150 i2 = 0;
1151
1152 if( Parameter[i2] == 1 && Parameter[i2+1] == ESC_BYREF ){
1153 //参照型
1154 SetError();
1155 Parameter += 2;
1156 }
1157
1158 if(dwFlags & DIMFLAG_CONST){
1159
1160 //////////////////////////////////
1161 // 定数変数の場合を考慮
1162 //////////////////////////////////
1163 for(;;i2++){
1164 if(Parameter[i2] == '=' ||
1165 Parameter[i2] == 1 && Parameter[i2] == ESC_AS ||
1166 Parameter[i2] =='('){
1167 VarName[i2] = 0;
1168 break;
1169 }
1170 VarName[i2] = Parameter[i2];
1171 }
1172
1173 //定数と2重定義されていないる場合は抜け出す
1174 if(CDBConst::obj.GetType(VarName)){
1175 return;
1176 }
1177
1178 //定数マクロとして定義されている場合は抜け出す
1179 if(GetConstHash(VarName)){
1180 return;
1181 }
1182 }
1183
1184 //構文を解析
1185 int SubScripts[MAX_ARRAYDIM];
1186 Type type;
1187 char InitBuf[8192];
1188 char ConstractParameter[VN_SIZE];
1189 if(!GetDimentionFormat(Parameter, VarName,SubScripts,type,InitBuf,ConstractParameter))
1190 return;
1191
1192
1193 //定数と2重定義されていないかを調べる
1194 if(CDBConst::obj.GetType(VarName)){
1195 SetError(15,VarName,cp);
1196 return;
1197 }
1198
1199 //定数マクロとして定義されている場合
1200 if(GetConstHash(VarName)){
1201 SetError(15,VarName,cp);
1202 return;
1203 }
1204
1205 if(dwFlags&DIMFLAG_STATIC){
1206 if( UserProc::IsGlobalAreaCompiling() ){
1207 SetError(60,NULL,cp);
1208 return;
1209 }
1210
1211 /////////////////////
1212 // Static変数
1213 // ※"Static.Object.Method.Variable"
1214 /////////////////////
1215
1216 char temporary[VN_SIZE];
1217 GetNowStaticVarFullName(VarName,temporary);
1218
1219 dim( temporary,SubScripts,type,InitBuf,ConstractParameter,dwFlags );
1220
1221 /*
1222 Note: 静的変数のコンストラクタ呼び出しは
1223 _System_InitStaticLocalVariables関数内で一括して行う
1224 */
1225 }
1226 else{
1227 dim( VarName,SubScripts,type,InitBuf,ConstractParameter,dwFlags );
1228 }
1229}
1230void OpcodeDim(char *Parameter,DWORD dwFlags){
1231 int i,i2,i3,IsStr=0;
1232 char temporary[8192];
1233
1234 for(i=0,i2=0;;i++,i2++){
1235 if(Parameter[i]=='\"') IsStr^=1;
1236 if(Parameter[i]=='('&&IsStr==0){
1237 i3=GetStringInPare(temporary+i2,Parameter+i);
1238 i+=i3-1;
1239 i2+=i3-1;
1240 continue;
1241 }
1242 if(Parameter[i]=='['&&IsStr==0){
1243 i3=GetStringInBracket(temporary+i2,Parameter+i);
1244 i+=i3-1;
1245 i2+=i3-1;
1246 continue;
1247 }
1248 if((Parameter[i]==','&&IsStr==0)||
1249 Parameter[i]=='\0'){
1250 temporary[i2]=0;
1251
1252 dim(temporary,dwFlags);
1253
1254 if(Parameter[i]=='\0') break;
1255 i2=-1;
1256 continue;
1257 }
1258 temporary[i2]=Parameter[i];
1259 }
1260}
Note: See TracBrowser for help on using the repository browser.