#include "stdafx.h" #include #include #include "../common.h" #ifdef _AMD64_ #include "../../compiler_x64/opcode.h" #else #include "../../compiler_x86/opcode.h" #endif using namespace ActiveBasic::Compiler; bool UserProc::IsEqualForOverride( const Types &actualTypeParametersForThisProc, const UserProc *pUserProc ) const { if( this->GetName() == pUserProc->GetName() // 名前空間及び名前が等しい && this->Params().Equals( actualTypeParametersForThisProc, pUserProc->Params() ) ) // パラメータが等しい { if( this->returnType.Equals( pUserProc->returnType ) ) { // 戻り値が等しい return true; } else if( this->returnType.IsCovariant( pUserProc->returnType ) ) { // 戻り値が共変 return true; } else if( this->returnType.IsTypeParameter() ) { // 型パラメータだったとき if( actualTypeParametersForThisProc[this->returnType.GetFormalTypeIndex()].Equals( pUserProc->returnType ) ) { // 戻り値が等しい return true; } else if( actualTypeParametersForThisProc[this->returnType.GetFormalTypeIndex()].IsCovariant( pUserProc->returnType ) ) { // 戻り値が共変 return true; } } } return false; } std::string UserProc::GetFullName() const { if( HasParentClass() ){ return GetParentClass().GetName() + "." + GetName(); } return GetName(); } bool UserProc::IsCastOperator() const { if( GetName()[0] == 1 && GetName()[1] == ESC_OPERATOR && GetName()[2] == CALC_AS ) { return true; } return false; } const NamespaceScopes &UserProc::GetNamespaceScopes() const { if( HasParentClass() ){ return GetParentClassPtr()->GetNamespaceScopes(); } return Symbol::GetNamespaceScopes(); } const NamespaceScopesCollection &UserProc::GetImportedNamespaces() const { if( pParentClass ) { return pParentClass->GetImportedNamespaces(); } return importedNamespaces; } bool UserProc::IsVirtual() const { if( pMethod == NULL ){ return false; } return ( pMethod->IsVirtual() != 0 ); } const CMethod &UserProc::GetMethod() const { if( !HasParentClass() ) { Jenga::Throw( "グローバル関数に対してUserProc::GetMethodメソッドが呼ばれた" ); } return *pMethod; } const UserProc *UserProc::pGlobalProc = NULL; bool UserProcs::Insert( UserProc *pUserProc, int nowLine ) { ///////////////////////////////// // ハッシュデータに追加 ///////////////////////////////// if( !Put( pUserProc ) ) { // 重複しているため、失敗 compiler.errorMessenger.Output(15,pUserProc->GetName().c_str(),nowLine); return false; } return true; } void UserProcs::EnumGlobalProcs( const char *simpleName, const char *localName, std::vector &subs ) { /////////////////////////// // グローバル関数を検索 /////////////////////////// // ハッシュ値を取得 UserProc *pUserProc = GetHashArrayElement( simpleName ); while(pUserProc){ if( pUserProc->IsGlobalProcedure() ){ if( pUserProc->IsEqualSymbol( LexicalAnalyzer::FullNameToSymbol( localName ) ) ){ subs.push_back( pUserProc ); } } pUserProc=pUserProc->GetChainNext(); } } bool DllProc::SetParamsAndReturnType( const char *sourceOfParams, int nowLine ){ int i = 0; int i2,i3,sw; char temporary[8192],temp2[VN_SIZE]; //ソースコードの位置 this->codePos = nowLine; //パラメータ if(sourceOfParams[i]!='('){ compiler.errorMessenger.Output(1,NULL,nowLine); return 0; } i++; while(1){ if(sourceOfParams[i]==')') break; //ByRef bool isRef; if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYVAL){ isRef = false; i+=2; } else if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYREF){ isRef = true; i+=2; } else isRef = false; //パラメータ名 bool isArray = false; Subscripts subscripts; char name[VN_SIZE]; sw=0; for(i2=0;;i++,i2++){ if(sourceOfParams[i]=='('){ if(!sw) sw=1; i3=GetStringInPare(name+i2,sourceOfParams+i); i2+=i3-1; i+=i3-1; continue; } if(sourceOfParams[i]=='['){ if(!sw) sw=1; i3=GetStringInBracket(name+i2,sourceOfParams+i); i2+=i3-1; i+=i3-1; continue; } if(!IsVariableChar(sourceOfParams[i])){ name[i2]=0; break; } name[i2]=sourceOfParams[i]; } if(sw){ //配列パラメータ if( isRef == false ) compiler.errorMessenger.Output(29,NULL,nowLine); isArray = true; if((name[i2-2]=='('&&name[i2-1]==')')|| (name[i2-2]=='['&&name[i2-1]==']')) { subscripts.push_back( LONG_MAX ); name[i2-2]=0; } else{ GetArrange(name,temp2,subscripts); lstrcpy(name,temp2); } i2=lstrlen(name); } //型 Type type( DEF_NON ); if(lstrcmp(name,"...")==0) type.SetBasicType( DEF_ELLIPSE ); else if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_AS){ i+=2; i2=0; while(sourceOfParams[i]=='*'){ temporary[i2]=sourceOfParams[i]; i++; i2++; } for(;;i++,i2++){ if(!IsVariableChar(sourceOfParams[i])){ if(sourceOfParams[i]==1&&(sourceOfParams[i+1]==ESC_FUNCTION||sourceOfParams[i+1]==ESC_SUB)){ temporary[i2++]=sourceOfParams[i++]; temporary[i2]=sourceOfParams[i]; continue; } temporary[i2]=0; break; } temporary[i2]=sourceOfParams[i]; } compiler.StringToType( temporary, type ); if( type.IsNull() ){ compiler.errorMessenger.Output(3,temporary,nowLine); type.SetBasicType( DEF_PTR_VOID ); } } else{ type.SetBasicType( Type::GetBasicTypeFromSimpleName(temporary) ); compiler.errorMessenger.Output(-103,temporary,nowLine); } Parameter *pParam = new Parameter( name, type, isRef ); if( isArray ){ pParam->SetArray( subscripts ); } //パラメータを追加 this->GetParameters().push_back( pParam ); if(sourceOfParams[i]==','){ i++; continue; } else if(sourceOfParams[i]==')') continue; else{ compiler.errorMessenger.Output(1,NULL,nowLine); break; } } i++; if(sourceOfParams[i]){ /////////////////// // 戻り値を取得 /////////////////// i2=lstrlen(sourceOfParams)-2; int sw_as=0; for(;i2>0;i2--){ if(sourceOfParams[i2]==')') break; if(sourceOfParams[i2]==1&&sourceOfParams[i2+1]==ESC_AS){ i2+=2; i3=0; while(sourceOfParams[i2]=='*') temporary[i3++]=sourceOfParams[i2++]; for(;;i2++,i3++){ if(!IsVariableChar(sourceOfParams[i2])){ temporary[i3]=0; break; } temporary[i3]=sourceOfParams[i2]; } compiler.StringToType( temporary, this->returnType ); if( this->returnType.IsNull() ) compiler.errorMessenger.Output(3,temporary,nowLine); sw_as=1; break; } } } else{ //戻り値なしのSub定義 this->returnType.SetNull(); } return true; } bool ProcPointer::SetParamsAndReturnType( const char *sourceOfParams, int nowLine ){ int i = 0; int i2,i3,sw; char temporary[8192],temp2[VN_SIZE]; //ソースコードの位置 this->codePos = nowLine; //パラメータ if(sourceOfParams[i]!='('){ compiler.errorMessenger.Output(1,NULL,nowLine); return 0; } i++; while(1){ if(sourceOfParams[i]==')') break; //ByRef bool isRef; if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYVAL){ isRef = false; i+=2; } else if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_BYREF){ isRef = true; i+=2; } else isRef = false; //パラメータ名 bool isArray = false; Subscripts subscripts; char name[VN_SIZE]; sw=0; for(i2=0;;i++,i2++){ if(sourceOfParams[i]=='('){ if(!sw) sw=1; i3=GetStringInPare(name+i2,sourceOfParams+i); i2+=i3-1; i+=i3-1; continue; } if(sourceOfParams[i]=='['){ if(!sw) sw=1; i3=GetStringInBracket(name+i2,sourceOfParams+i); i2+=i3-1; i+=i3-1; continue; } if(!IsVariableChar(sourceOfParams[i])){ name[i2]=0; break; } name[i2]=sourceOfParams[i]; } if(sw){ //配列パラメータ if( isRef == false ) compiler.errorMessenger.Output(29,NULL,nowLine); isArray = true; if((name[i2-2]=='('&&name[i2-1]==')')|| (name[i2-2]=='['&&name[i2-1]==']')) { subscripts.push_back( LONG_MAX ); name[i2-2]=0; } else{ GetArrange(name,temp2,subscripts); lstrcpy(name,temp2); } i2=lstrlen(name); } //型 Type type( DEF_NON ); if(sourceOfParams[i]==1&&sourceOfParams[i+1]==ESC_AS){ i+=2; i2=0; while(sourceOfParams[i]=='*'){ temporary[i2]=sourceOfParams[i]; i++; i2++; } for(;;i++,i2++){ if(!IsVariableChar(sourceOfParams[i])){ if(sourceOfParams[i]==1&&(sourceOfParams[i+1]==ESC_FUNCTION||sourceOfParams[i+1]==ESC_SUB)){ temporary[i2++]=sourceOfParams[i++]; temporary[i2]=sourceOfParams[i]; continue; } temporary[i2]=0; break; } temporary[i2]=sourceOfParams[i]; } compiler.StringToType( temporary, type ); if( type.IsNull() ){ compiler.errorMessenger.Output(3,temporary,nowLine); type.SetBasicType( DEF_PTR_VOID ); } } else{ type.SetBasicType( Type::GetBasicTypeFromSimpleName(temporary) ); compiler.errorMessenger.Output(-103,temporary,nowLine); } Parameter *pParam = new Parameter( name, type, isRef ); if( isArray ){ pParam->SetArray( subscripts ); } //パラメータを追加 this->GetParameters().push_back( pParam ); if(sourceOfParams[i]==','){ i++; continue; } else if(sourceOfParams[i]==')') continue; else{ compiler.errorMessenger.Output(1,NULL,nowLine); break; } } i++; if(sourceOfParams[i]){ /////////////////// // 戻り値を取得 /////////////////// i2=lstrlen(sourceOfParams)-2; int sw_as=0; for(;i2>0;i2--){ if(sourceOfParams[i2]==')') break; if(sourceOfParams[i2]==1&&sourceOfParams[i2+1]==ESC_AS){ i2+=2; i3=0; while(sourceOfParams[i2]=='*') temporary[i3++]=sourceOfParams[i2++]; for(;;i2++,i3++){ if(!IsVariableChar(sourceOfParams[i2])){ temporary[i3]=0; break; } temporary[i3]=sourceOfParams[i2]; } compiler.StringToType( temporary, this->returnType ); if( this->returnType.IsNull() ) compiler.errorMessenger.Output(3,temporary,nowLine); sw_as=1; break; } } } else{ //戻り値なしのSub定義 this->returnType.SetNull(); } //戻り値のエラーチェック if( IsFunction() ){ // Function定義 if( this->ReturnType().IsNull() ){ // 戻り値がない compiler.errorMessenger.Output(26,this->GetName(),nowLine); } } else{ if( !this->ReturnType().IsNull() ){ // Sub定義なのに、戻り値がある compiler.errorMessenger.Output(38,this->GetName(),nowLine); } } return true; } int ProcPointers::Add( const std::string &typeExpression ) { DWORD dwProcType = (DWORD)typeExpression[2]; const std::string ¶mStr = typeExpression.substr( 3 ); Procedure::Kind kind = Procedure::Sub; if( dwProcType == ESC_FUNCTION ){ kind = Procedure::Function; } ProcPointer *pProcPointer = new ProcPointer( kind ); //buffer[0]は'('となっている extern int cp; pProcPointer->SetParamsAndReturnType( paramStr.c_str(), cp ); this->push_back( pProcPointer ); return (int)this->size()-1; } void ProcPointers::Clear() { ProcPointers &procPointers = *this; BOOST_FOREACH( ProcPointer *pProcPointer, procPointers ){ delete pProcPointer; } this->clear(); }