source: dev/BasicCompiler_Common/VariableOpe.cpp@ 106

Last change on this file since 106 was 106, checked in by dai_9181, 17 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
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 char temp2[VN_SIZE];
735 sprintf(temp2,"%s.%s",VarName,temporary);
736
737 pVar = globalVars.Find( temp2 );
738 if( pVar ){
739 lstrcpy(member,tempMember);
740 lstrcpy(array,tempArray);
741 goto ok;
742 }
743 }
744
745 if(pobj_CompilingClass){
746 //自身のクラスから静的メンバを参照する場合
747 char temp2[VN_SIZE];
748 sprintf(temp2,"%s.%s",pobj_CompilingClass->name,VarName);
749
750 pVar = globalVars.Find( temp2 );
751 if( pVar ){
752 goto ok;
753 }
754 }
755
756
757 ////////////////////
758 // グローバル変数
759 ////////////////////
760
761 pVar = globalVars.BackSearch( VarName );
762 if( pVar ){
763 goto ok;
764 }
765
766 //変数として見つからなかったとき
767 if(isErrorEnabled) SetError(3,variable,cp);
768 return false;
769
770ok:
771
772 //ポインタ変数の場合
773 if( pVar->IsPointer() ){
774 if( !pVar->IsArray() ){
775 lstrcpy(lpPtrOffset,array);
776 array[0]=0;
777 }
778 }
779 else{
780 if(lpPtrOffset[0]){
781 if(isErrorEnabled) SetError(16,variable,cp);
782 return false;
783 }
784 }
785
786 resultType = (*pVar);
787 pSubScripts=pVar->GetSubScriptsPtr();
788
789
790 if(member[0]){
791 if( NATURAL_TYPE( resultType.GetBasicType() )==DEF_OBJECT
792 || NATURAL_TYPE( resultType.GetBasicType() )==DEF_STRUCT){
793 return GetMemberType(resultType.GetClass(),member,resultType,0,isErrorEnabled);
794 }
795 }
796
797 if(array[0]==0&&pSubScripts[0]!=-1){
798 //配列の先頭ポインタを示す場合
799 resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR );
800 }
801
802 if(lpPtrOffset[0]){
803 if( resultType.PtrLevel() ){
804 resultType.PtrLevelDown();
805 }
806 else{
807 //エラー
808 if(isErrorEnabled) SetError(1,NULL,cp);
809 return false;
810 }
811 }
812
813 return true;
814}
815
816bool GetVarOffsetReadOnly(const char *NameBuffer,RELATIVE_VAR *pRelativeVar,Type &resultType,int *pss ){
817 //読み取り専用で変数へアクセス
818 return GetVarOffset(
819 true, //エラー表示有効
820 false, //書き込みアクセスは無し
821 NameBuffer,
822 pRelativeVar,
823 resultType,
824 pss);
825}
826bool GetVarOffsetReadWrite(const char *NameBuffer,RELATIVE_VAR *pRelativeVar,Type &resultType,int *pss ){
827 //読み書き両用で変数へアクセス
828 return GetVarOffset(
829 true, //エラー表示有効
830 true, //書き込みアクセス
831 NameBuffer,
832 pRelativeVar,
833 resultType,
834 pss);
835}
836
837
838
839bool GetDimentionFormat( const char *buffer,
840 char *VarName,
841 int *SubScripts,
842 Type &type,
843 char *InitBuf,
844 char *ConstractParameter ){
845 int i,i2,i3,IsStr;
846 char variable[VN_SIZE],temporary[8192];
847
848 for(i=0;;i++){
849 if((buffer[i]==1&&buffer[i+1]==ESC_AS)||
850 buffer[i]=='='||
851 buffer[i]=='\0'){
852 variable[i]=0;
853 break;
854 }
855 variable[i]=buffer[i];
856 }
857
858 if(buffer[i]=='='){
859 ////////////////////////////////////
860 // 初期化データが指定されいるとき
861 ////////////////////////////////////
862 i++;
863
864 if( buffer[i]=='[' ){
865 // 構造初期データの場合
866
867 i3=GetStringInBracket(InitBuf,buffer+i);
868 i+=i3;
869 }
870 else{
871 // 代入初期データの場合
872
873 for(i2=0,IsStr=0;;i++,i2++){
874 if(buffer[i]=='\"') IsStr^=1;
875 if(buffer[i]=='('&&IsStr==0){
876 i3=GetStringInPare(InitBuf+i2,buffer+i);
877 i+=i3-1;
878 i2+=i3-1;
879 continue;
880 }
881 if(buffer[i]=='['&&IsStr==0){
882 i3=GetStringInBracket(InitBuf+i2,buffer+i);
883 i+=i3-1;
884 i2+=i3-1;
885 continue;
886 }
887 if((buffer[i]==','&&IsStr==0)||
888 buffer[i]=='\0'){
889 InitBuf[i2]=0;
890 break;
891 }
892 InitBuf[i2]=buffer[i];
893 }
894 }
895 }
896 else{
897 //初期化データなし
898 InitBuf[0]=0;
899 }
900
901 ConstractParameter[0]=0;
902 if(buffer[i]==1&&buffer[i+1]==ESC_AS){
903 /////////////////////////////
904 // "As ~" による型指定あり
905 /////////////////////////////
906
907 for(i+=2,i2=0;;i++,i2++){
908 if(buffer[i]==','||buffer[i]=='('||buffer[i]=='\0'){
909 temporary[i2]=0;
910 break;
911 }
912 temporary[i2]=buffer[i];
913 }
914 if(temporary[0]=='*'&&
915 temporary[1]==1&&
916 (temporary[2]==ESC_FUNCTION||temporary[2]==ESC_SUB)){
917 if(buffer[i]!='('){
918 SetError(10,temporary,cp);
919 return false;
920 }
921 i3=GetStringInPare(temporary+3,buffer+i);
922 i+=i3;
923 i2+=i3;
924
925 if(temporary[2]==ESC_FUNCTION&&buffer[i]==1&&buffer[i+1]==ESC_AS){
926 temporary[i2++]=buffer[i++];
927 temporary[i2++]=buffer[i++];
928 for(;;i++,i2++){
929 if(!IsVariableChar(buffer[i])){
930 temporary[i2]=0;
931 break;
932 }
933 temporary[i2]=buffer[i];
934 }
935 }
936 }
937
938 if( !Type::StringToType( temporary, type ) ){
939 SetError(3,temporary,cp);
940 type.SetBasicType( DEF_LONG );
941 }
942
943 if(buffer[i]=='('){
944 //コンストラクタに渡すパラメータを取得
945 i2=GetStringInPare(ConstractParameter,buffer+i);
946 i+=i2;
947 RemoveStringPare(ConstractParameter);
948
949 if( !type.IsObject() ){
950 SetError(112,variable,cp);
951 return false;
952 }
953 }
954 }
955 else{
956 /////////////////
957 // As指定なし
958 /////////////////
959
960 if( InitBuf[0] == '\0' ){
961 //As指定も、初期値指定もない場合
962 type.SetBasicType( GetTypeFromSimpleName(variable) );
963
964 i2=lstrlen(variable)-1;
965 if(i2>=0){
966 if(!(variable[i2]=='#'||variable[i2]=='!'||variable[i2]=='%'||variable[i2]=='$'))
967 SetError(-103,variable,cp);
968 }
969 }
970 else{
971 //初期値の型を判別して自動的に型情報を付加する
972 if( !NumOpe_GetType( InitBuf, GetStringTypeInfo(), type ) ){
973 // エラーの場合
974 return false;
975 }
976
977 if( IS_LITERAL( type.GetIndex() ) ){
978 type.SetIndex( -1 );
979 }
980 }
981
982 }
983
984 if( InitBuf[0] != '\0' && ConstractParameter[0] != '\0' ){
985 //初期値とコンストラクタパラメータが同時に呼び出されているとき
986 SetError(132, NULL, cp);
987 }
988
989 GetArrange(variable,VarName,SubScripts);
990 return true;
991}
992
993BOOL GetNowStaticVarFullName(char *VarName,char *FullName){
994 if( UserProc::IsGlobalAreaCompiling() ){
995 // グローバル領域をコンパイル中のとき
996 return 0;
997 }
998
999 UserProc &proc = UserProc::CompilingUserProc();
1000
1001 //Static識別
1002 lstrcpy(FullName,"Static%");
1003
1004 //クラス名
1005 if(pobj_CompilingClass){
1006 lstrcat(FullName,pobj_CompilingClass->name);
1007 lstrcat(FullName,"%");
1008 }
1009
1010 //関数(またはメソッド)名
1011 lstrcat(FullName,proc.GetName().c_str());
1012 lstrcat(FullName,"%");
1013
1014 //ID
1015 char temp[255];
1016 sprintf(temp,"%x",proc.id);
1017 lstrcat(FullName,temp);
1018 lstrcat(FullName,"%");
1019
1020 //変数名
1021 lstrcat(FullName,VarName);
1022
1023 return 1;
1024}
1025
1026
1027void AddGlobalVariable( const char *name,int *SubScripts, const Type &type,char *InitBuf,char *ConstractParameter,DWORD dwFlag){
1028 /////////////////////////
1029 // グローバル変数を追加
1030 /////////////////////////
1031 extern int AllInitGlobalVarSize;
1032 extern int AllGlobalVarSize;
1033
1034 if( globalVars.DuplicateCheck( name ) ){
1035 //2重定義のエラー
1036 SetError(15,name,cp);
1037 return;
1038 }
1039
1040 bool isConst = ( dwFlag & DIMFLAG_CONST ) ? true:false;
1041
1042 Variable *pVar = new Variable( Smoothie::Lexical::liveingNamespaceScopes, name, type, isConst );
1043
1044 if( SubScripts[0] != -1 ){
1045 //配列あり
1046 pVar->SetArray( SubScripts );
1047 }
1048
1049 //コンストラクタ用パラメータ
1050 pVar->paramStrForConstructor = ConstractParameter;
1051
1052 //レキシカルスコープ
1053 pVar->ScopeLevel=obj_LexScopes.GetNowLevel();
1054 pVar->ScopeStartAddress=obj_LexScopes.GetStartAddress();
1055 pVar->bLiving=TRUE;
1056
1057 //エラー用
1058 pVar->source_code_address=cp;
1059
1060 // 変数を追加
1061 globalVars.push_back( pVar );
1062
1063 //アラインメントを考慮
1064 int alignment = 0;
1065 if( pVar->IsStruct() ){
1066 alignment = pVar->GetClass().iAlign;
1067 }
1068
1069 if(InitBuf[0]||dwFlag==DIMFLAG_INITDEBUGVAR){
1070 //初期バッファがあるとき
1071
1072 if( alignment ){
1073 if( AllInitGlobalVarSize % alignment ){
1074 AllInitGlobalVarSize += alignment - (AllInitGlobalVarSize % alignment);
1075 }
1076 }
1077
1078 pVar->offset=AllInitGlobalVarSize;
1079 AllInitGlobalVarSize += pVar->GetMemorySize();
1080 }
1081 else{
1082 //初期バッファがないとき
1083
1084 if( alignment ){
1085 if( AllGlobalVarSize % alignment ){
1086 AllGlobalVarSize += alignment - (AllGlobalVarSize % alignment);
1087 }
1088 }
1089
1090 pVar->offset=AllGlobalVarSize | 0x80000000;
1091 AllGlobalVarSize += pVar->GetMemorySize();
1092 }
1093
1094 if(InitBuf[0]){
1095 int result = 0;
1096 if( !pVar->IsObject() ){
1097 //初期バッファにデータをセット
1098 extern BYTE *initGlobalBuf;
1099 initGlobalBuf=(BYTE *)HeapReAlloc(hHeap,
1100 HEAP_ZERO_MEMORY,
1101 initGlobalBuf,
1102 AllInitGlobalVarSize);
1103
1104 result = SetInitGlobalData(pVar->offset,
1105 *pVar,
1106 pVar->GetSubScriptsPtr(),
1107 InitBuf);
1108 }
1109
1110 if(!result){
1111 //動的な式だった場合は代入演算を行う
1112
1113 //初期代入時のみ、書き込みアクセスを許可する
1114 if( isConst ){
1115 pVar->ConstOff();
1116 }
1117
1118 //代入
1119 char temporary[8192];
1120 sprintf(temporary,"%s=%s",name,InitBuf);
1121 OpcodeCalc(temporary);
1122
1123 //アクセス制限を元に戻す
1124 if( isConst ){
1125 pVar->ConstOn();
1126 }
1127 }
1128 }
1129
1130
1131 if( type.IsObject() ){
1132 //デストラクタの利用フラグをオンにする
1133 CMethod *method = type.GetClass().GetDestructorMethod();
1134 if( method ){
1135 method->pUserProc->Using();
1136 }
1137 }
1138}
1139
1140void dim(char *Parameter,DWORD dwFlags){
1141 extern HANDLE hHeap;
1142 int i2;
1143 char VarName[VN_SIZE];
1144
1145 i2 = 0;
1146
1147 if( Parameter[i2] == 1 && Parameter[i2+1] == ESC_BYREF ){
1148 //参照型
1149 SetError();
1150 Parameter += 2;
1151 }
1152
1153 if(dwFlags & DIMFLAG_CONST){
1154
1155 //////////////////////////////////
1156 // 定数変数の場合を考慮
1157 //////////////////////////////////
1158 for(;;i2++){
1159 if(Parameter[i2] == '=' ||
1160 Parameter[i2] == 1 && Parameter[i2] == ESC_AS ||
1161 Parameter[i2] =='('){
1162 VarName[i2] = 0;
1163 break;
1164 }
1165 VarName[i2] = Parameter[i2];
1166 }
1167
1168 //定数と2重定義されていないる場合は抜け出す
1169 if(CDBConst::obj.GetBasicType(VarName)){
1170 return;
1171 }
1172
1173 //定数マクロとして定義されている場合は抜け出す
1174 if(GetConstHash(VarName)){
1175 return;
1176 }
1177 }
1178
1179 //構文を解析
1180 int SubScripts[MAX_ARRAYDIM];
1181 Type type;
1182 char InitBuf[8192];
1183 char ConstractParameter[VN_SIZE];
1184 if(!GetDimentionFormat(Parameter, VarName,SubScripts,type,InitBuf,ConstractParameter))
1185 return;
1186
1187
1188 //定数と2重定義されていないかを調べる
1189 if(CDBConst::obj.GetBasicType(VarName)){
1190 SetError(15,VarName,cp);
1191 return;
1192 }
1193
1194 //定数マクロとして定義されている場合
1195 if(GetConstHash(VarName)){
1196 SetError(15,VarName,cp);
1197 return;
1198 }
1199
1200 if(dwFlags&DIMFLAG_STATIC){
1201 if( UserProc::IsGlobalAreaCompiling() ){
1202 SetError(60,NULL,cp);
1203 return;
1204 }
1205
1206 /////////////////////
1207 // Static変数
1208 // ※"Static.Object.Method.Variable"
1209 /////////////////////
1210
1211 char temporary[VN_SIZE];
1212 GetNowStaticVarFullName(VarName,temporary);
1213
1214 dim( temporary,SubScripts,type,InitBuf,ConstractParameter,dwFlags );
1215
1216 /*
1217 Note: 静的変数のコンストラクタ呼び出しは
1218 _System_InitStaticLocalVariables関数内で一括して行う
1219 */
1220 }
1221 else{
1222 dim( VarName,SubScripts,type,InitBuf,ConstractParameter,dwFlags );
1223 }
1224}
1225void OpcodeDim(char *Parameter,DWORD dwFlags){
1226 int i,i2,i3,IsStr=0;
1227 char temporary[8192];
1228
1229 for(i=0,i2=0;;i++,i2++){
1230 if(Parameter[i]=='\"') IsStr^=1;
1231 if(Parameter[i]=='('&&IsStr==0){
1232 i3=GetStringInPare(temporary+i2,Parameter+i);
1233 i+=i3-1;
1234 i2+=i3-1;
1235 continue;
1236 }
1237 if(Parameter[i]=='['&&IsStr==0){
1238 i3=GetStringInBracket(temporary+i2,Parameter+i);
1239 i+=i3-1;
1240 i2+=i3-1;
1241 continue;
1242 }
1243 if((Parameter[i]==','&&IsStr==0)||
1244 Parameter[i]=='\0'){
1245 temporary[i2]=0;
1246
1247 dim(temporary,dwFlags);
1248
1249 if(Parameter[i]=='\0') break;
1250 i2=-1;
1251 continue;
1252 }
1253 temporary[i2]=Parameter[i];
1254 }
1255}
Note: See TracBrowser for help on using the repository browser.