#include "stdafx.h" using namespace ActiveBasic::Compiler; void LexicalAnalyzer::CollectDelegates( const char *source, Delegates &delegates ) { // 名前空間管理 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes(); namespaceScopes.clear(); // Imports情報のクリア compiler.GetNamespaceSupporter().ClearImportedNamespaces(); for (int i=0; source[i] != '\0'; i++) { if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){ i+=2; char const* p = &source[i]; while (!IsCommandDelimitation(source[i])) { ++i; } namespaceScopes.push_back(std::string(p, &source[i])); 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 ){ i+=2; char const* p = &source[i]; while (!IsCommandDelimitation(source[i])) { ++i; } std::string s(p, &source[i]); if (!compiler.GetNamespaceSupporter().ImportsNamespace(s)) { compiler.errorMessenger.Output(64, s.c_str(), i); } continue; } else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED ) { // Imports情報のクリア compiler.GetNamespaceSupporter().ClearImportedNamespaces(); continue; } else if( source[i] == 1 && source[i+1] == ESC_DELEGATE ) { int nowLine = i; i += 2; if( !( source[i] == 1 && ( source[i+1] == ESC_SUB || source[i+1] == ESC_FUNCTION ) ) ) { compiler.errorMessenger.Output(1,NULL,i); continue; } Procedure::Kind procKind = Procedure::Sub; if( source[i+1] == ESC_FUNCTION ) { procKind = Procedure::Function; } i += 2; // 名前 char name[VN_SIZE]; GetIdentifierToken( name, source, i ); if( source[i] != '(' ) { compiler.errorMessenger.Output(1,NULL,nowLine); continue; } // パラメータ文字列 char paramStr[8192]; i += GetStringInPare( paramStr, source + i, true ); // 戻り値の型の文字列 char returnTypeName[VN_SIZE] = ""; if( source[i] == 1 && source[i+1] == ESC_AS ) { i += 2; GetCommandToken( returnTypeName, source, i ); if( procKind != Procedure::Function ) { compiler.errorMessenger.Output(38,name,nowLine); } } else { if( procKind == Procedure::Function ) { compiler.errorMessenger.Output(-104,name,nowLine); strcpy( returnTypeName, "Double" ); } } delegates.Put( new Delegate( Symbol( namespaceScopes, name ), compiler.GetNamespaceSupporter().GetImportedNamespaces(), procKind, paramStr, returnTypeName, nowLine ) ); } } } std::string LexicalAnalyzer::GenerateDelegatesSourceCode( const Delegates &delegates ) { std::string destSource = ""; Jenga::Common::SourceTemplate sourceTemplate( ActiveBasic::Common::Environment::GetAbdevSystemDirPath() + "\\templates\\delegate_class.tab" ); foreach (auto pDelegate, delegates) { const Delegate &dg = *pDelegate; if( dg.IsExternal() ) { // 静的リンクライブラリの場合は飛ばす(既にインスタンスが定義済みであるため) continue; } std::map values; if( dg.GetNamespaceScopes().size() ) { std::string namespaceScopesCommandStr; std::string endNamespaceScopesCommandStr; foreach( const std::string &namespaceStr, dg.GetNamespaceScopes() ) { if( namespaceScopesCommandStr.size() ) { namespaceScopesCommandStr += ':'; endNamespaceScopesCommandStr += ':'; } namespaceScopesCommandStr += "Namespace " + namespaceStr; endNamespaceScopesCommandStr += "End Namespace"; } values.insert( std::map::value_type( "#namespace_begin#", namespaceScopesCommandStr ) ); values.insert( std::map::value_type( "#namespace_end#", endNamespaceScopesCommandStr ) ); } else { values.insert( std::map::value_type( "#namespace_begin#", "" ) ); values.insert( std::map::value_type( "#namespace_end#", "" ) ); } values.insert( std::map::value_type( "#name#", dg.GetName() ) ); if( dg.IsFunction() ) { values.insert( std::map::value_type( "#call_method_begin#", (std::string)"Function Call(" + dg.GetParamStr() + ") As " + dg.GetReturnTypeName() ) ); values.insert( std::map::value_type( "#call_method_end#", "End Function" ) ); values.insert( std::map::value_type( "#result#", "Call=" ) ); } else { values.insert( std::map::value_type( "#call_method_begin#", (std::string)"Sub Call(" + dg.GetParamStr() + ")" ) ); values.insert( std::map::value_type( "#call_method_end#", "End Sub" ) ); values.insert( std::map::value_type( "#result#", "" ) ); } // 呼び出し側の実引数文字列を作成 Jenga::Common::Strings paramVarNames; LexicalAnalyzer::ExtractParameterVarNames( dg.GetParamStr().c_str(), paramVarNames, dg.GetSourceIndex() ); std::string tempParamStrForCall; foreach( const std::string &varName, paramVarNames ) { if( !tempParamStrForCall.empty() ) { tempParamStrForCall += ","; } tempParamStrForCall += varName; } values.insert( std::map::value_type( "#params#", tempParamStrForCall ) ); destSource += sourceTemplate.GetResult( values ); } /* std::ofstream ofs( ( Jenga::Common::Environment::GetAppDir() + "\\generated_delegate_code.log" ).c_str() ); ofs << destSource; ofs.close(); */ return destSource; } void LexicalAnalyzer::RefleshDelegateParameterAndReturnType( Delegate &dg ) { if( dg.IsExternal() ) { // 外部参照の場合はリフレッシュが不要 return; } compiler.GetNamespaceSupporter().SetImportedNamespaces( dg.GetImportedNamespaces() ); compiler.GetNamespaceSupporter().SetLivingNamespaceScopes( dg.GetNamespaceScopes() ); // パラメータを解析 Jenga::Common::Strings parameterStrings; SplitParameter( dg.GetParamStr(), parameterStrings ); ActiveBasic::Compiler::LexicalAnalyzer::AnalyzeParameter( dg.GetParameters(), parameterStrings, dg.GetSourceIndex() ); // 動的パラメータを作る dg.GetDynamicParams() = dg.GetParameters(); dg.GetDynamicParams().insert( dg.GetDynamicParams().begin(), new Parameter( "_System_LocalThis", Type( DEF_PTR_VOID ) ) ); if( dg.IsFunction() ) { // 戻り値を取得 Type returnType; if( !compiler.StringToType( dg.GetReturnTypeName(), returnType ) ) { compiler.errorMessenger.Output(3,dg.GetReturnTypeName(),dg.GetSourceIndex()); } else { dg.SetReturnType( returnType ); } } } void LexicalAnalyzer::RefleshDelegatesParameterAndReturnType( Delegates &delegates ) { foreach (auto *pDelegate, delegates) { RefleshDelegateParameterAndReturnType(*pDelegate); } }