source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/VariableOpe.cpp@ 482

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

Messenger/ErrorMessengerクラスを導入。SetError関数によるエラー生成を廃止した。

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