#include "stdafx.h" using namespace ActiveBasic::Compiler; void LexicalAnalyzer::CollectEnumMembers( EnumInfo &enumInfo, const char *source, int nowLine ) { enumInfo.GetEnumMembers().clear(); int i=nowLine,i2; if(!(source[i]==1&&source[i+1]==ESC_ENUM)) return; i+=2; //列挙体の名前を取得 char temporary[VN_SIZE]; for(i2=0;;i++,i2++){ if(IsCommandDelimitation(source[i])){ temporary[i2]=0; break; } if(!IsVariableChar(source[i])){ compiler.errorMessenger.Output(1,NULL,i); break; } temporary[i2]=source[i]; } if(source[i]=='\0'){ compiler.errorMessenger.Output(22,"Enum",nowLine); return; } int currentValue = 0; bool isUseCurrentValue = true; std::string currentValueStr; std::string lastMemberName; char temp2[VN_SIZE]; while(1){ i++; if(source[i]==1&&source[i+1]==ESC_ENDENUM) break; for(i2=0;;i2++,i++){ if(IsCommandDelimitation(source[i])){ temporary[i2]=0; break; } if(source[i]=='='){ temporary[i2]=0; break; } temporary[i2]=source[i]; } if(temporary[0]=='\0'){ if(source[i]=='\0'){ compiler.errorMessenger.Output(22,"Enum",nowLine); break; } continue; } if( source[i] != '=' ) { if( isUseCurrentValue ) { currentValue++; sprintf( temp2, "%d", currentValue ); currentValueStr = temp2; } else { currentValueStr = lastMemberName + "+1"; } } else { i++; GetCommandToken( temp2, source, i ); _int64 i64data; if( StaticCalculation( false, temp2, 0, &i64data, Type() ) ) { currentValue = static_cast(i64data); sprintf( temp2, "%d", currentValue ); currentValueStr = temp2; } else { // 取得できなかった(なんらかの識別子を含む可能性あり) isUseCurrentValue = false; currentValueStr = temp2; } } //メンバを追加 enumInfo.GetEnumMembers().push_back( EnumMember( temporary, currentValueStr, i ) ); lastMemberName = temporary; } } void LexicalAnalyzer::CollectEnums( const char *source, EnumInfoCollection &enums ) { enums.clear(); // 名前空間管理 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes(); namespaceScopes.clear(); int i2; char temporary[VN_SIZE]; for(int 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; } if(source[i]==1&&source[i+1]==ESC_ENUM){ if(i>=2){ if(source[i-2]==1&&source[i-1]==ESC_CONST) continue; } i2 = i + 2; GetCommandToken( temporary, source, i2 ); // 追加 enums.push_back( EnumInfo( namespaceScopes, temporary ) ); // 収集 CollectEnumMembers( enums.back(), source, i ); } } } std::string LexicalAnalyzer::GenerateEnumsSourceCode( const EnumInfoCollection &enums ) { std::string buffer; buffer.reserve(65536); BOOST_FOREACH( const EnumInfo &enumInfo, enums ) { BOOST_FOREACH( const std::string &namespaceStr, enumInfo.GetNamespaceScopes() ){ buffer.append("Namespace ").append(namespaceStr) += '\n'; } buffer.append("Class Enum ").append(enumInfo.GetName()) += '\n'; buffer.append("\tInherits EnumBase<").append(enumInfo.GetName()).append(">\n"); buffer.append("\tSub ").append(enumInfo.GetName()).append("(value As Long,lpszName As LPCTSTR)\n"); buffer.append("\t\tEnumBase(value,lpszName)\n" "\tEnd Sub\n" "Public\n"); buffer.append("\tSub ").append(enumInfo.GetName()).append("()\n"); if( !enumInfo.GetMembers().empty() ){ buffer.append("\t\tEnumBase(").append(enumInfo.GetMembers().front().GetName()) .append(")\n"); } buffer.append("\tEnd Sub\n"); BOOST_FOREACH( const EnumMember &member, enumInfo.GetMembers() ) { buffer.append("\tStatic ") .append(member.GetName()).append(" As ") .append(enumInfo.GetName()).append("((") .append(member.GetValueStr()).append(") As Long,\"") .append(member.GetName()).append("\")\n"); } buffer.append("End Class\n"); BOOST_FOREACH( const std::string &namespaceStr, enumInfo.GetNamespaceScopes() ){ buffer.append("End Namespace\n"); } } #ifdef _DEBUG // ログを生成 Jenga::Common::Logger logger( Jenga::Common::Environment::GetAppDir() + "\\enum_generated.log", false ); logger << buffer << std::endl; #endif return buffer; }