#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 ) { char *buffer; int MaxSize,length; MaxSize=65535; buffer=(char *)HeapAlloc(hHeap,0,MaxSize+65535); length=0; buffer[0]=0; BOOST_FOREACH( const EnumInfo &enumInfo, enums ) { BOOST_FOREACH( const std::string &namespaceStr, enumInfo.GetNamespaceScopes() ){ sprintf(buffer+length,"Namespace %s\n",namespaceStr.c_str()); length+=lstrlen(buffer+length); } sprintf(buffer+length,"Class Enum %s\n",enumInfo.GetName().c_str()); length+=lstrlen(buffer+length); sprintf(buffer+length,"\tInherits EnumBase<%s>\n",enumInfo.GetName().c_str()); length+=lstrlen(buffer+length); sprintf(buffer+length,"\tSub %s(value As Long,lpszName As LPSTR)\n",enumInfo.GetName().c_str()); length+=lstrlen(buffer+length); lstrcpy(buffer+length,"\t\tEnumBase(value,lpszName)\n"); length+=lstrlen(buffer+length); lstrcpy(buffer+length,"\tEnd Sub\n"); length+=lstrlen(buffer+length); lstrcpy(buffer+length,"Public\n"); length+=lstrlen(buffer+length); sprintf(buffer+length,"\tSub %s()\n",enumInfo.GetName().c_str()); length+=lstrlen(buffer+length); if( enumInfo.GetMembers().size()){ sprintf(buffer+length,"\t\tEnumBase(%s)\n", enumInfo.GetMembers().begin()->GetName().c_str() ); length+=lstrlen(buffer+length); } lstrcpy(buffer+length,"\tEnd Sub\n"); length+=lstrlen(buffer+length); sprintf(buffer+length,"\tSub ~%s()\n",enumInfo.GetName().c_str()); length+=lstrlen(buffer+length); lstrcpy(buffer+length,"\tEnd Sub\n"); length+=lstrlen(buffer+length); BOOST_FOREACH( const EnumMember &member, enumInfo.GetMembers() ) { sprintf(buffer+length,"\tStatic %s As %s((%s) As Long,\"%s\")\n", member.GetName().c_str(), enumInfo.GetName().c_str(), member.GetValueStr().c_str(), member.GetName().c_str()); length+=lstrlen(buffer+length); } lstrcpy(buffer+length,"End Class\n"); length+=lstrlen(buffer+length); BOOST_FOREACH( const std::string &namespaceStr, enumInfo.GetNamespaceScopes() ){ lstrcpy( buffer+length, "End Namespace\n" ); length+=lstrlen(buffer+length); } //バッファ領域が足りなくなった場合はバッファを増量する if(length>MaxSize){ MaxSize+=65535; buffer=(char *)HeapReAlloc(hHeap,0,buffer,MaxSize+65535); } } #ifdef _DEBUG // ログを生成 Jenga::Common::Logger logger( Jenga::Common::Environment::GetAppDir() + "\\enum_generated.log", false ); logger << buffer << std::endl; #endif std::string result = buffer; HeapDefaultFree( buffer ); return result; }