#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 WITHINFO WithInfo; int i; buffer[0]=0; for(i=0;iIsNoneAccess() ){ 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); } }