source: dev/trunk/abdev/BasicCompiler_Common/VariableOpe.cpp@ 168

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

プロジェクト内を整理。jengaライブラリのベースを作成。

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