source: dev/BasicCompiler_Common/VariableOpe.cpp@ 79

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

バージョンをβ17にした。
#strictをデフォルトの状態で適用するようにした(#90)。
Dimステートメントにおいて、初期値式とAsが同時に指定されていたとき、As以降も初期値式の一部として捉えるよう、変更(#91)。
GetTypeDef関数を完全廃止。

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