#include "stdafx.h" #include #include #include #include #include #include #include #include "../common.h" #ifdef _AMD64_ #include "../../BasicCompiler64/opcode.h" #else #include "../../BasicCompiler32/opcode.h" #endif class CLoopRefCheck{ char **names; int num; void init(){ int i; for(i=0;iHasSuperClass() ) { return false; } const CClass *pTempClass = &pClass->GetSuperClass(); while( pTempClass ){ if( this == pTempClass ) return true; pTempClass = &pTempClass->GetSuperClass(); } return false; } //自身と等しいまたは派生クラスかどうかを確認 bool CClass::IsEqualsOrSubClass( const CClass *pClass ) const { if( IsEquals( pClass ) ) return true; return IsSubClass( pClass ); } // 自身と等しいまたは派生クラス、基底クラスかどうかを確認 bool CClass::IsEqualsOrSubClassOrSuperClass( const CClass &objClass ) const { if( IsEquals( &objClass ) ) return true; if( IsSubClass( &objClass ) ) return true; if( objClass.IsSubClass( this ) ) return true; return false; } bool CClass::IsInheritsInterface( const CClass *pInterfaceClass ) const { BOOST_FOREACH( const InheritedInterface &objInterface, interfaces ){ if( pInterfaceClass == &objInterface.GetInterfaceClass() ){ return true; } } return false; } bool CClass::Inherits( const char *inheritNames, int nowLine ){ int i = 0; bool isInheritsClass = false; while( true ){ char temporary[VN_SIZE]; for( int i2=0;; i++, i2++ ){ if( inheritNames[i] == '\0' || inheritNames[i] == ',' ){ temporary[i2] = 0; break; } temporary[i2] = inheritNames[i]; } // ジェネリクス構文を分解 char className[VN_SIZE]; Jenga::Common::Strings typeParameterStrings; SplitGenericClassInstance( temporary, className, typeParameterStrings ); // 型パラメータ文字列から型データを取得 std::vector actualTypeParameters; BOOST_FOREACH( const std::string &typeParameterStr, typeParameterStrings ) { Type type; compiler.StringToType( typeParameterStr, type ); actualTypeParameters.push_back( type ); } //継承元クラスを取得 const CClass *pInheritsClass = compiler.GetObjectModule().meta.GetClasses().Find(className); if( !pInheritsClass ){ SmoothieException::Throw(106,className,nowLine); return false; } if( pInheritsClass->IsInterface() ){ // インターフェイスはあとで継承する } else if( pInheritsClass->IsClass() ){ // クラスを継承する isInheritsClass = true; if( !InheritsClass( *pInheritsClass, actualTypeParameters, nowLine ) ){ return false; } } else{ SmoothieException::Throw(135,NULL,nowLine); return false; } if( inheritNames[i] == '\0' ){ break; } i++; } if( !isInheritsClass ){ // クラスを一つも継承していないとき if( !InheritsClass( *compiler.GetObjectModule().meta.GetClasses().GetObjectClassPtr(), Types(), nowLine ) ){ return false; } } i=0; while( true ){ char temporary[VN_SIZE]; for( int i2=0;; i++, i2++ ){ if( inheritNames[i] == '\0' || inheritNames[i] == ',' ){ temporary[i2] = 0; break; } temporary[i2] = inheritNames[i]; } char className[VN_SIZE]; Jenga::Common::Strings typeParameters; SplitGenericClassInstance( temporary, className, typeParameters ); //継承元クラスを取得 const CClass *pInheritsClass = compiler.GetObjectModule().meta.GetClasses().Find(className); if( !pInheritsClass ){ SmoothieException::Throw(106,className,nowLine); return false; } if( pInheritsClass->IsInterface() ){ // インターフェイスを継承する if( !InheritsInterface( *pInheritsClass, nowLine ) ){ return false; } } else if( pInheritsClass->IsClass() ){ // クラスはさっき継承した } else{ SmoothieException::Throw(135,NULL,nowLine); return false; } if( inheritNames[i] == '\0' ){ break; } i++; } return true; } bool CClass::InheritsClass( const CClass &inheritsClass, const Types &actualTypeParameters, int nowLine ){ //ループ継承でないかをチェック if(pobj_LoopRefCheck->check(inheritsClass)){ SmoothieException::Throw(123,inheritsClass.GetName(),nowLine); return false; } if( !inheritsClass.IsReady() ){ //継承先が読み取られていないとき pobj_LoopRefCheck->add(this->GetName().c_str()); compiler.GetObjectModule().meta.GetClasses().GetClass_recur(inheritsClass.GetName().c_str()); pobj_LoopRefCheck->del(this->GetName().c_str()); } //メンバをコピー BOOST_FOREACH( CMember *inheritsClassDynamicMember, inheritsClass.GetDynamicMembers() ){ CMember *pMember = new CMember( *inheritsClassDynamicMember ); // アクセシビリティ if( inheritsClassDynamicMember->IsPrivate() ){ pMember->SetAccessibility( Prototype::None ); } else{ pMember->SetAccessibility( inheritsClassDynamicMember->GetAccessibility() ); } // メンバのみ、型パラメータを解決する(メソッドのほうは呼び出し時に解決する) if( pMember->GetType().IsTypeParameter() ) { pMember->ResetType( actualTypeParameters[pMember->GetType().GetFormalTypeIndex()] ); } dynamicMembers.push_back( pMember ); } //メソッドをコピー BOOST_FOREACH( const CMethod *pBaseMethod, inheritsClass.GetMethods() ){ CMethod *pMethod = new DynamicMethod( *pBaseMethod ); // アクセシビリティ if(pBaseMethod->GetAccessibility() == Prototype::Private){ pMethod->SetAccessibility( Prototype::None ); } else{ pMethod->SetAccessibility( pBaseMethod->GetAccessibility() ); } //pobj_Inherits // ※継承元のClassIndexをセット(入れ子継承を考慮する) if(pBaseMethod->GetInheritsClassPtr()==0){ pMethod->SetInheritsClassPtr( &inheritsClass ); } else{ pMethod->SetInheritsClassPtr( pBaseMethod->GetInheritsClassPtr() ); } methods.push_back( pMethod ); } //仮想関数の数 AddVtblNum( inheritsClass.GetVtblNum() ); //継承先のクラスをメンバとして保持する SetSuperClass( &inheritsClass ); SetSuperClassActualTypeParameters( actualTypeParameters ); return true; } bool CClass::InheritsInterface( const CClass &inheritsInterface, int nowLine ){ //ループ継承でないかをチェック if(pobj_LoopRefCheck->check(inheritsInterface)){ SmoothieException::Throw(123,inheritsInterface.GetName(),nowLine); return false; } if( !inheritsInterface.IsReady() ){ //継承先が読み取られていないとき pobj_LoopRefCheck->add(this->GetName().c_str()); compiler.GetObjectModule().meta.GetClasses().GetClass_recur(inheritsInterface.GetName().c_str()); pobj_LoopRefCheck->del(this->GetName().c_str()); } //メソッドをコピー BOOST_FOREACH( const CMethod *pBaseMethod, inheritsInterface.GetMethods() ){ CMethod *pMethod = new DynamicMethod( *pBaseMethod ); // アクセシビリティ if(pBaseMethod->GetAccessibility() == Prototype::Private){ pMethod->SetAccessibility( Prototype::None ); } else{ pMethod->SetAccessibility( pBaseMethod->GetAccessibility() ); } //pobj_Inherits // ※継承元のClassIndexをセット(入れ子継承を考慮する) if(pBaseMethod->GetInheritsClassPtr()==0){ pMethod->SetInheritsClassPtr( &inheritsInterface ); } else{ pMethod->SetInheritsClassPtr( pBaseMethod->GetInheritsClassPtr() ); } methods.push_back( pMethod ); } interfaces.push_back( InheritedInterface( const_cast(&inheritsInterface), vtblNum ) ); //仮想関数の数 AddVtblNum( inheritsInterface.GetVtblNum() ); return true; } CMember *CClass::CreateMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ) { extern int cp; //構文を解析 char VarName[VN_SIZE]; char initBuffer[VN_SIZE]; char lpszConstructParameter[VN_SIZE]; Subscripts subscripts; Type type; GetDimentionFormat(buffer,VarName,subscripts,type,initBuffer,lpszConstructParameter); //重複チェック if(this->DupliCheckAll(VarName)){ SetError(15,VarName,cp); } CMember *pMember = new CMember( accessibility, VarName, type, isConst, subscripts, initBuffer, lpszConstructParameter ); pMember->source_code_address = nowLine; return pMember; } void CClass::AddMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){ dynamicMembers.push_back( CreateMember( accessibility, isConst, isRef, buffer, nowLine ) ); } void CClass::AddStaticMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){ staticMembers.push_back( CreateMember( accessibility, isConst, isRef, buffer, nowLine ) ); } void CClass::AddMethod(CClass *pobj_c, Prototype::Accessibility accessibility, BOOL bStatic, bool isConst, bool isAbstract, bool isVirtual, bool isOverride, char *buffer, int nowLine){ int i,i2; char temporary[VN_SIZE]; i=2; for(i2=0;;i++,i2++){ if(buffer[i]=='('||buffer[i]=='\0'){ temporary[i2]=0; break; } temporary[i2]=buffer[i]; } //関数ハッシュへ登録 UserProc *pUserProc = compiler.GetObjectModule().meta.GetUserProcs().Add( NamespaceScopes(), NamespaceScopesCollection(), buffer,nowLine,isVirtual,pobj_c, (bStatic!=0) ); if(!pUserProc) return; //////////////////////////////////////////////////////////// // コンストラクタ、デストラクタの場合の処理 //////////////////////////////////////////////////////////// BOOL fConstructor=0,bDestructor=0; if(lstrcmp(temporary,pobj_c->GetName().c_str())==0){ //コンストラクタの場合 //標準コンストラクタ(引数なし) if(pUserProc->Params().size()==0) fConstructor=1; //強制的にConst修飾子をつける isConst = true; } else if(temporary[0]=='~'){ //デストラクタの場合はその名前が正しいかチェックを行う if(lstrcmp(temporary+1,pobj_c->GetName().c_str())!=0) SetError(117,NULL,nowLine); else bDestructor=1; } if(fConstructor||bDestructor){ // コンストラクタ、デストラクタのアクセシビリティをチェック //強制的にConst修飾子をつける isConst = true; } if( fConstructor == 1 ) pobj_c->SetConstructorMemberSubIndex( (int)pobj_c->GetMethods().size() ); else if( bDestructor ) pobj_c->SetDestructorMemberSubIndex( (int)pobj_c->GetMethods().size() ); ////////////////// // 重複チェック ////////////////// if(pobj_c->DupliCheckMember(temporary)){ SetError(15,temporary,nowLine); return; } //メソッド BOOST_FOREACH( const CMethod *pMethod, pobj_c->GetMethods() ){ //基底クラスと重複する場合はオーバーライドを行う if( pMethod->GetInheritsClassPtr() ) continue; if( pMethod->GetUserProc().GetName() == temporary ){ if( pMethod->GetUserProc().Params().Equals( pUserProc->Params() ) ){ //関数名、パラメータ属性が合致したとき SetError(15,pUserProc->GetName().c_str(),nowLine); return; } } } //仮想関数の場合 if( isAbstract ) pUserProc->CompleteCompile(); //メソッドのオーバーライド BOOST_FOREACH( CMethod *pMethod, pobj_c->GetMethods() ){ if( pMethod->GetUserProc().GetName() == temporary ){ if( pMethod->GetUserProc().Params().Equals( pUserProc->Params() ) ) { //メンバ関数を上書き pMethod->SetUserProcPtr( pUserProc ); pMethod->Override(); if( !pMethod->IsVirtual() ) { // オーバーライドミス SetError(136,NULL,cp); } if( !isOverride ) { SetError(127,NULL,nowLine); } if(pMethod->GetAccessibility() != accessibility ) { SetError(128,NULL,nowLine); } pUserProc->SetMethod( pMethod ); return; } } } if( isVirtual ){ pobj_c->AddVtblNum( 1 ); } if( isOverride ){ SetError(12,"Override",nowLine); } if(bStatic){ pobj_c->GetStaticMethods().AddStatic( pUserProc, accessibility ); } else{ pobj_c->GetMethods().Add(pUserProc, accessibility, isConst, isAbstract, isVirtual); } } bool CClass::DupliCheckAll(const char *name){ //重複チェック //メンバ if(DupliCheckMember(name)) return 1; //メソッド BOOST_FOREACH( const CMethod *pMethod, methods ){ if( lstrcmp( name, pMethod->GetUserProc().GetName().c_str() ) == 0 ){ return 1; } } return 0; } bool CClass::DupliCheckMember(const char *name){ //重複チェック // 動的メンバ BOOST_FOREACH( CMember *pMember, dynamicMembers ){ if( GetName() == pMember->GetName() ){ return 1; } } // 静的メンバ BOOST_FOREACH( CMember *pMember, staticMembers ){ if( GetName() == pMember->GetName() ){ return 1; } } return 0; } //サイズを取得 int CClass::GetSize() const { return GetMemberOffset( NULL, NULL ); } //メンバのオフセットを取得 int CClass::GetMemberOffset( const char *memberName, int *pMemberNum ) const { int i2; //仮想関数が存在する場合は関数リストへのポインタのサイズを追加 int offset = IsExistVirtualFunctions() ? PTR_SIZE : 0; int alignment = 1; if( GetFixedAlignment() ) { alignment = GetFixedAlignment(); } int iMaxAlign=0; int i = -1; BOOST_FOREACH( CMember *pMember, dynamicMembers ){ i++; i2 = pMember->GetType().GetSize(); //アラインメントを算出 int member_size; if( pMember->GetType().IsStruct() ){ //メンバクラスのアラインメントを取得 member_size=pMember->GetType().GetClass().GetAlignment(); } else{ //メンバサイズを取得 member_size=i2; } if(iMaxAlignGetName() == memberName ){ if(pMemberNum) *pMemberNum=i; return offset; } } //配列を考慮したメンバサイズを取得 member_size = i2 * Variable::GetSubScriptCounts( pMember->GetSubscripts() ); //メンバサイズを加算 offset+= member_size; } if(iMaxAlignGetType().IsStruct()){ //メンバクラスのアラインメントを取得 member_size=pMember->GetType().GetClass().GetAlignment(); } else{ //メンバサイズを取得 member_size = pMember->GetType().GetSize(); } //アラインメントをセット if(alignmentGetUserProc() == pUserProc ) break; if( pMethod->IsVirtual() ) n++; } return n; } LONG_PTR CClass::GetVtblGlobalOffset(void) const { //既に存在する場合はそれを返す if(vtbl_offset!=-1) return vtbl_offset; ////////////////////////////////////// // 存在しないときは新たに生成する ////////////////////////////////////// const UserProc **ppsi; ppsi=(const UserProc **)malloc(GetVtblNum()*sizeof(UserProc *)); //関数テーブルに値をセット int i2 = 0; BOOST_FOREACH( const CMethod *pMethod, methods ){ if(pMethod->IsVirtual()){ pMethod->GetUserProc().Using(); if(pMethod->IsAbstract()){ extern int cp; SmoothieException::Throw(300,NULL,cp); ppsi[i2]=0; } else{ ppsi[i2]=&pMethod->GetUserProc(); } i2++; } } vtbl_offset=compiler.GetObjectModule().dataTable.AddBinary((void *)ppsi,GetVtblNum()*sizeof(LONG_PTR)); for( int i=0; i < GetVtblNum(); i++ ){ pobj_Reloc->AddSchedule_DataSection(vtbl_offset+i*sizeof(LONG_PTR)); } free(ppsi); return vtbl_offset; } void CClass::GenerateVTables() { if( IsAbstract() ) { // 抽象クラスは無視 return; } if( !IsUsing() ) { // 使われていないクラスは無視 return; } const UserProc **ppsi; ppsi=(const UserProc **)malloc(GetVtblNum()*sizeof(UserProc *)); //関数テーブルに値をセット int i2 = 0; BOOST_FOREACH( const CMethod *pMethod, methods ){ if(pMethod->IsVirtual()){ if( !pMethod->GetUserProc().IsUsing() ) { ts((char *)pMethod->GetUserProc().GetFullName().c_str()); } pMethod->GetUserProc().Using(); if(pMethod->IsAbstract()){ extern int cp; SmoothieException::Throw(300,NULL,cp); ppsi[i2]=0; } else{ ppsi[i2]=&pMethod->GetUserProc(); } i2++; } } vtbl_offset=compiler.GetObjectModule().dataTable.AddBinary((void *)ppsi,GetVtblNum()*sizeof(LONG_PTR)); for( int i=0; i < GetVtblNum(); i++ ){ pobj_Reloc->AddSchedule_DataSection(vtbl_offset+i*sizeof(LONG_PTR)); } free(ppsi); } void CClass::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){ if( IsAbstract() ) { // 抽象クラスは無視 return; } if( !IsUsing() ) { // 使われていないクラスは無視 return; } if(vtbl_offset==-1) return; LONG_PTR *pVtbl; pVtbl=(LONG_PTR *)((char *)compiler.GetObjectModule().dataTable.GetPtr()+vtbl_offset); int i; for(i=0;iGetBeginOpAddress() == 0 && pUserProc->GetEndOpAddress() == 0 ) { Jenga::Throw( "未解決の仮想関数が存在する" ); } pVtbl[i]=pUserProc->GetBeginOpAddress()+ImageBase+MemPos_CodeSection; } } bool CClass::IsAbstract() const { // 未実装(abstract)の仮想関数を持つ場合はtrueを返す BOOST_FOREACH( const CMethod *pMethod, methods ){ if(pMethod->IsVirtual()){ if(pMethod->IsAbstract()){ return true; } } } return false; } CClass *Classes::Create( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name){ return new CClass(namespaceScopes, importedNamespaces, name); } bool Classes::Insert( CClass *pClass ) { ///////////////////////////////// // ハッシュデータに追加 ///////////////////////////////// if( !Put( pClass ) ) { SetError(15,pClass->GetName(), cp); return false; } return true; } CClass *Classes::Add( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name,int nowLine){ ////////////////////////////////////////////////////////////////////////// // クラスを追加 // ※名前のみを登録。その他の情報はSetClassメソッドで! ////////////////////////////////////////////////////////////////////////// CClass *pClass = Create(namespaceScopes, importedNamespaces, name); if( !Insert( pClass ) ) { return NULL; } return pClass; } void Classes::CollectClassesForNameOnly( const BasicSource &source ) { int i, i2; char temporary[VN_SIZE]; // 名前空間管理 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes(); namespaceScopes.clear(); // Importsされた名前空間の管理 NamespaceScopesCollection &importedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces(); importedNamespaces.clear(); for(i=0;;i++){ if(source[i]=='\0') break; if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){ for(i+=2,i2=0;;i2++,i++){ if( IsCommandDelimitation( source[i] ) ){ temporary[i2]=0; break; } temporary[i2]=source[i]; } namespaceScopes.push_back( temporary ); continue; } else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){ if( namespaceScopes.size() <= 0 ){ SmoothieException::Throw(12, "End Namespace", i ); } else{ namespaceScopes.pop_back(); } i += 2; continue; } else if( source[i] == 1 && source[i+1] == ESC_IMPORTS ){ for(i+=2,i2=0;;i2++,i++){ if( IsCommandDelimitation( source[i] ) ){ temporary[i2]=0; break; } temporary[i2]=source[i]; } if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) ) { SmoothieException::Throw(64,temporary,i ); } continue; } else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED ){ importedNamespaces.clear(); continue; } if(source[i]==1&&( source[i+1]==ESC_CLASS|| source[i+1]==ESC_TYPE|| source[i+1]==ESC_INTERFACE )) { int nowLine = i; i += 2; Type blittableType; if(memicmp(source.GetBuffer()+i,"Align(",6)==0){ //アラインメント修飾子 i+=6; i=JumpStringInPare(source.GetBuffer(),i)+1; } else if( memicmp( source.GetBuffer() + i, "Blittable(", 10 ) == 0 ){ // Blittable修飾子 i+=10; i+=GetStringInPare_RemovePare(temporary,source.GetBuffer()+i)+1; compiler.StringToType( temporary, blittableType ); } bool isEnum = false; if( source[i] == 1 && source[i+1] == ESC_ENUM ){ // 列挙型の場合 isEnum = true; i+=2; } for(i2=0;;i++,i2++){ if(!IsVariableChar(source[i])){ temporary[i2]=0; break; } temporary[i2]=source[i]; } //クラスを追加 CClass *pClass = this->Add(namespaceScopes, importedNamespaces, temporary,nowLine); if( pClass ){ if( source[nowLine+1] == ESC_CLASS ){ if( isEnum ){ pClass->SetClassType( CClass::Enum ); } else{ pClass->SetClassType( CClass::Class ); } } else if( source[nowLine+1] == ESC_INTERFACE ){ pClass->SetClassType( CClass::Interface ); } else{ pClass->SetClassType( CClass::Structure ); } } // Blittable型の場合 if( !blittableType.IsNull() ){ pClass->SetBlittableType( blittableType ); // Blittable型として登録 compiler.GetObjectModule().meta.GetBlittableTypes().push_back( BlittableType( blittableType, pClass ) ); } } } } void Classes::GenerateVTables() { Iterator_Reset(); while( Iterator_HasNext() ) { CClass *pClass = Iterator_GetNext(); pClass->GenerateVTables(); } } void Classes::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){ Iterator_Reset(); while( Iterator_HasNext() ) { CClass *pClass = Iterator_GetNext(); pClass->ActionVtblSchedule(ImageBase,MemPos_CodeSection); } } void Classes::InitStaticMember(){ //静的メンバをグローバル領域に作成 //イテレータをリセット extern int cp; int back_cp=cp; this->Iterator_Reset(); while(this->Iterator_HasNext()){ CClass &objClass = *this->Iterator_GetNext(); if( objClass.isTargetObjectModule == false ) { // 静的リンクライブラリの場合は飛ばす(既にインスタンスが定義済みであるため) continue; } // 名前空間をセット compiler.GetNamespaceSupporter().GetLivingNamespaceScopes() = objClass.GetNamespaceScopes(); int i=0; BOOST_FOREACH( CMember *member, objClass.GetStaticMembers() ){ char temporary[VN_SIZE]; sprintf(temporary,"%s.%s",objClass.GetName().c_str(),member->GetName().c_str()); dim( temporary, member->GetSubscripts(), member->GetType(), member->GetInitializeExpression().c_str(), member->GetConstructParameter().c_str(), 0); i++; } } compiler.GetNamespaceSupporter().GetLivingNamespaceScopes().clear(); cp=back_cp; } bool Classes::MemberVar_LoopRefCheck(const CClass &objClass){ bool result = true; BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){ if(pMember->GetType().IsStruct()){ //循環参照でないかをチェック if(pobj_LoopRefCheck->check(pMember->GetType().GetClass())){ extern int cp; SetError(124,pMember->GetType().GetClass().GetName(),cp); return false; } pobj_LoopRefCheck->add(objClass.GetName().c_str()); bool tempResult = MemberVar_LoopRefCheck(pMember->GetType().GetClass()); if( result ) { result = tempResult; } pobj_LoopRefCheck->del(objClass.GetName().c_str()); } } return result; } void Classes::GetClass_recur(const char *lpszInheritsClass){ extern char *basbuf; int i,i2,i3,sub_address,top_pos; char temporary[8192]; // 名前空間管理 NamespaceScopes backupNamespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes(); NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes(); namespaceScopes.clear(); // Importsされた名前空間の管理 NamespaceScopesCollection backupImportedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces(); compiler.GetNamespaceSupporter().GetImportedNamespaces().clear(); // 呼び出し元でコンパイル中のクラスポインタをバックアップ const CClass *pBackCompilingClass = compiler.pCompilingClass; for(i=0;;i++){ if(basbuf[i]=='\0') break; // 名前空間 if( basbuf[i] == 1 && basbuf[i+1] == ESC_NAMESPACE ){ for(i+=2,i2=0;;i2++,i++){ if( IsCommandDelimitation( basbuf[i] ) ){ temporary[i2]=0; break; } temporary[i2]=basbuf[i]; } namespaceScopes.push_back( temporary ); continue; } else if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENDNAMESPACE ){ if( namespaceScopes.size() <= 0 ){ SetError(12, "End Namespace", i ); } else{ namespaceScopes.pop_back(); } i += 2; continue; } else if( basbuf[i] == 1 && basbuf[i+1] == ESC_IMPORTS ){ for(i+=2,i2=0;;i2++,i++){ if( IsCommandDelimitation( basbuf[i] ) ){ temporary[i2]=0; break; } temporary[i2]=basbuf[i]; } if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) ) { SmoothieException::Throw(64,temporary,i ); } continue; } else if( basbuf[i] == 1 && basbuf[i+1] == ESC_CLEARNAMESPACEIMPORTED ){ compiler.GetNamespaceSupporter().GetImportedNamespaces().clear(); continue; } if(basbuf[i]==1&&basbuf[i+1]==ESC_INTERFACE){ ////////////////////////// // インターフェイス ////////////////////////// top_pos=i; i+=2; //インターフェイス名を取得 GetIdentifierToken( temporary, basbuf, i ); CClass *pobj_c = const_cast( this->Find(namespaceScopes, temporary) ); if(!pobj_c) continue; if(lpszInheritsClass){ if(lstrcmp(lpszInheritsClass,pobj_c->GetName().c_str())!=0){ //継承先先読み用 continue; } } if(pobj_c->IsReady()){ //既に先読みされているとき continue; } pobj_c->Readed(); pobj_c->SetConstructorMemberSubIndex( -1 ); pobj_c->SetDestructorMemberSubIndex( -1 ); if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS){ //継承を行う場合 for(i+=3,i2=0;;i++,i2++){ if(IsCommandDelimitation(basbuf[i])){ temporary[i2]=0; break; } temporary[i2]=basbuf[i]; } if(lstrcmpi(temporary,pobj_c->GetName().c_str())==0){ SetError(105,temporary,i); goto Interface_InheritsError; } //継承元クラスを取得 const Classes &classes = *this; const CClass *pInheritsClass = classes.Find(temporary); if( !pInheritsClass ){ SetError(106,temporary,i); goto Interface_InheritsError; } //継承させる if( !pobj_c->InheritsClass( *pInheritsClass, Types(), i ) ){ goto Interface_InheritsError; } } else{ //継承無し if( &pobj_c->GetSuperClass() || pobj_c->GetVtblNum() ) { // TODO: ここに来ないことが実証できたらこの分岐は消す Jenga::Throw( "GetClass_recur内の例外" ); } } Interface_InheritsError: //メンバ変数、関数を取得 while(1){ i++; //エラー if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE||basbuf[i+1]==ESC_INTERFACE)){ SetError(22,"Interface",i); i--; break; } if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){ SetError(111,NULL,i); break; } sub_address=i; for(i2=0;;i++,i2++){ if(IsCommandDelimitation(basbuf[i])){ temporary[i2]=0; break; } temporary[i2]=basbuf[i]; } if(temporary[0]=='\0'){ if(basbuf[i]=='\0'){ i--; SetError(22,"Interface",top_pos); break; } continue; } //End Interface記述の場合 if(temporary[0]==1&&temporary[1]==ESC_ENDINTERFACE) break; if(!(temporary[0]==1&&( temporary[1]==ESC_SUB||temporary[1]==ESC_FUNCTION ))){ SetError(1,NULL,i); break; } //メンバ関数を追加 pobj_c->AddMethod(pobj_c, Prototype::Public, //Publicアクセス権 0, //Static指定なし false, //Constではない 1, //Abstract 1, //Virtual 0, temporary, sub_address ); } } if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){ ////////////////////////// // クラス ////////////////////////// top_pos=i; const DWORD dwClassType=basbuf[i+1]; i+=2; int iAlign=0; if(memicmp(basbuf+i,"Align(",6)==0){ //アラインメント修飾子 i+=6; i+=GetStringInPare_RemovePare(temporary,basbuf+i)+1; iAlign=atoi(temporary); if(!(iAlign==1||iAlign==2||iAlign==4||iAlign==8||iAlign==16)) SetError(51,NULL,i); } else if( memicmp( basbuf + i, "Blittable(", 10 ) == 0 ){ // Blittable修飾子 i+=10; i=JumpStringInPare(basbuf,i)+1; } if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENUM ){ // 列挙型の場合 i+=2; } //クラス名を取得 GetCommandToken( temporary, basbuf, i ); char className[VN_SIZE]; Jenga::Common::Strings typeParameters; SplitGenericClassInstance( temporary, className, typeParameters ); CClass *pobj_c = const_cast( this->Find(namespaceScopes, className) ); if(!pobj_c) continue; compiler.pCompilingClass = pobj_c; if(lpszInheritsClass){ if( pobj_c->GetName() != lpszInheritsClass ){ //継承先先読み用 continue; } } if(pobj_c->IsReady()){ //既に先読みされているとき continue; } ///////////////////////////////////////////////////////// // ☆★☆ ジェネリクスサポート ☆★☆ BOOST_FOREACH( const std::string &typeParameter, typeParameters ) { pobj_c->AddFormalGenericType( GenericType( typeParameter, Type(DEF_OBJECT,*GetObjectClassPtr()) ) ); } ///////////////////////////////////////////////////////// pobj_c->SetFixedAlignment( iAlign ); pobj_c->Readed(); pobj_c->SetConstructorMemberSubIndex( -1 ); pobj_c->SetDestructorMemberSubIndex( -1 ); //アクセス制限の初期値をセット Prototype::Accessibility accessibility; if(dwClassType==ESC_CLASS){ accessibility = Prototype::Private; } else{ accessibility = Prototype::Public; } if( pobj_c->GetName() == "Object" || dwClassType == ESC_TYPE ){ if( &pobj_c->GetSuperClass() || pobj_c->GetVtblNum() ) { // TODO: ここに来ないことが実証できたらこの分岐は消す Jenga::Throw( "GetClass_recur内の例外" ); } } else{ bool isInherits = false; if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS){ //継承を行う場合 isInherits = true; i += 3; GetCommandToken( temporary, basbuf, i ); if(lstrcmpi(temporary,pobj_c->GetName().c_str())==0){ SetError(105,temporary,i); goto InheritsError; } } if( !isInherits ){ //Objectを継承する lstrcpy( temporary, "Object" ); } pobj_c->Inherits( temporary, i ); } InheritsError: //メンバとメソッドを取得 while(1){ i++; //エラー if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){ SetError(22,"Class",i); i--; break; } if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){ SetError(111,NULL,i); break; } //Static修飾子 BOOL bStatic; if(basbuf[i]==1&&basbuf[i+1]==ESC_STATIC){ bStatic=1; i+=2; } else bStatic=0; //Const修飾子 bool isConst = false; if( basbuf[i] == 1 && basbuf[i + 1] == ESC_CONST ){ isConst = true; i += 2; } if(basbuf[i]==1&&( basbuf[i+1]==ESC_ABSTRACT||basbuf[i+1]==ESC_VIRTUAL||basbuf[i+1]==ESC_OVERRIDE|| basbuf[i+1]==ESC_SUB||basbuf[i+1]==ESC_FUNCTION )){ i3=basbuf[i+1]; sub_address=i; } else i3=0; bool isVirtual = false, isAbstract = false, isOverride = false; if(i3==ESC_ABSTRACT){ isAbstract=1; isVirtual=1; i+=2; i3=basbuf[i+1]; } else if(i3==ESC_VIRTUAL){ isAbstract=0; isVirtual=1; i+=2; i3=basbuf[i+1]; } else if(i3==ESC_OVERRIDE){ isOverride=1; isVirtual=1; i+=2; i3=basbuf[i+1]; } for(i2=0;;i++,i2++){ if(IsCommandDelimitation(basbuf[i])){ temporary[i2]=0; break; } temporary[i2]=basbuf[i]; } if(temporary[0]=='\0'){ if(basbuf[i]=='\0'){ if(dwClassType==ESC_CLASS) SetError(22,"Class",top_pos); else SetError(22,"Type",top_pos); i--; break; } continue; } //End Class記述の場合 if(temporary[0]==1&&temporary[1]==ESC_ENDCLASS&&dwClassType==ESC_CLASS) break; if(temporary[0]==1&&temporary[1]==ESC_ENDTYPE&&dwClassType==ESC_TYPE) break; //アクセスを変更 if(lstrcmpi(temporary,"Private")==0){ accessibility = Prototype::Private; continue; } if(lstrcmpi(temporary,"Public")==0){ accessibility = Prototype::Public; continue; } if(lstrcmpi(temporary,"Protected")==0){ accessibility = Prototype::Protected; continue; } extern int cp; if(i3==0){ if(bStatic){ //静的メンバを追加 cp=i; //エラー用 pobj_c->AddStaticMember( accessibility, isConst, false, temporary, i); } else{ //メンバを追加 cp=i; //エラー用 pobj_c->AddMember( accessibility, isConst, false, temporary, i ); if(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().IsStruct()){ if( !pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().GetClass().IsReady() ){ //参照先が読み取られていないとき GetClass_recur(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().GetClass().GetName().c_str()); } } if(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().IsStruct()){ //循環参照のチェック pobj_LoopRefCheck->add(pobj_c->GetName().c_str()); if(!MemberVar_LoopRefCheck(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().GetClass())){ //エラー回避 Type &type = const_cast(pobj_c->GetDynamicMembers().back()->GetType()); type.SetBasicType( DEF_PTR_VOID ); } pobj_LoopRefCheck->del(pobj_c->GetName().c_str()); } } } else{ //メソッドを追加 cp=i; //エラー用 pobj_c->AddMethod(pobj_c, accessibility, bStatic, isConst, isAbstract, isVirtual, isOverride, temporary, sub_address); if( isAbstract ) continue; for(;;i++){ if(basbuf[i]=='\0'){ i--; break; } if(basbuf[i-1]!='*'&& basbuf[i]==1&&( basbuf[i+1]==ESC_SUB|| basbuf[i+1]==ESC_FUNCTION|| basbuf[i+1]==ESC_MACRO|| basbuf[i+1]==ESC_TYPE|| basbuf[i+1]==ESC_CLASS|| basbuf[i+1]==ESC_INTERFACE|| basbuf[i+1]==ESC_ENUM)){ GetDefaultNameFromES(i3,temporary); SetError(22,temporary,i); } if(basbuf[i]==1&&basbuf[i+1]==GetEndXXXCommand((char)i3)){ i+=2; break; } } } } } } // 呼び出し元でコンパイル中のクラスポインタを元に戻す compiler.pCompilingClass = pBackCompilingClass; // 名前空間を元に戻す compiler.GetNamespaceSupporter().GetLivingNamespaceScopes() = backupNamespaceScopes; // インポートされた名前空間を元に戻す compiler.GetNamespaceSupporter().GetImportedNamespaces() = backupImportedNamespaces; } void Classes::GetAllClassInfo(void){ //ループ継承チェック用のクラス pobj_LoopRefCheck=new CLoopRefCheck(); //クラスを取得 GetClass_recur(0); delete pobj_LoopRefCheck; pobj_LoopRefCheck=0; // イテレータの準備 this->Iterator_Init(); } void Classes::Compile_System_InitializeUserTypes(){ char temporary[VN_SIZE]; //////////////////////////////////////////////////////////////////// // クラス登録 //////////////////////////////////////////////////////////////////// // イテレータをリセット Iterator_Reset(); while( Iterator_HasNext() ){ const CClass &objClass = *Iterator_GetNext(); if( !objClass.IsUsing() ){ // 未使用のクラスは無視する continue; } char referenceOffsetsBuffer[1024] = ""; int numOfReference = 0; BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){ if( pMember->GetType().IsObject() || pMember->GetType().IsPointer() ){ if( referenceOffsetsBuffer[0] ){ lstrcat( referenceOffsetsBuffer, "," ); } sprintf( referenceOffsetsBuffer + lstrlen( referenceOffsetsBuffer ), "%d", objClass.GetMemberOffset( pMember->GetName().c_str() ) ); numOfReference++; } } sprintf( temporary , "Add(%c%c_System_TypeForClass(\"%s\",\"%s\",[%s],%d))" , 1 , ESC_NEW , "" // 名前空間 (TODO: 実装) , objClass.GetName().c_str() // クラス名 , referenceOffsetsBuffer // 参照メンバオフセット配列 , numOfReference // 参照メンバの個数 ); // コンパイル ChangeOpcode( temporary ); } //////////////////////////////////////////////////////////////////// // 基底クラスを登録 //////////////////////////////////////////////////////////////////// sprintf(temporary, "%c%ctempType=Nothing%c%cTypeBaseImpl" , HIBYTE( COM_DIM ) , LOBYTE( COM_DIM ) , 1 , ESC_AS ); ChangeOpcode( temporary ); // イテレータをリセット Iterator_Reset(); while( Iterator_HasNext() ){ const CClass &objClass = *Iterator_GetNext(); if( !objClass.IsUsing() ){ // 未使用のクラスは無視する continue; } if( objClass.HasSuperClass() ){ sprintf( temporary , "tempType=Search(\"%s\",\"%s\")" , "" // 名前空間 (TODO: 実装) , objClass.GetName().c_str() // クラス名 ); // コンパイル ChangeOpcode( temporary ); sprintf( temporary , "tempType.SetBaseType(Search(\"%s\",\"%s\"))" , "" // 名前空間 (TODO: 実装) , objClass.GetSuperClass().GetName().c_str() // 基底クラス名 ); // コンパイル ChangeOpcode( temporary ); } } //////////////////////////////////////////////////////////////////// // 継承関係登録 //////////////////////////////////////////////////////////////////// // TODO: 未完成 /* // イテレータをリセット Iterator_Reset(); while( Iterator_HasNext() ){ CClass *pClass = Iterator_GetNext(); sprintf( genBuffer + length , "obj.Search( \"%s\" ).SetBaseType( Search( \"%s\" ) ):" , "" // クラス名 , pClass->name // クラス名 ); length += lstrlen( genBuffer + length ); while( length + 8192 > max ){ max += 8192; genBuffer = (char *)realloc( genBuffer, max ); } }*/ } const CClass *Classes::Find( const NamespaceScopes &namespaceScopes, const string &name ) const { if( namespaceScopes.size() == 0 && name == "Object" ){ return GetObjectClassPtr(); } else if( namespaceScopes.size() == 0 && name == "String" ){ return GetStringClassPtr(); } const CClass *pClass = GetHashArrayElement( name.c_str() ); while( pClass ) { if( pClass->IsEqualSymbol( namespaceScopes, name ) ){ //名前空間とクラス名が一致した return pClass; } pClass = pClass->GetChainNext(); } // TypeDefも見る int index = compiler.GetObjectModule().meta.GetTypeDefs().GetIndex( namespaceScopes, name ); if( index != -1 ){ Type type = compiler.GetObjectModule().meta.GetTypeDefs()[index].GetBaseType(); if( type.IsObject() ){ return &type.GetClass(); } } return NULL; } const CClass *Classes::Find( const string &fullName ) const { char AreaName[VN_SIZE] = ""; //オブジェクト変数 char NestName[VN_SIZE] = ""; //入れ子メンバ bool isNest = SplitMemberName( fullName.c_str(), AreaName, NestName ); return Find( NamespaceScopes( AreaName ), NestName ); } void Classes::StartCompile( const UserProc *pUserProc ){ const CClass *pParentClass = pUserProc->GetParentClassPtr(); if( pParentClass ){ pParentClass->Using(); // 仮想関数になるメソッドに使用チェックをつける BOOST_FOREACH( const CMethod *pMethod, pParentClass->GetMethods() ) { if( pMethod->IsVirtual() ) { pMethod->GetUserProc().Using(); } } pCompilingMethod = pParentClass->GetMethods().GetMethodPtr( pUserProc ); if( !pCompilingMethod ){ pCompilingMethod = pParentClass->GetStaticMethods().GetMethodPtr( pUserProc ); if( !pCompilingMethod ){ SmoothieException::Throw(300); } } } else{ pCompilingMethod = NULL; } } const CClass *Classes::GetStringClassPtr() const { if( !pStringClass ){ // キャッシュしておく pStringClass = this->Find( NamespaceScopes( "System" ), "String" ); if( !pStringClass ) { SmoothieException::Throw(); } return pStringClass; } return pStringClass; } const CClass *Classes::GetObjectClassPtr() const { if( !pObjectClass ){ // キャッシュしておく pObjectClass = this->Find( NamespaceScopes( "System" ), "Object" ); if( !pObjectClass ) { SmoothieException::Throw(); } return pObjectClass; } return pObjectClass; }