#include "stdafx.h" #include "../common.h" #ifdef _AMD64_ #include "../../compiler_x64/opcode.h" #else #include "../../compiler_x86/opcode.h" #endif using namespace ActiveBasic::Compiler; void LexicalAnalyzer::CollectClassesForNameOnly( const char *source, Classes &classes ) { 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 ){ compiler.errorMessenger.Output(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 ) ) { compiler.errorMessenger.Output(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+i,"Align(",6)==0){ //アラインメント修飾子 i+=6; i=JumpStringInPare(source,i)+1; } else if( memicmp( source + i, "Blittable(", 10 ) == 0 ){ // Blittable修飾子 i+=10; i+=GetStringInPare_RemovePare(temporary,source+i)+1; compiler.StringToType( temporary, blittableType ); } bool isEnum = false; bool isDelegate = false; if( source[i] == 1 && source[i+1] == ESC_ENUM ){ // 列挙型の場合 isEnum = true; i += 2; } else if( source[i] == 1 && source[i+1] == ESC_DELEGATE ) { // デリゲートの場合 isDelegate = true; i += 2; } for(i2=0;;i++,i2++){ if(!IsVariableChar(source[i])){ temporary[i2]=0; break; } temporary[i2]=source[i]; } //クラスを追加 CClass *pClass = new CClass( Symbol( namespaceScopes, temporary ), importedNamespaces ); if( classes.IsExist( pClass ) ) { // 既に存在している compiler.errorMessenger.Output(15,pClass->GetName(), nowLine); delete pClass; continue; } classes.Put( pClass ); if( source[nowLine+1] == ESC_CLASS ) { if( isEnum ) { pClass->SetClassType( CClass::Enum ); } else if( isDelegate ) { pClass->SetClassType( CClass::Delegate ); } 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 ) ); } } } } class CLoopRefCheck{ char **names; int num; void init(){ int i; for(i=0;iGetType().IsStruct()){ //循環参照でないかをチェック if(pobj_LoopRefCheck->check(pMember->GetType().GetClass())){ extern int cp; compiler.errorMessenger.Output(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 OverrideErrorCheck( const DynamicMethod::OverrideResult &result ) { switch( result.enumType ) { case DynamicMethod::OverrideResult::Successful: break; case DynamicMethod::OverrideResult::NotVirtual: compiler.errorMessenger.Output(136, result.pMethod->GetUserProc().GetName(), cp); break; case DynamicMethod::OverrideResult::NotUseOverrideModifier: compiler.errorMessenger.Output(127, result.pMethod->GetUserProc().GetName(), cp); break; case DynamicMethod::OverrideResult::DifferentAccesibility: compiler.errorMessenger.Output(128, result.pMethod->GetUserProc().GetName(), cp); break; default: throw; } } Member *LexicalAnalyzer::CreateMember( const CClass &_class, 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; if( !GetDimentionFormat(buffer,VarName,subscripts,type,initBuffer,lpszConstructParameter) ) { return NULL; } //重複チェック if( _class.DupliCheckAll( VarName ) ){ compiler.errorMessenger.Output(15,VarName,cp); } Member *pMember = new Member( accessibility, VarName, type, isConst, subscripts, initBuffer, lpszConstructParameter ); pMember->source_code_address = nowLine; return pMember; } void LexicalAnalyzer::AddMethod(CClass *pobj_c, UserProc *pUserProc, Prototype::Accessibility accessibility, BOOL bStatic, bool isConst, bool isAbstract, bool isVirtual, bool isOverride, const char *interfaceName, bool isAutoGeneration, int nowLine) { if( isAutoGeneration ) { // コード自動生成 pUserProc->ThisIsAutoGenerationProc(); } //////////////////////////////////////////////////////////// // コンストラクタ、デストラクタの場合の処理 //////////////////////////////////////////////////////////// BOOL fConstructor=0,bDestructor=0; if( pUserProc->GetName() == pobj_c->GetName() ){ //コンストラクタの場合 //標準コンストラクタ(引数なし) if(pUserProc->Params().size()==0) fConstructor=1; //強制的にConst修飾子をつける isConst = true; } else if(pUserProc->GetName()[0]=='~'){ //デストラクタの場合はその名前が正しいかチェックを行う if(lstrcmp(pUserProc->GetName().c_str()+1,pobj_c->GetName().c_str())!=0) compiler.errorMessenger.Output(117,NULL,nowLine); else bDestructor=1; } if(fConstructor||bDestructor){ // コンストラクタ、デストラクタのアクセシビリティをチェック //強制的にConst修飾子をつける isConst = true; } if( fConstructor == 1 ) pobj_c->SetConstructorMemberSubIndex( (int)pobj_c->GetDynamicMethods().size() ); else if( bDestructor ) pobj_c->SetDestructorMemberSubIndex( (int)pobj_c->GetDynamicMethods().size() ); ////////////////// // 重複チェック ////////////////// if(pobj_c->DupliCheckMember( pUserProc->GetName().c_str() )){ compiler.errorMessenger.Output(15,pUserProc->GetName(),nowLine); return; } //メソッド BOOST_FOREACH( const CMethod *pMethod, pobj_c->GetDynamicMethods() ) { //基底クラスと重複する場合はオーバーライドを行う if( pMethod->GetInheritsClassPtr() ) continue; if( pMethod->GetUserProc().IsEqualForOverride( pobj_c->GetSuperClassActualTypeParameters(), pUserProc ) ) { //関数名、パラメータ、戻り値が合致したとき compiler.errorMessenger.Output(15,pUserProc->GetName().c_str(),nowLine); return; } } //仮想関数の場合 if( isAbstract ) pUserProc->CompleteCompile(); // メソッドのオーバーライド DynamicMethod *pMethodForOverride = pobj_c->GetDynamicMethods().FindForOverride( pobj_c->GetSuperClassActualTypeParameters(), pUserProc ); if( pMethodForOverride ) { DynamicMethod::OverrideResult result; result.enumType = pMethodForOverride->Override( pUserProc, accessibility, isOverride ); result.pMethod = pMethodForOverride; OverrideErrorCheck( result ); pUserProc->SetMethod( pMethodForOverride ); return; } else { // インターフェイス メソッドのオーバーライド BOOST_FOREACH( ::Interface *pInterface, pobj_c->GetInterfaces() ) { if( interfaceName[0] ) { if( pInterface->GetClass().GetName() != interfaceName ) { // 指定されたインターフェイス名と整合しないとき continue; } } if( !pInterface->GetClass().IsReady() ){ // インターフェイスが未解析のとき LexicalAnalyzer::LookaheadClass( pInterface->GetClass().GetName().c_str(), compiler.GetObjectModule().meta.GetClasses() ); } DynamicMethod *pMethodForOverride = pInterface->GetDynamicMethods().FindForOverride( pInterface->GetActualTypeParameters(), pUserProc ); if( pMethodForOverride ) { DynamicMethod::OverrideResult result; result.enumType = pMethodForOverride->Override( pUserProc, accessibility, isOverride ); result.pMethod = pMethodForOverride; OverrideErrorCheck( result ); pUserProc->SetMethod( pMethodForOverride ); return; } } } if( interfaceName[0] ) { compiler.errorMessenger.Output(139,interfaceName,nowLine); } if( isVirtual ){ pobj_c->AddVtblNum( 1 ); } if( isOverride ){ compiler.errorMessenger.Output(12,"Override",nowLine); } if(bStatic){ pobj_c->GetStaticMethods().AddStatic( pUserProc, accessibility ); } else{ pobj_c->GetDynamicMethods().Add(pUserProc, accessibility, isConst, isAbstract, isVirtual); } } bool LexicalAnalyzer::Inherits( CClass &_class, 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 ); // 型パラメータ文字列から型データを取得 Types actualTypeParameters; BOOST_FOREACH( const std::string &typeParameterStr, typeParameterStrings ) { Type type; compiler.StringToType( typeParameterStr, type ); actualTypeParameters.push_back( type ); } //継承元クラスを取得 const CClass *pInheritsClass = compiler.GetObjectModule().meta.FindClassSupportedTypeDef( LexicalAnalyzer::FullNameToSymbol( className ) ); if( !pInheritsClass ){ compiler.errorMessenger.Output(106,className,nowLine); return false; } if( pInheritsClass->IsClass() ){ // クラスを継承する isInheritsClass = true; //ループ継承でないかをチェック if( !LexicalAnalyzer::LoopRefCheck(*pInheritsClass) ) { compiler.errorMessenger.Output(123,pInheritsClass->GetName(),nowLine); return false; } if( !pInheritsClass->IsReady() ){ //継承先が読み取られていないとき LexicalAnalyzer::LookaheadClass( pInheritsClass->GetName().c_str(), compiler.GetObjectModule().meta.GetClasses() ); } if( !_class.InheritsClass( *pInheritsClass, actualTypeParameters, nowLine ) ){ return false; } } else{ compiler.errorMessenger.Output(135,pInheritsClass->GetFullName().c_str(),nowLine); return false; } if( inheritNames[i] == '\0' ){ break; } i++; } if( !isInheritsClass ){ const CClass *pObjectClass = compiler.GetObjectModule().meta.GetClasses().GetObjectClassPtr(); //ループ継承でないかをチェック if( !LexicalAnalyzer::LoopRefCheck( *pObjectClass ) ) { compiler.errorMessenger.Output(123,pObjectClass->GetName(),nowLine); return false; } if( !pObjectClass->IsReady() ){ //継承先が読み取られていないとき LexicalAnalyzer::LookaheadClass( pObjectClass->GetName().c_str(), compiler.GetObjectModule().meta.GetClasses() ); } // クラスを一つも継承していないとき if( !_class.InheritsClass( *pObjectClass, Types(), nowLine ) ){ return false; } } return true; } void LexicalAnalyzer::Implements( CClass &_class, Interface *pInterface, std::vector &overrideResults ) { _class.AddInterface( pInterface ); ///////////////////////////////////////////////////////////////// // 基底クラスのメソッドからインターフェイスメソッドを再実装する ///////////////////////////////////////////////////////////////// BOOST_FOREACH( CMethod *pMethod, _class.GetDynamicMethods() ) { DynamicMethod *pMethodForOverride = pInterface->GetDynamicMethods().FindForOverride( pInterface->GetActualTypeParameters(), &pMethod->GetUserProc() ); if( pMethodForOverride ) { DynamicMethod::OverrideResult result; result.enumType = pMethodForOverride->Override( &pMethod->GetUserProc(), pMethod->GetAccessibility(), false ); result.pMethod = pMethod; overrideResults.push_back( result ); // 実装元になるメソッドは呼び出し不可にしておく(オーバーロードの解決から除外する) pMethod->SetNotUseMark( true ); } } ///////////////////////////////////////////////////////////////// // キャストメソッドを追加(内部コードは自動生成すること) // ※COMインターフェイスは除外すること ///////////////////////////////////////////////////////////////// if( pInterface->GetClass().IsInterface() ) { // Function Operator() As ITest char methodName[255] = { 1, ESC_OPERATOR, CALC_AS, '\0' }; //関数ハッシュへ登録 UserProc *pUserProc = new UserProc( Symbol( NamespaceScopes(), methodName ), NamespaceScopesCollection(), Procedure::Function, false, false, false ); pUserProc->SetParentClass( &_class ); Parameters params; params.push_back( new Parameter( "_System_LocalThis", Type( DEF_PTR_VOID ) ) ); pUserProc->SetRealParams( params ); pUserProc->SetReturnType( Type( DEF_OBJECT, pInterface->GetClass() ) ); pUserProc->_paramStr = ""; pUserProc->Using(); // 関数を追加 if( compiler.GetObjectModule().meta.GetUserProcs().IsExist( pUserProc ) ) { // 既に存在している compiler.errorMessenger.Output(15,pUserProc->GetName(),-1); delete pUserProc; } else { compiler.GetObjectModule().meta.GetUserProcs().Put( pUserProc ); } LexicalAnalyzer::AddMethod( &_class, pUserProc, Prototype::Public, 0, false, // isConst false, // isAbstract false, // isVirtual false, // isOverride "", true, // isAutoGeneration -1 ); } } bool LexicalAnalyzer::Implements( CClass &_class, const char *interfaceNames, int nowLine ) { Jenga::Common::Strings paramStrs; SplitParameter( interfaceNames, paramStrs ); BOOST_FOREACH( const std::string ¶mStr, paramStrs ) { char className[VN_SIZE]; Jenga::Common::Strings typeParameterStrings; SplitGenericClassInstance( paramStr.c_str(), className, typeParameterStrings ); Types actualTypeParameters; BOOST_FOREACH( const std::string &typeParameterStr, typeParameterStrings ) { Type type; compiler.StringToType( typeParameterStr, type ); actualTypeParameters.push_back( type ); } //継承元クラスを取得 const CClass *pInterfaceClass = compiler.GetObjectModule().meta.FindClassSupportedTypeDef( LexicalAnalyzer::FullNameToSymbol( className ) ); if( !pInterfaceClass ){ compiler.errorMessenger.Output(106,paramStr.c_str(),nowLine); continue; } if( !pInterfaceClass->IsReady() ){ // インターフェイスが未解析のとき LexicalAnalyzer::LookaheadClass( pInterfaceClass->GetName().c_str(), compiler.GetObjectModule().meta.GetClasses() ); } if( pInterfaceClass->IsInterface() || pInterfaceClass->IsComInterface() ) { // インターフェイスを継承する std::vector overrideResults; Implements( _class, new ::Interface( pInterfaceClass, actualTypeParameters ), overrideResults ); // エラーチェック BOOST_FOREACH( const DynamicMethod::OverrideResult result, overrideResults ) { OverrideErrorCheck( result ); } } else { // インターフェイスではないとき compiler.errorMessenger.Output(138,pInterfaceClass->GetName().c_str(),nowLine ); } } return true; } void GetClass_recur( const char *lpszInheritsClass, Classes &classes ) { 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.IsCompilingClass() ? &compiler.GetCompilingClass() : NULL; 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 ){ compiler.errorMessenger.Output(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 ) ) { compiler.errorMessenger.Output(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; //インターフェイス名を取得 GetCommandToken( temporary, basbuf, i ); char className[VN_SIZE]; Jenga::Common::Strings typeParameters; Jenga::Common::Strings typeParameterBaseClassNames; SplitGenericClassInstance( temporary, className, typeParameters, true, &typeParameterBaseClassNames ); CClass *pobj_c = const_cast( classes.FindEx( Symbol( namespaceScopes, className ) ) ); if(!pobj_c) continue; compiler.SetCompilingClass( pobj_c ); if(lpszInheritsClass){ if(lstrcmp(lpszInheritsClass,pobj_c->GetName().c_str())!=0){ //継承先先読み用 continue; } } if(pobj_c->IsReady()){ //既に先読みされているとき continue; } ///////////////////////////////////////////////////////// // ☆★☆ ジェネリクスサポート ☆★☆ for( i2=0; i2(typeParameters.size()); i2++ ) { Type baseType( DEF_OBJECT, *classes.GetObjectClassPtr() ); if( typeParameterBaseClassNames[i2].size() ) { if( !compiler.StringToType( typeParameterBaseClassNames[i2], baseType ) ) { compiler.errorMessenger.Output(106,typeParameterBaseClassNames[i2],i); } else if( !baseType.IsObject() ) { compiler.errorMessenger.Output(106,typeParameterBaseClassNames[i2],i); } } pobj_c->AddFormalGenericType( GenericType( typeParameters[i2], baseType ) ); } ///////////////////////////////////////////////////////// pobj_c->Readed(); pobj_c->SetConstructorMemberSubIndex( -1 ); pobj_c->SetDestructorMemberSubIndex( -1 ); if( memcmp( basbuf+i+1, "__COM", 5 ) == 0 && IsCommandDelimitation( basbuf[i+1+5] ) ) { // COMインターフェイス pobj_c->SetClassType( CClass::ComInterface ); i += 6; } 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){ compiler.errorMessenger.Output(105,temporary,i); goto Interface_InheritsError; } //継承元クラスを取得 const CClass *pInheritsClass = compiler.GetObjectModule().meta.FindClassSupportedTypeDef( LexicalAnalyzer::FullNameToSymbol( temporary ) ); if( !pInheritsClass ){ compiler.errorMessenger.Output(106,temporary,i); goto Interface_InheritsError; } //ループ継承でないかをチェック if( !LexicalAnalyzer::LoopRefCheck( *pInheritsClass ) ) { compiler.errorMessenger.Output(123,pInheritsClass->GetName(),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)){ compiler.errorMessenger.Output(22,"Interface",i); i--; break; } if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){ compiler.errorMessenger.Output(111,NULL,i); break; } else if( basbuf[i] == 1 && basbuf[i+1] == ESC_IMPLEMENTS ) { compiler.errorMessenger.Output(137, 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--; compiler.errorMessenger.Output(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 ))){ compiler.errorMessenger.Output(1,NULL,i); break; } //関数ハッシュへ登録 char interfaceName[VN_SIZE] = ""; UserProc *pUserProc = LexicalAnalyzer::ParseUserProc( NamespaceScopes(), NamespaceScopesCollection(), temporary,sub_address,true,pobj_c, false, interfaceName ); if( pUserProc ) { // 関数を追加 if( compiler.GetObjectModule().meta.GetUserProcs().IsExist( pUserProc ) ) { // 既に存在している compiler.errorMessenger.Output(15,pUserProc->GetName(),i); delete pUserProc; } else { compiler.GetObjectModule().meta.GetUserProcs().Put( pUserProc ); } //メンバ関数を追加 LexicalAnalyzer::AddMethod(pobj_c, pUserProc, Prototype::Public, //Publicアクセス権 0, // bStatic false, // isConst true, // isAbstract true, // isVirtual false, // isOverride interfaceName, false, // isAutoGeneration 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( dwClassType != ESC_TYPE ) { compiler.errorMessenger.Output(140,NULL,i); } if(!(iAlign==1||iAlign==2||iAlign==4||iAlign==8||iAlign==16)) compiler.errorMessenger.Output(51,NULL,i); } else if( memicmp( basbuf + i, "Blittable(", 10 ) == 0 ){ // Blittable修飾子 i+=10; i=JumpStringInPare(basbuf,i)+1; if( dwClassType != ESC_CLASS ) { compiler.errorMessenger.Output(141,NULL,i); } } if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENUM ) { // 列挙型の場合 i += 2; } else if( basbuf[i] == 1 && basbuf[i+1] == ESC_DELEGATE ) { // デリゲートの場合 i += 2; } //クラス名を取得 GetCommandToken( temporary, basbuf, i ); char className[VN_SIZE]; Jenga::Common::Strings typeParameters; Jenga::Common::Strings typeParameterBaseClassNames; SplitGenericClassInstance( temporary, className, typeParameters, true, &typeParameterBaseClassNames ); CClass *pobj_c = const_cast( classes.FindEx( Symbol( namespaceScopes, className ) ) ); if(!pobj_c) continue; compiler.SetCompilingClass( pobj_c ); if(lpszInheritsClass){ if( pobj_c->GetName() != lpszInheritsClass ){ //継承先先読み用 continue; } } if( lstrcmp(className,"Control")==0) { int test=0; } if(pobj_c->IsReady()){ //既に先読みされているとき continue; } ///////////////////////////////////////////////////////// // ☆★☆ ジェネリクスサポート ☆★☆ for( i2=0; i2(typeParameters.size()); i2++ ) { Type baseType( DEF_OBJECT, *classes.GetObjectClassPtr() ); if( typeParameterBaseClassNames[i2].size() ) { if( !compiler.StringToType( typeParameterBaseClassNames[i2], baseType ) ) { compiler.errorMessenger.Output(106,typeParameterBaseClassNames[i2],i); } else if( !baseType.IsObject() ) { compiler.errorMessenger.Output(106,typeParameterBaseClassNames[i2],i); } } pobj_c->AddFormalGenericType( GenericType( typeParameters[i2], baseType ) ); } ///////////////////////////////////////////////////////// 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{ if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS) { // クラス継承先が指定されているとき i += 3; GetCommandToken( temporary, basbuf, i ); if(lstrcmpi(temporary,pobj_c->GetName().c_str())==0){ compiler.errorMessenger.Output(105,temporary,i); goto InheritsError; } } else { // 何の指定もないときはObjectクラスを継承する lstrcpy( temporary, "Object" ); } LexicalAnalyzer::Inherits( *pobj_c, temporary, i ); if( basbuf[i+1] == 1 && basbuf[i+2] == ESC_IMPLEMENTS ) { // インターフェイス実装を行う場合 i += 3; GetCommandToken( temporary, basbuf, i ); LexicalAnalyzer::Implements( *pobj_c, temporary, i ); } } InheritsError: //メンバとメソッドを取得 while(1){ i++; //エラー if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){ compiler.errorMessenger.Output(22,"Class",i); i--; break; } if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){ compiler.errorMessenger.Output(111,NULL,i); break; } else if( basbuf[i] == 1 && basbuf[i+1] == ESC_IMPLEMENTS ) { compiler.errorMessenger.Output(137, 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) compiler.errorMessenger.Output(22,"Class",top_pos); else compiler.errorMessenger.Output(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){ cp=i; //エラー用 Member *pMember = LexicalAnalyzer::CreateMember( *pobj_c, accessibility, isConst, false, temporary, i ); if( pMember ) { if(bStatic) { //静的メンバを追加 pobj_c->AddStaticMember( pMember ); } else { //メンバを追加 pobj_c->AddDynamicMember( pMember ); if(pobj_c->GetDynamicMembers().back()->GetType().IsStruct()){ if( !pobj_c->GetDynamicMembers().back()->GetType().GetClass().IsReady() ){ //参照先が読み取られていないとき GetClass_recur( pobj_c->GetDynamicMembers().back()->GetType().GetClass().GetName().c_str(), classes ); } } if(pobj_c->GetDynamicMembers().back()->GetType().IsStruct()){ //循環参照のチェック pobj_LoopRefCheck->add(pobj_c->GetName().c_str()); if(!MemberVar_LoopRefCheck(pobj_c->GetDynamicMembers().back()->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{ //関数ハッシュへ登録 char interfaceName[VN_SIZE] = ""; UserProc *pUserProc = LexicalAnalyzer::ParseUserProc( NamespaceScopes(), NamespaceScopesCollection(), temporary,sub_address,isVirtual,pobj_c, (bStatic!=0), interfaceName ); if( pUserProc ) { // 関数を追加 if( compiler.GetObjectModule().meta.GetUserProcs().IsExist( pUserProc ) ) { // 既に存在している compiler.errorMessenger.Output(15,pUserProc->GetName(),i); delete pUserProc; } else { compiler.GetObjectModule().meta.GetUserProcs().Put( pUserProc ); } //メソッドを追加 cp=i; //エラー用 LexicalAnalyzer::AddMethod(pobj_c, pUserProc, accessibility, bStatic, isConst, isAbstract, isVirtual, isOverride, interfaceName, false, 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); compiler.errorMessenger.Output(22,temporary,i); } if(basbuf[i]==1&&basbuf[i+1]==GetEndXXXCommand((char)i3)){ i+=2; break; } } } } } } // 呼び出し元でコンパイル中のクラスポインタを元に戻す compiler.SetCompilingClass( pBackCompilingClass ); // 名前空間を元に戻す compiler.GetNamespaceSupporter().GetLivingNamespaceScopes() = backupNamespaceScopes; // インポートされた名前空間を元に戻す compiler.GetNamespaceSupporter().GetImportedNamespaces() = backupImportedNamespaces; } void LexicalAnalyzer::LookaheadClass( const char *className, Classes &classes ) { pobj_LoopRefCheck->add( className ); GetClass_recur( className, classes ); pobj_LoopRefCheck->del( className ); } bool LexicalAnalyzer::LoopRefCheck( const CClass &objClass ) { if( pobj_LoopRefCheck->check( objClass ) ) { return false; } return true; } void LexicalAnalyzer::CollectClasses( const char *source, Classes &classes ){ //ループ継承チェック用のクラス pobj_LoopRefCheck=new CLoopRefCheck(); //クラスを取得 GetClass_recur( 0, classes ); delete pobj_LoopRefCheck; pobj_LoopRefCheck=0; // イテレータの準備 classes.Iterator_Init(); } void LexicalAnalyzer::TemplateExpand_ResolveMethod( const CMethod *pBaseMethod, const Types &actualTypes, CClass *pNewClass ) { UserProc *pUserProc = new UserProc( pBaseMethod->GetUserProc(), pNewClass ); pUserProc->Using(); pUserProc->GetParameters().clear(); pUserProc->RealParams().clear(); // パラメータのジェネリック型を解決 BOOST_FOREACH( const Parameter *pParam, pBaseMethod->GetUserProc().Params() ) { Type type = pParam->IsTypeParameter() ? actualTypes[pParam->GetFormalTypeIndex()] : *pParam; type.SetPtrLevel( pParam->PtrLevel() ); pUserProc->GetParameters().push_back( new Parameter( *pParam, type ) ); } BOOST_FOREACH( const Parameter *pParam, pBaseMethod->GetUserProc().RealParams() ) { Type type = pParam->IsTypeParameter() ? actualTypes[pParam->GetFormalTypeIndex()] : *pParam; type.SetPtrLevel( pParam->PtrLevel() ); pUserProc->RealParams().push_back( new Parameter( *pParam, type ) ); } // 戻り値のジェネリック型を解決 if( pUserProc->ReturnType().IsTypeParameter() ) { Type type = actualTypes[pUserProc->ReturnType().GetFormalTypeIndex()]; type.SetPtrLevel( pUserProc->ReturnType().PtrLevel() ); pUserProc->SetReturnType( type ); } compiler.GetObjectModule().meta.GetUserProcs().Put( pUserProc ); compiler.GetObjectModule().meta.GetUserProcs().Iterator_Init(); LexicalAnalyzer::AddMethod( pNewClass, pUserProc, pBaseMethod->GetAccessibility(), pBaseMethod->IsStatic(), pBaseMethod->IsConst(), pBaseMethod->IsAbstract(), pBaseMethod->IsVirtual(), false, "", false, -1 ); } const CClass *LexicalAnalyzer::TemplateExpand( CClass &_class, const Types &actualTypes ) { // 展開済みのクラスがあればそれを返す BOOST_FOREACH( const ExpandedTemplateClass *pExpandedTemplateClass, _class.expandedTemplateClasses ) { if( pExpandedTemplateClass->GetActualTypes().IsEquals( actualTypes ) ) { return &pExpandedTemplateClass->GetClass(); } } ///////////////////////////////////////////////////////////////// // 未展開の場合は新たに展開する ///////////////////////////////////////////////////////////////// // クラスをコピー CClass *pNewClass = new CClass( _class, _class.GetImportedNamespaces(), _class.GetClassType(), _class.GetFormalGenericTypes(), actualTypes, _class.GetConstructorMemberSubIndex(), _class.GetDestructorMemberSubIndex(), 0, _class.GetFixedAlignment() ); // 基底クラス pNewClass->SetSuperClass( &_class.GetSuperClass() ); // インターフェイスのジェネリック型を解決 BOOST_FOREACH( const ::Interface *pInterface, _class.GetInterfaces() ) { pNewClass->AddInterface( new ::Interface( &pInterface->GetClass(), actualTypes ) ); } // メンバのジェネリック型を解決 BOOST_FOREACH( const Member *pMember, _class.GetDynamicMembers() ) { Type type = pMember->GetType(); if( type.IsTypeParameter() ) { // ジェネリック型だったときは値型に変換 type = actualTypes[type.GetFormalTypeIndex()]; type.SetPtrLevel( pMember->GetType().PtrLevel() ); } pNewClass->GetDynamicMembers().push_back( new Member( *pMember, type ) ); } // クラス メソッドのジェネリック型を解決 BOOST_FOREACH( const CMethod *pMethod, _class.GetDynamicMethods() ) { if( pMethod->GetUserProc().GetParentClassPtr() == &_class ) { // ターゲットクラス内で実装されるメソッドの場合 TemplateExpand_ResolveMethod( pMethod, actualTypes, pNewClass ); } else { DynamicMethod *pNewDynamicMethod = new DynamicMethod( *pMethod ); pNewClass->GetDynamicMethods().push_back( pNewDynamicMethod ); } } // インターフェイス メソッドのジェネリック型を解決 BOOST_FOREACH( const ::Interface *pInterface, _class.GetInterfaces() ) { BOOST_FOREACH( const CMethod *pMethod, pInterface->GetDynamicMethods() ) { TemplateExpand_ResolveMethod( pMethod, actualTypes, pNewClass ); } } pNewClass->SetVtblNum( _class.GetVtblNum() ); // 展開済みクラスとして登録 _class.expandedTemplateClasses.push_back( new ExpandedTemplateClass( pNewClass, actualTypes ) ); pNewClass->Readed(); return pNewClass; }