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

Last change on this file since 647 was 637, checked in by dai_9181, 16 years ago

リンカの依存関係解決モジュールを製作中

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