void write_realization( const circuit& circ, std::ostream& os, const write_realization_settings& settings ) { unsigned oldsize = 0; if ( !settings.header.empty() ) { std::string header = settings.header; boost::algorithm::replace_all( header, "\n", "\n# " ); os << "# " << header << std::endl; } if ( !settings.version.empty() ) { os << ".version " << settings.version << std::endl; } os << ".numvars " << circ.lines() << std::endl; std::vector<std::string> variables( circ.lines() ); for ( unsigned i = 0u; i < circ.lines(); ++i ) { variables[i] = boost::str( boost::format( "x%d" ) % i ); } std::vector<std::string> _inputs( circ.inputs().begin(), circ.inputs().end() ); oldsize = _inputs.size(); _inputs.resize( circ.lines() ); for ( unsigned i = oldsize; i < circ.lines(); ++i ) { _inputs[i] = boost::str( boost::format( "i%d" ) % i ); } std::vector<std::string> _outputs( circ.outputs().begin(), circ.outputs().end() ); oldsize = _outputs.size(); _outputs.resize( circ.lines() ); for ( unsigned i = oldsize; i < circ.lines(); ++i ) { _outputs[i] = boost::str( boost::format( "o%d" ) % i ); } os << ".variables " << boost::algorithm::join( variables, " " ) << std::endl; namespace karma = boost::spirit::karma; namespace ascii = boost::spirit::ascii; os << ".inputs"; //std::ostream_iterator<char> outit( os ); //karma::generate_delimited( outit, *( karma::no_delimit['"' << karma::string] << '"' ), ascii::space, _inputs ); for ( const auto& _input : _inputs ) { std::string quote = ( _input.find( " " ) != std::string::npos ) ? "\"" : ""; os << boost::format( " %s%s%s" ) % quote % _input % quote; } os << std::endl; os << ".outputs"; //karma::generate_delimited( outit, *( karma::no_delimit['"' << karma::string] << '"' ), ascii::space, _outputs ); for ( const auto& _output : _outputs ) { std::string quote = ( _output.find( " " ) != std::string::npos ) ? "\"" : ""; os << boost::format( " %s%s%s" ) % quote % _output % quote; } os << std::endl; std::string _constants( circ.lines(), '-' ); std::transform( circ.constants().begin(), circ.constants().end(), _constants.begin(), constant_to_char() ); std::string _garbage( circ.lines(), '-' ); std::transform( circ.garbage().begin(), circ.garbage().end(), _garbage.begin(), garbage_to_char() ); os << ".constants " << _constants << std::endl << ".garbage " << _garbage << std::endl; for ( const auto& bus : circ.inputbuses().buses() ) { std::vector<std::string> lines; std::transform( bus.second.begin(), bus.second.end(), std::back_inserter( lines ), line_to_variable() ); os << ".inputbus " << bus.first << " " << boost::algorithm::join( lines, " " ) << std::endl; } for ( const auto& bus : circ.outputbuses().buses() ) { std::vector<std::string> lines; std::transform( bus.second.begin(), bus.second.end(), std::back_inserter( lines ), line_to_variable() ); os << ".outputbus " << bus.first << " " << boost::algorithm::join( lines, " " ) << std::endl; } for ( const auto& bus : circ.statesignals().buses() ) { std::vector<std::string> lines; std::transform( bus.second.begin(), bus.second.end(), std::back_inserter( lines ), line_to_variable() ); os << ".state " << bus.first << " " << boost::algorithm::join( lines, " " ) << std::endl; } for ( const auto& module : circ.modules() ) { os << ".module " << module.first << std::endl; write_realization_settings module_settings; module_settings.version.clear(); module_settings.header.clear(); write_realization( *module.second, os, module_settings ); } os << ".begin" << std::endl; std::string cmd; for ( const auto& g : circ ) { cmd = settings.type_label( g ); std::vector<std::string> lines; // Peres is special boost::transform( g.controls(), std::back_inserter( lines ), line_to_variable() ); boost::transform( g.targets(), std::back_inserter( lines ), line_to_variable() ); os << cmd << " " << boost::algorithm::join( lines, " " ); boost::optional<const std::map<std::string, std::string>&> annotations = circ.annotations( g ); if ( annotations ) { std::string sannotations; for ( const auto& p : *annotations ) { sannotations += boost::str( boost::format( " %s=\"%s\"" ) % p.first % p.second ); } os << " #@" << sannotations; } os << std::endl; } os << ".end" << std::endl; }