source: dev/BasicCompiler_Common/VariableOpe.cpp@ 116

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

暗黙的なアップキャストを可能にした

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