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

Last change on this file since 699 was 699, checked in by イグトランス (egtra), 16 years ago

VN_SIZEが小さくてControlがコンパイルできなかったので、増量(_TermOpe関数でエラーになるのでそこを直したが、それだけではだめだった)。

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