#include "stdafx.h" #ifdef _AMD64_ #include "../compiler_x64/opcode.h" #else #include "../compiler_x86/opcode.h" #endif using namespace ActiveBasic::Compiler; BOOL IsPtrType(int type){ if(type==-1) return 0; if(PTR_LEVEL(type)||type==DEF_PTR_VOID||type==DEF_PTR_PROC|| (type&FLAG_PTR) ) return 1; return 0; } BOOL IsSignedType(int type){ switch(type){ case DEF_SBYTE: case DEF_INTEGER: case DEF_LONG: case DEF_INT64: case DEF_SINGLE: case DEF_DOUBLE: case DEF_CHAR: return 1; default: break; } return 0; } BOOL IsNaturalWholeNumberType(int type){ switch(type){ case DEF_SBYTE: case DEF_BYTE: case DEF_INTEGER: case DEF_WORD: case DEF_LONG: case DEF_DWORD: case DEF_INT64: case DEF_QWORD: case DEF_CHAR: return 1; default: break; } return 0; } BOOL IsWholeNumberType(int type){ return ( IsNaturalWholeNumberType(type) || IsPtrType(type) || type == DEF_BOOLEAN ); } BOOL IsRealNumberType(int type){ switch(type){ case DEF_DOUBLE: case DEF_SINGLE: return 1; default: break; } return 0; } BOOL Is64Type(int type){ switch(type){ case DEF_INT64: case DEF_QWORD: return 1; default: break; } #ifdef _AMD64_ return IsPtrType(type); #else return 0; #endif } int GetSignedType(int type){ switch(type){ case DEF_BYTE: return DEF_SBYTE; case DEF_WORD: return DEF_INTEGER; case DEF_DWORD: return DEF_LONG; case DEF_QWORD: return DEF_INT64; default: break; } #ifdef _AMD64_ if(IsPtrType(type)) return DEF_INT64; #else if(IsPtrType(type)) return DEF_LONG; #endif return type; } int GetUnsignedType(int type){ switch(type){ case DEF_SBYTE: return DEF_BYTE; case DEF_INTEGER: return DEF_WORD; case DEF_LONG: return DEF_DWORD; case DEF_INT64: return DEF_QWORD; case DEF_CHAR: if( compiler.IsUnicode() ) return DEF_WORD; return DEF_BYTE; } return type; } int GetPtrType(int type){ return MAKE_PTR_TYPE(NATURAL_TYPE(type),PTR_LEVEL(type)+1); } BOOL GetTypeName(int type,LONG_PTR lpIndex,char *name){ if(PTR_LEVEL(type)){ //ポインタ型 name[0]='*'; return GetTypeName(MAKE_PTR_TYPE(NATURAL_TYPE(type),PTR_LEVEL(type)-1),lpIndex,name+1); } //整数型 if(type==DEF_SBYTE) lstrcpy(name,"SByte"); else if(type==DEF_BYTE) lstrcpy(name,"Byte"); else if(type==DEF_INTEGER) lstrcpy(name,"Integer"); else if(type==DEF_WORD) lstrcpy(name,"Word"); else if(type==DEF_LONG) lstrcpy(name,"Long"); else if(type==DEF_DWORD) lstrcpy(name,"DWord"); else if(type==DEF_INT64) lstrcpy(name,"Int64"); else if(type==DEF_QWORD) lstrcpy(name,"QWord"); //実数型 else if(type==DEF_SINGLE) lstrcpy(name,"Single"); else if(type==DEF_DOUBLE) lstrcpy(name,"Double"); //文字型 //else if(type==DEF_CHAR) lstrcpy(name,"Char"); //bool型 else if(type==DEF_BOOLEAN) lstrcpy(name,"Boolean"); //オブジェクト else if(type==DEF_OBJECT || type==DEF_STRUCT){ if(lpIndex==0) lstrcpy(name,"non"); else{ lstrcpy(name,((CClass *)lpIndex)->GetName().c_str()); } } //ポインタ型 else if(type==DEF_PTR_VOID) lstrcpy(name,"VoidPtr"); else if(type==DEF_PTR_PROC){ if(lpIndex==-1) lstrcpy(name,"VoidPtr"); else{ if( compiler.GetObjectModule().meta.GetProcPointers()[lpIndex]->ReturnType().IsNull() ) lstrcpy(name,"*Sub"); else lstrcpy(name,"*Function"); } } else{ extern int cp; compiler.errorMessenger.Output(1,NULL,cp); return 0; } return 1; } Type GetStringTypeInfo(){ Type type( DEF_OBJECT, *compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr() ); return type; } void GetWithName(char *buffer){ extern WithInfos withInfos; buffer[0]=0; BOOST_FOREACH( const WithInfo &withInfo, withInfos ) { lstrcat( buffer, withInfo.name.c_str() ); } } void GetWithName(std::string& buffer){ extern WithInfos withInfos; std::string tmp; tmp.reserve(1024); BOOST_FOREACH( const WithInfo &withInfo, withInfos ) { tmp+=withInfo.name; } tmp.swap(buffer); } void GetArrange(char *variable,char *variAnswer, Subscripts &subscripts ){ extern int cp; int i,i2,i4; double dbl; _int64 i64data; BOOL bBracket; char temporary[VN_SIZE]; for(i=0;;i++){ if(variable[i]=='('||variable[i]=='['){ if(variable[i]=='[') bBracket=1; else bBracket=0; variAnswer[i]=0; for(i++,i2=0;;i++,i2++){ if(variable[i]==','){ temporary[i2]=0; Type resultType; if( !StaticCalculation(true, temporary,0,&i64data,resultType) ){ return; } if(resultType.IsReal()){ memcpy(&dbl,&i64data,sizeof(double)); i64data=(_int64)dbl; } if(i64data<0) { //error subscripts.push_back( 0 ); } else { subscripts.push_back( (int)i64data ); } i2=-1; continue; } if(variable[i]=='('){ i4=GetStringInPare(temporary+i2,variable+i); i2+=i4-1; i+=i4-1; continue; } if(variable[i]=='['){ i4=GetStringInBracket(temporary+i2,variable+i); i2+=i4-1; i+=i4-1; continue; } if(variable[i]==')'&&bBracket==0|| variable[i]==']'&&bBracket){ temporary[i2]=0; if(i2==0){ subscripts.push_back( -2 ); break; } Type resultType; if( !StaticCalculation(true, temporary,0,&i64data,resultType) ){ return; } if(resultType.IsReal()){ memcpy(&dbl,&i64data,sizeof(double)); i64data=(_int64)dbl; } if(i64data<0){ //error subscripts.push_back( 0 ); } else { subscripts.push_back( (int)i64data ); } break; } if(variable[i]=='\"'){ compiler.errorMessenger.Output(1,NULL,cp); return; } temporary[i2]=variable[i]; } break; } variAnswer[i]=variable[i]; if(variable[i]=='\0'){ break; } } } //対応する閉じ括弧cPare_Closeが現れるまでbufからarrayへコピーする。 int CopyInsideBracket(char *array, const char *buf, char cPare_Open, char cPare_Close) { bool inStr=false; for(int i2=0;;i2++){ if(buf[i2]=='"'){ inStr=!inStr; } if(!inStr){ if(buf[i2]==cPare_Open){ int i3; if(cPare_Open=='[') i3=GetStringInBracket(array+i2,buf+i2); else i3=GetStringInPare(array+i2,buf+i2); i2+=i3-1; continue; } if(buf[i2]==cPare_Close){ array[i2]=0; return i2; } } array[i2]=buf[i2]; } } bool GetVarFormatString( char *buffer,char *array,char *array2,char *NestMember,ReferenceKind &refType, PareOrBracket *pPareOrBracket ){ extern int cp; int i; char cPare_Open,cPare_Close; array[0]=0; array2[0]=0; NestMember[0]=0; for(i=0;;i++){ if(buffer[i]=='\"'){ for(i++;;i++){ if(IsDBCSLeadByte(buffer[i])){ i++; continue; } if(buffer[i]=='\"') break; } } if(buffer[i]=='['||buffer[i]=='('){ if(buffer[i]=='['){ cPare_Open='['; cPare_Close=']'; } else{ cPare_Open='('; cPare_Close=')'; } if( pPareOrBracket ) { // []なのか、()なのかを伝える if( cPare_Open == '[' ) { *pPareOrBracket = Bracket; } else { *pPareOrBracket = Pare; } } buffer[i]=0; i++; i+=CopyInsideBracket(array,buffer+i,cPare_Open,cPare_Close); if(buffer[i+1]==cPare_Open){ i+=2; for(int i2=0;;i++,i2++){ if(buffer[i]==cPare_Open){ int i3; if(cPare_Open=='[') i3=GetStringInBracket(array2+i2,buffer+i); else i3=GetStringInPare(array2+i2,buffer+i); i+=i3-1; i2+=i3-1; continue; } if(buffer[i]==cPare_Close){ array2[i2]=0; break; } array2[i2]=buffer[i]; } if(buffer[i+1]==cPare_Open){ compiler.errorMessenger.Output(14,buffer,cp); return false; } } continue; } if(buffer[i]=='.'){ lstrcpy(NestMember,buffer+i+1); refType = RefDot; buffer[i]=0; break; } if(buffer[i]==1&&buffer[i+1]==ESC_PSMEM){ lstrcpy(NestMember,buffer+i+2); refType = RefPointer; buffer[i]=0; break; } if(buffer[i]=='\0') break; } return true; } void GetArrayElement( const char *buffer,char *variable,char *array_element){ array_element[0]=0; if(buffer[lstrlen(buffer)-1]!=']'){ lstrcpy(variable,buffer); return; } int i,i2; for(i=0;;i++){ if(buffer[i]=='\0') break; if(buffer[i]=='['){ i2=GetStringInBracket(array_element,buffer+i); i+=i2-1; continue; } } lstrcpy(variable,buffer); variable[lstrlen(variable)-lstrlen(array_element)]=0; RemoveStringBracket(array_element); } BOOL CheckVarNameError(char *name,int nowLine){ int i2; if(!IsVariableTopChar(name[0])){ compiler.errorMessenger.Output(1,NULL,nowLine); return 0; } for(i2=1;;i2++){ if(name[i2]=='\0') break; if(!IsVariableChar(name[i2])){ compiler.errorMessenger.Output(1,NULL,nowLine); return 0; } } return 1; } int JumpSubScripts( const Subscripts &subscripts ){ //DIMで定義された並んだ配列の数だけアドレスを進める int i, i2; for( i=0,i2=1; i<(int)subscripts.size(); i++ ){ i2 *= subscripts[i] + 1; } return i2; } bool GetMemberType( const Type &classType, const char *lpszMember, Type &resultType, BOOL bPrivateAccess, bool isErrorEnabled) { const CClass &objClass = classType.GetClass(); extern int cp; //クラス、配列の構成要素を解析する char VarName[VN_SIZE]; //変数名 char array[VN_SIZE]; //第1次配列 char lpPtrOffset[VN_SIZE]; //第2次配列 char NestMember[VN_SIZE]; //入れ子メンバ ReferenceKind refType = RefNon; lstrcpy(VarName,lpszMember); if(!GetVarFormatString(VarName,array,lpPtrOffset,NestMember,refType)) return false; const Member *pMember = objClass.FindDynamicMember( VarName ); if( !pMember ){ if(isErrorEnabled) compiler.errorMessenger.Output(103,VarName,cp); return false; } //アクセシビリティをチェック if( compiler.IsCompilingClass() && &objClass == &compiler.GetCompilingClass() ){ //同一クラスオブジェクトの場合はプライベートアクセスを容認する if( pMember->IsNoneAccess() ){ if(isErrorEnabled) compiler.errorMessenger.Output(107,VarName,cp); return false; } } else{ if(( bPrivateAccess==0 && pMember->IsPrivate() )|| pMember->IsNoneAccess() ){ if(isErrorEnabled) compiler.errorMessenger.Output(107,VarName,cp); return false; } else if( bPrivateAccess==0 && pMember->IsProtected() ){ if(isErrorEnabled) compiler.errorMessenger.Output(108,VarName,cp); return false; } } resultType = pMember->GetType(); // 型パラメータを解決 ResolveFormalGenericTypeParameter( resultType, classType ); //ポインタ変数の場合 if( resultType.IsPointer() ){ if( pMember->GetSubscripts().size() == 0 ){ lstrcpy(lpPtrOffset,array); array[0]=0; } } else{ if(lpPtrOffset[0]){ if(isErrorEnabled) compiler.errorMessenger.Output(16,lpszMember,cp); return false; } } if(array[0]){ //配列オフセット if( pMember->GetSubscripts().size() <= 0 ) { // 配列ではないメンバに配列指定をした return false; } } else if( pMember->GetSubscripts().size() > 0 ){ resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR ); } if( refType != RefNon ){ //入れ子構造の場合 return GetMemberType( pMember->GetType(), NestMember, resultType, 0, isErrorEnabled); } if(lpPtrOffset[0]){ if( resultType.PtrLevel() ){ resultType.PtrLevelDown(); } else{ //エラー if(isErrorEnabled) compiler.errorMessenger.Output(1,NULL,cp); return false; } } return true; } bool GetVarType( const char *nameBuffer, Type &resultType, bool isErrorEnabled){ char variable[VN_SIZE]; if(nameBuffer[0]=='.'){ GetWithName(variable); lstrcat(variable,nameBuffer); } else lstrcpy(variable,nameBuffer); // 名前空間を分離 char namespaceStr[VN_SIZE]="", simpleName[VN_SIZE]; compiler.GetObjectModule().meta.GetNamespaces().SplitNamespace( variable, namespaceStr, simpleName ); // 先頭オブジェクトまたはクラス名と入れ子メンバに分割 ReferenceKind refType; char member[VN_SIZE],array[VN_SIZE],lpPtrOffset[VN_SIZE]; GetVarFormatString(simpleName,array,lpPtrOffset,member,refType); // 名前空間を分離していた場合は結合 char VarName[VN_SIZE]; if( namespaceStr[0] ){ sprintf( VarName, "%s.%s", namespaceStr, simpleName ); } else{ lstrcpy( VarName, simpleName ); } const Variable *pVar = NULL; if( compiler.IsLocalAreaCompiling() ){ ///////////////// // ローカル変数 ///////////////// pVar = compiler.GetCompilingUserProc().GetLocalVars().BackSearch( LexicalAnalyzer::FullNameToSymbol( VarName ), compiler.codeGenerator.lexicalScopes.GetNowLevel() ); if( pVar ){ goto ok; } } if( compiler.IsCompilingClass() ){ /////////////////////// // クラスメンバの参照 /////////////////////// if(lstrcmpi(variable,"This")==0){ //Thisオブジェクト resultType.SetType( DEF_OBJECT, &compiler.GetCompilingClass() ); return true; } if(memicmp(variable,"This.",5)==0){ //Thisオブジェクトのメンバを参照するとき SlideString(variable+5,-5); lstrcpy(VarName,variable); } else{ //クラス内の動的メンバを参照するとき(通常) if( !compiler.GetCompilingClass().HasDynamicMember( VarName ) ) { goto NonClassMember; } } return GetMemberType( Type( DEF_OBJECT, compiler.GetCompilingClass() ), variable, resultType, 1, isErrorEnabled ); } NonClassMember: ////////////////////////// // 静的ローカル変数 // ※"Static.Object.Method.Variable" ////////////////////////// char temporary[VN_SIZE]; if( compiler.IsLocalAreaCompiling() ){ GetNowStaticVarFullName(VarName,temporary); pVar = compiler.GetObjectModule().meta.GetGlobalVars().Find( LexicalAnalyzer::FullNameToSymbol( temporary ) ); if( pVar ){ goto ok; } } ////////////////////////// // クラスの静的メンバ ////////////////////////// if(member[0]){ lstrcpy(temporary,member); char tempMember[VN_SIZE]; char tempArray[VN_SIZE]; { ReferenceKind refType; GetVarFormatString(temporary,tempArray,lpPtrOffset,tempMember,refType); } const TypeDef *pTypeDef = compiler.GetObjectModule().meta.GetTypeDefs().Find( LexicalAnalyzer::FullNameToSymbol( VarName ) ); if( pTypeDef ) { // TypeDef後の型名だったとき lstrcpy( VarName, pTypeDef->GetBaseName().c_str() ); } char temp2[VN_SIZE]; sprintf(temp2,"%s.%s",VarName,temporary); pVar = compiler.GetObjectModule().meta.GetGlobalVars().Find( LexicalAnalyzer::FullNameToSymbol( temp2 ) ); if( pVar ){ lstrcpy(member,tempMember); lstrcpy(array,tempArray); goto ok; } } if( compiler.IsCompilingClass() ){ //自身のクラスから静的メンバを参照する場合 char temp2[VN_SIZE]; sprintf(temp2,"%s.%s",compiler.GetCompilingClass().GetName().c_str(),VarName); pVar = compiler.GetObjectModule().meta.GetGlobalVars().Find( LexicalAnalyzer::FullNameToSymbol( temp2 ) ); if( pVar ){ goto ok; } } //////////////////// // グローバル変数 //////////////////// pVar = compiler.GetObjectModule().meta.GetGlobalVars().BackSearch( LexicalAnalyzer::FullNameToSymbol( VarName ), compiler.codeGenerator.lexicalScopes.GetNowLevel() ); if( pVar ){ goto ok; } //変数として見つからなかったとき if(isErrorEnabled) compiler.errorMessenger.Output(3,variable,cp); return false; ok: //ポインタ変数の場合 if( pVar->GetType().IsPointer() ){ if( !pVar->IsArray() ){ lstrcpy(lpPtrOffset,array); array[0]=0; } } else{ if(lpPtrOffset[0]){ if(isErrorEnabled) compiler.errorMessenger.Output(16,variable,cp); return false; } } resultType = pVar->GetType(); if(member[0]){ if( NATURAL_TYPE( resultType.GetBasicType() )==DEF_OBJECT || NATURAL_TYPE( resultType.GetBasicType() )==DEF_STRUCT) { return GetMemberType(resultType,member,resultType,0,isErrorEnabled); } } if( array[0] == 0 && pVar->GetSubscripts().size() > 0 ){ //配列の先頭ポインタを示す場合 resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR ); } if(lpPtrOffset[0]){ if( resultType.PtrLevel() ){ resultType.PtrLevelDown(); } else{ //エラー if(isErrorEnabled) compiler.errorMessenger.Output(1,NULL,cp); return false; } } return true; } bool GetVarOffsetReadOnly(const char *NameBuffer,RELATIVE_VAR *pRelativeVar,Type &resultType, Subscripts *pResultSubscripts ) { //読み取り専用で変数へアクセス return GetVarOffset( true, //エラー表示有効 false, //書き込みアクセスは無し NameBuffer, pRelativeVar, resultType, pResultSubscripts ); } bool GetVarOffsetReadWrite(const char *NameBuffer,RELATIVE_VAR *pRelativeVar,Type &resultType, Subscripts *pResultSubscripts ) { //読み書き両用で変数へアクセス return GetVarOffset( true, //エラー表示有効 true, //書き込みアクセス NameBuffer, pRelativeVar, resultType, pResultSubscripts ); } bool GetDimentionFormat( const char *buffer, char *VarName, Subscripts &subscripts, Type &type, char *InitBuf, char *ConstractParameter ){ int i,i2,i3,IsStr; char variable[VN_SIZE],temporary[8192]; for(i=0;;i++){ if((buffer[i]==1&&buffer[i+1]==ESC_AS)|| buffer[i]=='='|| buffer[i]=='\0'){ variable[i]=0; break; } variable[i]=buffer[i]; } if(buffer[i]=='='){ //////////////////////////////////// // 初期化データが指定されいるとき //////////////////////////////////// i++; if( buffer[i]=='[' ){ // 構造初期データの場合 i3=GetStringInBracket(InitBuf,buffer+i); i+=i3; } else{ // 代入初期データの場合 for(i2=0,IsStr=0;;i++,i2++){ if(buffer[i]=='\"') IsStr^=1; if(buffer[i]=='('&&IsStr==0){ i3=GetStringInPare(InitBuf+i2,buffer+i); i+=i3-1; i2+=i3-1; continue; } if(buffer[i]=='['&&IsStr==0){ i3=GetStringInBracket(InitBuf+i2,buffer+i); i+=i3-1; i2+=i3-1; continue; } if((buffer[i]==','&&IsStr==0)|| buffer[i]=='\0'){ InitBuf[i2]=0; break; } InitBuf[i2]=buffer[i]; } } } else{ //初期化データなし InitBuf[0]=0; } ConstractParameter[0]=0; if(buffer[i]==1&&buffer[i+1]==ESC_AS){ ///////////////////////////// // "As 〜" による型指定あり ///////////////////////////// for(i+=2,i2=0;;i++,i2++){ if(buffer[i]=='('||buffer[i]=='\0'){ temporary[i2]=0; break; } temporary[i2]=buffer[i]; } if(temporary[0]=='*'&& temporary[1]==1&& (temporary[2]==ESC_FUNCTION||temporary[2]==ESC_SUB)){ if(buffer[i]!='('){ compiler.errorMessenger.Output(10,temporary,cp); return false; } i3=GetStringInPare(temporary+3,buffer+i); i+=i3; i2+=i3; if(temporary[2]==ESC_FUNCTION&&buffer[i]==1&&buffer[i+1]==ESC_AS){ temporary[i2++]=buffer[i++]; temporary[i2++]=buffer[i++]; for(;;i++,i2++){ if(!IsVariableChar(buffer[i])){ temporary[i2]=0; break; } temporary[i2]=buffer[i]; } } } ActiveBasic::Compiler::Error::StringToTypeErrorCode::EnumType result = compiler.StringToTypeEx( temporary, type, true ); if( result != ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful ) { if( result == ActiveBasic::Compiler::Error::StringToTypeErrorCode::FailedResolveGenericType ) { compiler.errorMessenger.Output(143,temporary,cp); } else { compiler.errorMessenger.Output(3,temporary,cp); } return false; } if(buffer[i]=='('){ //コンストラクタに渡すパラメータを取得 i2=GetStringInPare(ConstractParameter,buffer+i); i+=i2; RemoveStringPare(ConstractParameter); if( !type.IsObject() ){ compiler.errorMessenger.Output(112,variable,cp); return false; } } } else{ ///////////////// // As指定なし ///////////////// if( InitBuf[0] == '\0' ){ //As指定も、初期値指定もない場合 type.SetBasicType( Type::GetBasicTypeFromSimpleName(variable) ); i2=lstrlen(variable)-1; if(i2>=0){ if(!(variable[i2]=='#'||variable[i2]=='!'||variable[i2]=='%'||variable[i2]=='$')) compiler.errorMessenger.Output(-103,variable,cp); } } else{ //初期値の型を判別して自動的に型情報を付加する if( !NumOpe_GetType( InitBuf, GetStringTypeInfo(), type ) ){ // エラーの場合 return false; } if( IS_LITERAL( type.GetIndex() ) ){ type.SetIndex( -1 ); } } } if( InitBuf[0] != '\0' && ConstractParameter[0] != '\0' ){ //初期値とコンストラクタパラメータが同時に呼び出されているとき compiler.errorMessenger.Output(132, NULL, cp); } GetArrange(variable,VarName,subscripts); return true; } BOOL GetNowStaticVarFullName(char *VarName,char *FullName){ if( compiler.IsGlobalAreaCompiling() ){ // グローバル領域をコンパイル中のとき return 0; } const UserProc &proc = compiler.GetCompilingUserProc(); //Static識別 lstrcpy(FullName,"Static%"); //クラス名 if( compiler.IsCompilingClass() ){ lstrcat(FullName,compiler.GetCompilingClass().GetName().c_str()); lstrcat(FullName,"%"); } //関数(またはメソッド)名 lstrcat(FullName,proc.GetName().c_str()); lstrcat(FullName,"%"); //ID char temp[255]; sprintf(temp,"%x",proc.GetId()); lstrcat(FullName,temp); lstrcat(FullName,"%"); //変数名 lstrcat(FullName,VarName); return 1; } void AddGlobalVariable( const char *name, const Subscripts &subscripts, const Type &type,const char *InitBuf,const char *ConstractParameter,DWORD dwFlag){ ///////////////////////// // グローバル変数を追加 ///////////////////////// if( compiler.GetObjectModule().meta.GetGlobalVars().DuplicateCheck( LexicalAnalyzer::FullNameToSymbol( name ), compiler.codeGenerator.lexicalScopes.GetNowLevel() ) ){ //2重定義のエラー compiler.errorMessenger.Output(15,name,cp); return; } bool isConst = ( dwFlag & DIMFLAG_CONST ) ? true:false; Variable *pVar = new Variable( Symbol( compiler.GetNamespaceSupporter().GetLivingNamespaceScopes(), name ), type, isConst, false, ConstractParameter, ( InitBuf[0] != 0 || dwFlag == DIMFLAG_INITDEBUGVAR ) ); if( subscripts.size() > 0 ){ //配列あり pVar->SetArray( subscripts ); } //レキシカルスコープ pVar->SetScopeLevel( compiler.codeGenerator.lexicalScopes.GetNowLevel() ); pVar->SetScopeStartAddress( compiler.codeGenerator.lexicalScopes.GetStartAddress() ); pVar->isLiving = true; //エラー用 pVar->source_code_address=cp; // 変数を追加 compiler.GetObjectModule().meta.GetGlobalVars().Add( pVar ); if(InitBuf[0]){ int result = 0; if( !pVar->GetType().IsObject() ){ result = SetInitGlobalData(pVar->GetOffsetAddress(), pVar->GetType(), pVar->GetSubscripts(), InitBuf); } if(!result){ //動的な式だった場合は代入演算を行う //初期代入時のみ、書き込みアクセスを許可する if( isConst ){ pVar->ConstOff(); } //代入 char temporary[8192]; sprintf(temporary,"%s=%s",name,InitBuf); OpcodeCalc(temporary); //アクセス制限を元に戻す if( isConst ){ pVar->ConstOn(); } } } if( type.IsObject() ){ //デストラクタの利用フラグをオンにする const CMethod *method = type.GetClass().GetDestructorMethod(); if( method ){ method->GetUserProc().Using(); } } } void dim(char *Parameter,DWORD dwFlags){ int i2; char VarName[VN_SIZE]; i2 = 0; if( Parameter[i2] == 1 && Parameter[i2+1] == ESC_BYREF ){ //参照型 compiler.errorMessenger.OutputFatalError(); Parameter += 2; } if(dwFlags & DIMFLAG_CONST){ ////////////////////////////////// // 定数変数の場合を考慮 ////////////////////////////////// for(;;i2++){ if(Parameter[i2] == '=' || Parameter[i2] == 1 && Parameter[i2] == ESC_AS || Parameter[i2] =='('){ VarName[i2] = 0; break; } VarName[i2] = Parameter[i2]; } //定数と2重定義されていないる場合は抜け出す if(compiler.GetObjectModule().meta.GetGlobalConsts().GetBasicType( ActiveBasic::Compiler::LexicalAnalyzer::FullNameToSymbol( VarName ) )){ return; } //定数マクロとして定義されている場合は抜け出す if( compiler.GetObjectModule().meta.GetGlobalConstMacros().IsExistDuplicationKeyName( VarName ) ) { return; } } //構文を解析 Type type; char InitBuf[8192]; char ConstractParameter[VN_SIZE]; Subscripts subscripts; if(!GetDimentionFormat(Parameter, VarName,subscripts,type,InitBuf,ConstractParameter)) return; //定数と2重定義されていないかを調べる if(compiler.GetObjectModule().meta.GetGlobalConsts().GetBasicType( ActiveBasic::Compiler::LexicalAnalyzer::FullNameToSymbol( VarName ) )){ compiler.errorMessenger.Output(15,VarName,cp); return; } //定数マクロとして定義されている場合 if( compiler.GetObjectModule().meta.GetGlobalConstMacros().IsExistDuplicationKeyName( VarName ) ){ compiler.errorMessenger.Output(15,VarName,cp); return; } if( type.IsObject() ){ if( type.GetClass().IsBlittableType() ){ // Blittable型のときは基本型として扱う // ※ただし、コンパイル中のメソッドがBlittable型クラスに属していないこと if( compiler.IsLocalAreaCompiling() && compiler.GetCompilingUserProc().HasParentClass() && compiler.GetCompilingUserProc().GetParentClass().IsBlittableType() ) { // コンパイル中のメソッドがBlittable型クラスに属している } else{ type = type.GetClass().GetBlittableType(); } } } if(dwFlags&DIMFLAG_STATIC) { if( compiler.IsGlobalAreaCompiling() ) { compiler.errorMessenger.Output(60,NULL,cp); return; } ///////////////////// // Static変数 // ※"Static.Object.Method.Variable" ///////////////////// char temporary[VN_SIZE]; GetNowStaticVarFullName(VarName,temporary); dim( temporary,subscripts,type,InitBuf,ConstractParameter,dwFlags ); /* Note: 静的変数のコンストラクタ呼び出しは _System_InitStaticLocalVariables関数内で一括して行う */ } else{ dim( VarName,subscripts,type,InitBuf,ConstractParameter,dwFlags ); } } void OpcodeDim(char *Parameter,DWORD dwFlags){ int i,i2,i3,IsStr=0; char temporary[8192]; for(i=0,i2=0;;i++,i2++){ if(Parameter[i]=='\"') IsStr^=1; if(Parameter[i]=='('&&IsStr==0){ i3=GetStringInPare(temporary+i2,Parameter+i); i+=i3-1; i2+=i3-1; continue; } if(Parameter[i]=='['&&IsStr==0){ i3=GetStringInBracket(temporary+i2,Parameter+i); i+=i3-1; i2+=i3-1; continue; } if( Parameter[i] == '<' && IsStr == 0 ) { if( IsGenericTypeSourcePart( Parameter + i ) ) { // ジェネリクス構文 i3=GetStringInGenericBracket(temporary+i2,Parameter+i); i+=i3-1; i2+=i3-1; continue; } else { // 一般構文 } } if((Parameter[i]==','&&IsStr==0)|| Parameter[i]=='\0'){ temporary[i2]=0; dim(temporary,dwFlags); if(Parameter[i]=='\0') break; i2=-1; continue; } temporary[i2]=Parameter[i]; } } void DebugVariable(void) { char temporary[255]; if( compiler.GetObjectModule().meta.GetGlobalVars().Find( LexicalAnalyzer::FullNameToSymbol( "_DebugSys_dwThreadID" ) ) == NULL ) { // 未定義の場合は定義する sprintf(temporary,"_DebugSys_dwThreadID[255]%c%cDWord",1,ESC_AS); OpcodeDim(temporary,DIMFLAG_INITDEBUGVAR); sprintf(temporary,"_DebugSys_ProcNum[255]%c%cDWord",1,ESC_AS); OpcodeDim(temporary,DIMFLAG_INITDEBUGVAR); sprintf(temporary,"_DebugSys_lplpObp[255]%c%c*ULONG_PTR",1,ESC_AS); OpcodeDim(temporary,DIMFLAG_INITDEBUGVAR); sprintf(temporary,"_DebugSys_lplpSpBase[255]%c%c*ULONG_PTR",1,ESC_AS); OpcodeDim(temporary,DIMFLAG_INITDEBUGVAR); } }