#include "common.h" #ifdef _AMD64_ #include "../BasicCompiler64/opcode.h" #else #include "../BasicCompiler32/opcode.h" #endif CDBClass *pobj_DBClass; const CClass *pobj_CompilingClass; CMember *pCompilingMethod; CMember::CMember( CClass *pobj_c, DWORD access, bool isConst, bool isRef, char *buffer, int nowLine ){ extern int cp; if( strstr(buffer,"environVarName")){ int test=0; } //構文を解析 char VarName[VN_SIZE]; char init_buf[VN_SIZE]; char constract_parameter[VN_SIZE]; GetDimentionFormat(buffer,VarName,SubScripts,*this,init_buf,constract_parameter); //重複チェック if(pobj_c->DupliCheckAll(VarName)){ SetError(15,VarName,cp); } //メンバ名 name=(char *)HeapAlloc(hHeap,0,lstrlen(VarName)+1); lstrcpy(name,VarName); //アクセス権 dwAccess=access; //定数扱いかどうか this->isConst = isConst; //初期データ InitBuf=(char *)HeapAlloc(hHeap,0,lstrlen(init_buf)+1); lstrcpy(InitBuf,init_buf); //コンストラクタ用のパラメータ ConstractParameter=(char *)HeapAlloc(hHeap,0,lstrlen(constract_parameter)+1); lstrcpy(ConstractParameter,constract_parameter); //ソースコードの位置 source_code_address=nowLine; } CMember::CMember(CMember &member): Type( member ) { //name name=(char *)HeapAlloc(hHeap,0,lstrlen(member.name)+1); lstrcpy(name,member.name); //定数扱いかどうか isConst = member.isConst; //SubScripts memcpy(SubScripts,member.SubScripts,MAX_ARRAYDIM*sizeof(int)); //ソースコードの位置 source_code_address=member.source_code_address; } CMember::CMember(){ memset(this,0,sizeof(CMember)); } CMember::~CMember(){ HeapDefaultFree(name); if(InitBuf) HeapDefaultFree(InitBuf); if(ConstractParameter) HeapDefaultFree(ConstractParameter); } bool CMember::IsConst(){ return isConst; } void CMember::InitStaticMember(void){ //静的メンバをグローバル領域に作成 //イテレータをリセット extern CDBClass *pobj_DBClass; pobj_DBClass->Iterator_Reset(); int back_cp=cp; while(pobj_DBClass->Iterator_HasNext()){ CClass &objClass = *pobj_DBClass->Iterator_GetNext(); // 名前空間をセット Smoothie::Lexical::liveingNamespaceScopes = objClass.GetNamespaceScopes(); int i=0; foreach( CMember *member, objClass.staticMembers ){ char temporary[VN_SIZE]; sprintf(temporary,"%s.%s",objClass.name,member->name); dim( temporary, member->SubScripts, *member, member->InitBuf, member->ConstractParameter, 0); //ネイティブコードバッファの再確保 ReallocNativeCodeBuffer(); i++; } } Smoothie::Lexical::liveingNamespaceScopes.clear(); cp=back_cp; } //コピーコンストラクタ CMethod::CMethod(CMethod *pMethod) : pUserProc( pMethod->pUserProc ) , dwAccess( pMethod->dwAccess ) , bAbstract( pMethod->bAbstract ) , bVirtual( pMethod->bVirtual ) , isConst( pMethod->isConst ) , isStatic( pMethod->isStatic ) { } CMethod::CMethod( UserProc *pUserProc, DWORD dwAccess, BOOL bAbstract, BOOL bVirtual, bool isConst, bool isStatic ) : pUserProc( pUserProc ) , dwAccess( dwAccess ) , bAbstract( bAbstract ) , bVirtual( bVirtual ) , isConst( isConst ) , isStatic( isStatic ) , pobj_InheritsClass( NULL ) { } CMethod::~CMethod(){ } CClass::CClass( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name ) : namespaceScopes( namespaceScopes ) , importedNamespaces( importedNamespaces ) , ConstructorMemberSubIndex( 0 ) , DestructorMemberSubIndex( 0 ) , classType( Class ) , isUsing( false ) , pobj_InheritsClass( NULL ) , ppobj_Member( NULL ) , iMemberNum( 0 ) , vtbl_num( 0 ) , iAlign( 0 ) , vtbl_offset( -1 ) , isCompilingConstructor( false ) , isCompilingDestructor( false ) , pobj_NextClass( NULL ) { this->name=(char *)HeapAlloc(hHeap,0,lstrlen(name)+1); lstrcpy(this->name,name); } CClass::~CClass(){ int i; //クラス名 HeapDefaultFree(name); if(ppobj_Member){ //メンバ for(i=0;icheck(inheritsClass)){ SetError(123,inheritsClass.name,nowLine); return false; } if( inheritsClass.ppobj_Member == 0 ){ //継承先が読み取られていないとき pobj_LoopRefCheck->add(this->name); pobj_DBClass->GetClass_recur(inheritsClass.name); pobj_LoopRefCheck->del(this->name); } //メンバをコピー ppobj_Member=(CMember **)HeapReAlloc( hHeap, 0, ppobj_Member, ( iMemberNum + inheritsClass.iMemberNum )*sizeof(CMember *)); for(int i3=0;i3dwAccess==ACCESS_PRIVATE) ppobj_Member[iMemberNum]->dwAccess=ACCESS_NON; else ppobj_Member[iMemberNum]->dwAccess=inheritsClass.ppobj_Member[i3]->dwAccess; iMemberNum++; } //メソッドをコピー foreach( CMethod *baseMethod, inheritsClass.methods ){ CMethod *method = new CMethod( baseMethod ); //dwAccess if(baseMethod->dwAccess==ACCESS_PRIVATE) method->dwAccess=ACCESS_NON; else method->dwAccess=baseMethod->dwAccess; //pobj_Inherits // ※継承元のClassIndexをセット(入れ子継承を考慮する) if(baseMethod->pobj_InheritsClass==0) method->pobj_InheritsClass=&inheritsClass; else method->pobj_InheritsClass= baseMethod->pobj_InheritsClass; methods.push_back( method ); } //仮想関数の数 vtbl_num += inheritsClass.vtbl_num; //継承先のクラスをメンバとして保持する pobj_InheritsClass = &inheritsClass; return true; } bool CClass::InheritsInterface( const CClass &inheritsInterface, int nowLine ){ //ループ継承でないかをチェック if(pobj_LoopRefCheck->check(inheritsInterface)){ SetError(123,inheritsInterface.name,nowLine); return false; } if( inheritsInterface.ppobj_Member == 0 ){ //継承先が読み取られていないとき pobj_LoopRefCheck->add(this->name); pobj_DBClass->GetClass_recur(inheritsInterface.name); pobj_LoopRefCheck->del(this->name); } //メソッドをコピー foreach( CMethod *baseMethod, inheritsInterface.methods ){ CMethod *method = new CMethod( baseMethod ); //dwAccess if(baseMethod->dwAccess==ACCESS_PRIVATE) method->dwAccess=ACCESS_NON; else method->dwAccess=baseMethod->dwAccess; //pobj_Inherits // ※継承元のClassIndexをセット(入れ子継承を考慮する) if(baseMethod->pobj_InheritsClass==0) method->pobj_InheritsClass=&inheritsInterface; else method->pobj_InheritsClass= baseMethod->pobj_InheritsClass; methods.push_back( method ); } //仮想関数の数 vtbl_num += inheritsInterface.vtbl_num; /* TODO: インターフェイス向けの機構を作る //継承先のクラスをメンバとして保持する pobj_InheritsClass = &inheritsInterface; */ return true; } void CClass::AddMember( DWORD dwAccess, bool isConst, bool isRef, char *buffer ){ ppobj_Member = (CMember **)HeapReAlloc( hHeap, 0, ppobj_Member, ( iMemberNum + 1 ) * sizeof(CMember *) ); ppobj_Member[iMemberNum] = new CMember( this, dwAccess, isConst, isRef, buffer ); iMemberNum++; } void CClass::AddStaticMember( DWORD dwAccess, bool isConst, bool isRef, char *buffer, int nowLine ){ CMember *member = new CMember( this, dwAccess, isConst, isRef, buffer, nowLine ); staticMembers.push_back( member ); } void CClass::AddMethod( UserProc *pUserProc,DWORD dwAccess, bool isConst, BOOL bAbstract, BOOL bVirtual ){ CMethod *method = new CMethod( pUserProc, dwAccess, bAbstract, bVirtual, isConst, false ); methods.push_back( method ); // プロシージャオブジェクトと関連付け pUserProc->SetMethod( method ); } void CClass::AddStaticMethod(UserProc *pUserProc,DWORD dwAccess){ CMethod *method = new CMethod( pUserProc, dwAccess, FALSE, FALSE, false, true ); staticMethods.push_back( method ); // プロシージャオブジェクトと関連付け pUserProc->SetMethod( method ); } BOOL CClass::DupliCheckAll(const char *name){ //重複チェック //メンバ if(DupliCheckMember(name)) return 1; //メソッド foreach( CMethod *method, methods ){ if( lstrcmp( name, method->pUserProc->GetName().c_str() ) == 0 ){ return 1; } } return 0; } BOOL CClass::DupliCheckMember(const char *name){ //重複チェック //メンバ for( int i=0;iname)==0){ return 1; } } //静的メンバ foreach( CMember *member, staticMembers ){ if( lstrcmp( name, member->name ) == 0 ){ return 1; } } return 0; } CMethod *CClass::GetMethodInfo( UserProc *pUserProc ) const { for( int i=(int)methods.size()-1; i>=0; i-- ){ if( pUserProc == methods[i]->pUserProc ){ return methods[i]; } } return NULL; } CMethod *CClass::GetStaticMethodInfo( UserProc *pUserProc ) const { for( int i=(int)staticMethods.size()-1; i>=0; i-- ){ if( pUserProc == staticMethods[i]->pUserProc ) return staticMethods[i]; } return NULL; } bool CClass::IsExistMethod( const char *name ) const { foreach( CMethod *method, methods ){ if( method->pUserProc->GetName() == name ) return true; } return false; } bool CClass::IsExistStaticMethod( const char *name ) const { foreach( CMethod *method, staticMethods ){ if( method->pUserProc->GetName() == name ) return true; } return false; } void CClass::EnumStaticMethod( const char *methodName, vector &subs ) const { foreach( CMethod *method, staticMethods ){ if( method->pUserProc->GetName() == methodName ){ subs.push_back( method->pUserProc ); } } } void CClass::EnumMethod( const char *methodName, vector &subs ) const { //オブジェクトのメンバ関数の場合 //※オーバーライドされた関数を先にサーチする必要があるため、バックサーチを行う for( int i=(int)methods.size()-1; i>=0; i-- ){ if( methods[i]->pUserProc->GetName() == methodName ){ subs.push_back( methods[i]->pUserProc ); } } } void CClass::EnumMethod( const BYTE idOperatorCalc, vector &subs ) const { //オブジェクトのメンバ関数の場合 //※オーバーライドされた関数を先にサーチする必要があるため、バックサーチを行う for( int i=(int)methods.size()-1; i>=0; i-- ){ UserProc *pUserProc = methods[i]->pUserProc; const char *temp = pUserProc->GetName().c_str(); if(temp[0]==1&&temp[1]==ESC_OPERATOR){ if((BYTE)temp[2]==idOperatorCalc){ subs.push_back( pUserProc ); } } } } //デフォルト コンストラクタ メソッドを取得 CMethod *CClass::GetConstructorMethod() const { if( ConstructorMemberSubIndex == -1 ) return NULL; return methods[ConstructorMemberSubIndex]; } //デストラクタ メソッドを取得 CMethod *CClass::GetDestructorMethod() const { if( DestructorMemberSubIndex == -1 ) return NULL; return methods[DestructorMemberSubIndex]; } //サイズを取得 int CClass::GetSize() const { return GetMemberOffset( NULL, NULL ); } //メンバのオフセットを取得 int CClass::GetMemberOffset( const char *memberName, int *pMemberNum ) const { int i,i2,offset; //仮想関数が存在する場合は関数リストへのポインタのサイズを追加 if(vtbl_num) offset=PTR_SIZE; else offset=0; int alignment; if(iAlign) alignment=iAlign; else alignment=1; int iMaxAlign=0; for(i=0;iGetSize(); //アラインメントを算出 int member_size; if( pMember->IsStruct() ){ //メンバクラスのアラインメントを取得 member_size=pMember->GetClass().GetAlignment(); } else{ //メンバサイズを取得 member_size=i2; } if(iMaxAlignname,memberName)==0){ if(pMemberNum) *pMemberNum=i; return offset; } } //配列を考慮したメンバサイズを取得 member_size=i2 * JumpSubScripts(pMember->SubScripts); //メンバサイズを加算 offset+= member_size; } if(iMaxAlignIsStruct()){ //メンバクラスのアラインメントを取得 member_size=pMember->GetClass().GetAlignment(); } else{ //メンバサイズを取得 member_size = pMember->GetSize(); } //アラインメントをセット if(alignmentpUserProc == pUserProc ) break; if( method->bVirtual ) n++; } return n; } LONG_PTR CClass::GetVtblGlobalOffset(void) const { //既に存在する場合はそれを返す if(vtbl_offset!=-1) return vtbl_offset; ////////////////////////////////////// // 存在しないときは新たに生成する ////////////////////////////////////// UserProc **ppsi; ppsi=(UserProc **)HeapAlloc(hHeap,0,vtbl_num*sizeof(GlobalProc *)); //関数テーブルに値をセット int i2 = 0; foreach( CMethod *method, methods ){ if(method->bVirtual){ method->pUserProc->Using(); if(method->bAbstract){ extern int cp; SetError(300,NULL,cp); ppsi[i2]=0; } else{ ppsi[i2]=method->pUserProc; } i2++; } } vtbl_offset=dataTable.AddBinary((void *)ppsi,vtbl_num*sizeof(LONG_PTR)); for( int i=0; i < vtbl_num; i++ ){ pobj_Reloc->AddSchedule_DataSection(vtbl_offset+i*sizeof(LONG_PTR)); } HeapDefaultFree(ppsi); return vtbl_offset; } void CClass::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){ if(vtbl_offset==-1) return; LONG_PTR *pVtbl; pVtbl=(LONG_PTR *)((char *)dataTable.GetPtr()+vtbl_offset); int i; for(i=0;ibeginOpAddress+ImageBase+MemPos_CodeSection; } } bool CClass::IsAbstract() const { // 未実装(abstract)の仮想関数を持つ場合はtrueを返す foreach( CMethod *method, methods ){ if(method->bVirtual){ if(method->bAbstract){ return true; } } } return false; } // コンストラクタのコンパイルを開始 void CClass::NotifyStartConstructorCompile() const { isCompilingConstructor = true; } //コンストラクタのコンパイルを終了 void CClass::NotifyFinishConstructorCompile() const { isCompilingConstructor = false; } //コンストラクタをコンパイル中かどうかを判別 bool CClass::IsCompilingConstructor() const { return isCompilingConstructor; } //デストラクタのコンパイルを開始 void CClass::NotifyStartDestructorCompile() const{ isCompilingDestructor = true; } //デストラクタのコンパイルを終了 void CClass::NotifyFinishDestructorCompile() const{ isCompilingDestructor = false; } //デストラクタをコンパイル中かどうかを判別 bool CClass::IsCompilingDestructor() const { return isCompilingDestructor; } //自身と等しいクラスかどうかを確認 bool CClass::IsEquals( const CClass *pClass ) const { if( this == pClass ) return true; return false; } //自身の派生クラスかどうかを確認 bool CClass::IsSubClass( const CClass *pClass ) const { pClass = pClass->pobj_InheritsClass; while( pClass ){ if( this == pClass ) return true; pClass = pClass->pobj_InheritsClass; } 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; } int CDBClass::hash(const char *name) const{ int key; for(key=0;*name!='\0';name++){ key=((key<<8)+ *name )%MAX_CLASS_HASH; } return key; } void CDBClass::DestroyClass(CClass *pobj_c){ if(pobj_c->pobj_NextClass){ DestroyClass(pobj_c->pobj_NextClass); } delete pobj_c; } CDBClass::CDBClass(): pStringClass( NULL ), pObjectClass( NULL ), pCompilingClass( NULL ), pCompilingMethod( NULL ), ppobj_IteClass( NULL ), iIteMaxNum( 0 ), iIteNextNum( 0 ) { memset( pobj_ClassHash, 0, MAX_CLASS_HASH * sizeof(CClass *) ); } CDBClass::~CDBClass(){ int i; for(i=0;iActionVtblSchedule(ImageBase,MemPos_CodeSection); if(pobj_c->pobj_NextClass==0) break; pobj_c=pobj_c->pobj_NextClass; } } } } const CClass *CDBClass::Find( const NamespaceScopes &namespaceScopes, const string &name ) const { int key; key=hash(name.c_str()); if( namespaceScopes.size() == 0 && name == "Object" ){ return GetObjectClassPtr(); } else if( namespaceScopes.size() == 0 && name == "String" ){ return GetStringClassPtr(); } if(pobj_ClassHash[key]){ CClass *pobj_c; pobj_c=pobj_ClassHash[key]; while(1){ if( pobj_c->IsEqualSymbol( namespaceScopes, name ) ){ //名前空間とクラス名が一致した return pobj_c; } if(pobj_c->pobj_NextClass==0) break; pobj_c=pobj_c->pobj_NextClass; } } // TypeDefも見る int index = Smoothie::Meta::typeDefs.GetIndex( namespaceScopes, name ); if( index != -1 ){ Type type = Smoothie::Meta::typeDefs[index].GetBaseType(); if( type.IsObject() ){ return &type.GetClass(); } } return NULL; } const CClass *CDBClass::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 ); } CClass *CDBClass::AddClass( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name,int nowLine){ ////////////////////////////////////////////////////////////////////////// // クラスを追加 // ※名前のみを登録。その他の情報はSetClassメソッドで! ////////////////////////////////////////////////////////////////////////// CClass *pobj_c; pobj_c=new CClass(namespaceScopes, importedNamespaces, name); if(lstrcmp(name,"String")==0){ //Stringクラス pStringClass=pobj_c; } if( lstrcmp( name, "Object" ) == 0 ){ pObjectClass = pobj_c; } ///////////////////////////////// // ハッシュデータに追加 ///////////////////////////////// int key; key=hash(name); if(pobj_ClassHash[key]){ CClass *pobj_c2; pobj_c2=pobj_ClassHash[key]; while(1){ if( pobj_c2->IsEqualSymbol( namespaceScopes, name ) ){ //名前空間及びクラス名が重複した場合 SetError(15,name,nowLine); return 0; } if(pobj_c2->pobj_NextClass==0) break; pobj_c2=pobj_c2->pobj_NextClass; } pobj_c2->pobj_NextClass=pobj_c; } else{ pobj_ClassHash[key]=pobj_c; } return pobj_c; } void CDBClass::InitNames(void){ extern char *basbuf; int i, i2; char temporary[VN_SIZE]; // Blittable型管理オブジェクトを初期化 Smoothie::Meta::blittableTypes.clear(); // 名前空間管理 NamespaceScopes &namespaceScopes = Smoothie::Lexical::liveingNamespaceScopes; namespaceScopes.clear(); // Importsされた名前空間の管理 NamespaceScopesCollection &importedNamespaces = Smoothie::Meta::importedNamespaces; importedNamespaces.clear(); 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]; } importedNamespaces.Imports( temporary ); continue; } else if( basbuf[i] == 1 && basbuf[i+1] == ESC_CLEARNAMESPACEIMPORTED ){ importedNamespaces.clear(); continue; } if(basbuf[i]==1&&( basbuf[i+1]==ESC_CLASS|| basbuf[i+1]==ESC_TYPE|| basbuf[i+1]==ESC_INTERFACE )){ int nowLine; nowLine=i; i+=2; Type blittableType; if(memicmp(basbuf+i,"Align(",6)==0){ //アラインメント修飾子 i+=6; i=JumpStringInPare(basbuf,i)+1; } else if( memicmp( basbuf + i, "Blittable(", 10 ) == 0 ){ // Blittable修飾子 i+=10; i+=GetStringInPare_RemovePare(temporary,basbuf+i)+1; Type::StringToType( temporary, blittableType ); } bool isEnum = false; if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENUM ){ // 列挙型の場合 isEnum = true; i+=2; } int i2; char temporary[VN_SIZE]; for(i2=0;;i++,i2++){ if(!IsVariableChar(basbuf[i])){ temporary[i2]=0; break; } temporary[i2]=basbuf[i]; } //クラスを追加 CClass *pClass = pobj_DBClass->AddClass(namespaceScopes, importedNamespaces, temporary,nowLine); if( pClass ){ if( basbuf[nowLine+1] == ESC_CLASS ){ if( isEnum ){ pClass->classType = CClass::Enum; } else{ pClass->classType = CClass::Class; } } else if( basbuf[nowLine+1] == ESC_INTERFACE ){ pClass->classType = CClass::Interface; } else{ pClass->classType = CClass::Structure; } } // Blittable型の場合 if( !blittableType.IsNull() ){ pClass->SetBlittableType( blittableType ); // Blittable型として登録 Smoothie::Meta::blittableTypes.push_back( BlittableType( blittableType, pClass ) ); } } } } void CDBClass::AddMethod(CClass *pobj_c, DWORD dwAccess, BOOL bStatic, bool isConst, BOOL bAbstract, BOOL bVirtual, BOOL bOverride, 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]; } //関数ハッシュへ登録 GlobalProc *pUserProc; pUserProc=AddSubData( NamespaceScopes(), NamespaceScopesCollection(), buffer,nowLine,bVirtual,pobj_c, (bStatic!=0) ); if(!pUserProc) return; //////////////////////////////////////////////////////////// // コンストラクタ、デストラクタの場合の処理 //////////////////////////////////////////////////////////// BOOL fConstructor=0,bDestructor=0; if(lstrcmp(temporary,pobj_c->name)==0){ //コンストラクタの場合 //標準コンストラクタ(引数なし) if(pUserProc->Params().size()==0) fConstructor=1; //強制的にConst修飾子をつける isConst = true; } else if(temporary[0]=='~'){ //デストラクタの場合はその名前が正しいかチェックを行う if(lstrcmp(temporary+1,pobj_c->name)!=0) SetError(117,NULL,nowLine); else bDestructor=1; } if(fConstructor||bDestructor){ // コンストラクタ、デストラクタのアクセシビリティをチェック //強制的にConst修飾子をつける isConst = true; } if( fConstructor == 1 ) pobj_c->ConstructorMemberSubIndex = (int)pobj_c->methods.size(); else if( bDestructor ) pobj_c->DestructorMemberSubIndex = (int)pobj_c->methods.size(); ////////////////// // 重複チェック ////////////////// if(pobj_c->DupliCheckMember(temporary)){ SetError(15,temporary,nowLine); return; } //メソッド foreach( CMethod *method, pobj_c->methods ){ //基底クラスと重複する場合はオーバーライドを行う if(method->pobj_InheritsClass) continue; if( method->pUserProc->GetName() == temporary ){ if( method->pUserProc->Params().Equals( pUserProc->Params() ) ){ //関数名、パラメータ属性が合致したとき SetError(15,pUserProc->GetName().c_str(),nowLine); return; } } } //仮想関数の場合 if(bAbstract) pUserProc->CompleteCompile(); //メソッドのオーバーライド foreach( CMethod *method, pobj_c->methods ){ if( method->pUserProc->GetName() == temporary ){ if( method->pUserProc->Params().Equals( pUserProc->Params() ) ){ if(method->bVirtual){ //メンバ関数を上書き method->pUserProc=pUserProc; method->bAbstract=0; if(!bOverride){ SetError(127,NULL,nowLine); } if(method->dwAccess!=dwAccess){ SetError(128,NULL,nowLine); } pUserProc->SetMethod( method ); return; } } } } if(bVirtual){ pobj_c->vtbl_num++; } if(bOverride){ SetError(12,"Override",nowLine); } if(bStatic){ pobj_c->AddStaticMethod(pUserProc,dwAccess); } else{ pobj_c->AddMethod(pUserProc, dwAccess, isConst, bAbstract, bVirtual); } } BOOL CDBClass::MemberVar_LoopRefCheck(const CClass &objClass){ int i,i2,bRet=1; for(i=0;iIsStruct()){ //循環参照でないかをチェック if(pobj_LoopRefCheck->check(pMember->GetClass())){ extern int cp; SetError(124,pMember->GetClass().name,cp); return 0; } pobj_LoopRefCheck->add(objClass.name); i2=MemberVar_LoopRefCheck(pMember->GetClass()); if(bRet==1) bRet=i2; pobj_LoopRefCheck->del(objClass.name); } } return bRet; } void CDBClass::GetClass_recur(const char *lpszInheritsClass){ extern char *basbuf; int i,i2,i3,sub_address,top_pos; DWORD dwAccess; char temporary[8192]; // 名前空間管理 NamespaceScopes &namespaceScopes = Smoothie::Lexical::liveingNamespaceScopes; namespaceScopes.clear(); 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; } if(basbuf[i]==1&&basbuf[i+1]==ESC_INTERFACE){ ////////////////////////// // インターフェイス ////////////////////////// top_pos=i; i+=2; //インターフェイス名を取得 GetIdentifierToken( temporary, basbuf, i ); CClass *pobj_c = const_cast( pobj_DBClass->Find(namespaceScopes, temporary) ); if(!pobj_c) continue; if(lpszInheritsClass){ if(lstrcmp(lpszInheritsClass,pobj_c->name)!=0){ //継承先先読み用 continue; } } if(pobj_c->ppobj_Member){ //既に先読みされているとき continue; } //メンバ用メモリを初期化 pobj_c->ppobj_Member=(CMember **)HeapAlloc(hHeap,0,1); pobj_c->iMemberNum=0; pobj_c->ConstructorMemberSubIndex=-1; pobj_c->DestructorMemberSubIndex=-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->name)==0){ SetError(105,temporary,i); goto Interface_InheritsError; } //継承元クラスを取得 const CClass *pInheritsClass = Find(temporary); if( !pInheritsClass ){ SetError(106,temporary,i); goto Interface_InheritsError; } //継承させる if( !pobj_c->InheritsInterface( *pInheritsClass, i ) ){ goto Interface_InheritsError; } } else{ //継承無し pobj_c->pobj_InheritsClass=0; //仮想関数の数を初期化 pobj_c->vtbl_num=0; } 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; } //メンバ関数を追加 AddMethod(pobj_c, ACCESS_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; } //クラス名を取得 GetIdentifierToken( temporary, basbuf, i ); CClass *pobj_c = const_cast( pobj_DBClass->Find(namespaceScopes, temporary) ); if(!pobj_c) continue; if(lpszInheritsClass){ if(lstrcmp(lpszInheritsClass,pobj_c->name)!=0){ //継承先先読み用 continue; } } if(pobj_c->ppobj_Member){ //既に先読みされているとき continue; } pobj_c->iAlign=iAlign; //メンバ用メモリを初期化 pobj_c->ppobj_Member=(CMember **)HeapAlloc(hHeap,0,1); pobj_c->iMemberNum=0; pobj_c->ConstructorMemberSubIndex=-1; pobj_c->DestructorMemberSubIndex=-1; //アクセス制限の初期値をセット if(dwClassType==ESC_CLASS) dwAccess=ACCESS_PRIVATE; else dwAccess=ACCESS_PUBLIC; if( lstrcmp( pobj_c->name, "Object" ) == 0 || dwClassType == ESC_TYPE ){ //継承無し pobj_c->pobj_InheritsClass=0; //仮想関数の数を初期化 pobj_c->vtbl_num=0; } else{ bool isInherits = false; if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS){ //継承を行う場合 isInherits = true; for(i+=3,i2=0;;i++,i2++){ if(IsCommandDelimitation(basbuf[i])){ temporary[i2]=0; break; } temporary[i2]=basbuf[i]; } if(lstrcmpi(temporary,pobj_c->name)==0){ SetError(105,temporary,i); goto InheritsError; } } if( !isInherits ){ //Objectを継承する lstrcpy( temporary, "Object" ); } //継承元クラスを取得 const CClass *pInheritsClass = Find(temporary); if( !pInheritsClass ){ SetError(106,temporary,i); goto InheritsError; } if( pInheritsClass->IsInterface() ){ // クラスを継承していないとき const CClass *pObjectClass = Find("Object"); if( !pObjectClass ){ SetError(106,"Object",i); goto InheritsError; } if( !pobj_c->Inherits( *pObjectClass, i ) ){ goto InheritsError; } } //継承させる if( !pobj_c->Inherits( *pInheritsClass, i ) ){ goto InheritsError; } } 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 bVirtual=0,bAbstract=0,bOverride=0; if(i3==ESC_ABSTRACT){ bAbstract=1; bVirtual=1; i+=2; i3=basbuf[i+1]; } else if(i3==ESC_VIRTUAL){ bAbstract=0; bVirtual=1; i+=2; i3=basbuf[i+1]; } else if(i3==ESC_OVERRIDE){ bOverride=1; bVirtual=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){ dwAccess=ACCESS_PRIVATE; continue; } if(lstrcmpi(temporary,"Public")==0){ dwAccess=ACCESS_PUBLIC; continue; } if(lstrcmpi(temporary,"Protected")==0){ dwAccess=ACCESS_PROTECTED; continue; } extern int cp; if(i3==0){ if(bStatic){ //静的メンバを追加 cp=i; //エラー用 pobj_c->AddStaticMember( dwAccess, isConst, false, temporary, i); } else{ //メンバを追加 cp=i; //エラー用 pobj_c->AddMember( dwAccess, isConst, false, temporary ); if(pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->IsStruct()){ if(pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->GetClass().ppobj_Member==0){ //参照先が読み取られていないとき GetClass_recur(pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->GetClass().name); } } if(pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->IsStruct()){ //循環参照のチェック pobj_LoopRefCheck->add(pobj_c->name); if(!MemberVar_LoopRefCheck(pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->GetClass())){ //エラー回避 pobj_c->ppobj_Member[pobj_c->iMemberNum-1]->SetBasicType( DEF_PTR_VOID ); } pobj_LoopRefCheck->del(pobj_c->name); } } } else{ //メソッドを追加 cp=i; //エラー用 AddMethod(pobj_c, dwAccess, bStatic, isConst, bAbstract, bVirtual, bOverride, temporary, sub_address); if(bAbstract) 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; } } } } } } } void CDBClass::GetAllClassInfo(void){ //ループ継承チェック用のクラス pobj_LoopRefCheck=new CLoopRefCheck(); //クラスを取得 GetClass_recur(0); delete pobj_LoopRefCheck; pobj_LoopRefCheck=0; // イテレータ用のデータを作る pobj_DBClass->Iterator_Init(); } void CDBClass::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; for( int i=0; iname // 基底クラス名 ); // コンパイル ChangeOpcode( temporary ); } // ネイティブコードバッファの再確保 ReallocNativeCodeBuffer(); } //////////////////////////////////////////////////////////////////// // 継承関係登録 //////////////////////////////////////////////////////////////////// // 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 ); } }*/ } CClass *CDBClass::GetStringClassPtr() const { if( !pStringClass ){ SetError(); return NULL; } return pStringClass; } CClass *CDBClass::GetObjectClassPtr() const { if( !pObjectClass ){ SetError(); return NULL; } return pObjectClass; } void CDBClass::StartCompile( UserProc *pUserProc ){ pCompilingClass = pUserProc->GetParentClassPtr(); if( pCompilingClass ){ pCompilingClass->Using(); pCompilingMethod = pCompilingClass->GetMethodInfo( pUserProc ); if( !pCompilingMethod ){ pCompilingMethod = pCompilingClass->GetStaticMethodInfo( pUserProc ); if( !pCompilingMethod ){ SetError(300,NULL,cp); } } } else{ pCompilingMethod = NULL; } } const CClass *CDBClass::GetNowCompilingClass() const { return pCompilingClass; } CMethod *CDBClass::GetNowCompilingMethodInfo(){ return pCompilingMethod; } ////////////////////// // イテレータ ////////////////////// void CDBClass::Iterator_Init(void){ if(ppobj_IteClass) HeapDefaultFree(ppobj_IteClass); iIteMaxNum=0; iIteNextNum=0; ppobj_IteClass=(CClass **)HeapAlloc(hHeap,0,1); int i; for(i=0;ipobj_NextClass==0) break; pobj_c=pobj_c->pobj_NextClass; } } } } void CDBClass::Iterator_Reset(void){ iIteNextNum = 0; } BOOL CDBClass::Iterator_HasNext(void){ if(iIteNextNum