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

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

コード全体のリファクタリングを実施

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