| #include "TileConfig.hpp" |
| #include "Util.hpp" |
| #include "BitDatabase.hpp" |
| #include <algorithm> |
| #include <sstream> |
| using namespace std; |
| |
| namespace Trellis { |
| ostream &operator<<(ostream &out, const ConfigArc &arc) { |
| out << "arc: " << arc.sink << " " << arc.source << endl; |
| return out; |
| } |
| |
| istream &operator>>(istream &in, ConfigArc &arc) { |
| in >> arc.sink; |
| in >> arc.source; |
| return in; |
| } |
| |
| ostream &operator<<(ostream &out, const ConfigWord &cw) { |
| out << "word: " << cw.name << " " << to_string(cw.value) << endl; |
| return out; |
| } |
| |
| istream &operator>>(istream &in, ConfigWord &cw) { |
| in >> cw.name; |
| in >> cw.value; |
| return in; |
| } |
| |
| ostream &operator<<(ostream &out, const ConfigEnum &cw) { |
| out << "enum: " << cw.name << " " << cw.value << endl; |
| return out; |
| } |
| |
| istream &operator>>(istream &in, ConfigEnum &ce) { |
| in >> ce.name; |
| in >> ce.value; |
| return in; |
| } |
| |
| ostream &operator<<(ostream &out, const ConfigUnknown &cu) { |
| out << "unknown: " << to_string(ConfigBit{cu.frame, cu.bit, false}) << endl; |
| return out; |
| } |
| |
| istream &operator>>(istream &in, ConfigUnknown &cu) { |
| string s; |
| in >> s; |
| ConfigBit c = cbit_from_str(s); |
| cu.frame = c.frame; |
| cu.bit = c.bit; |
| assert(!c.inv); |
| return in; |
| } |
| |
| ostream &operator<<(ostream &out, const TileConfig &tc) { |
| for (const auto &arc : tc.carcs) |
| out << arc; |
| for (const auto &cword : tc.cwords) |
| out << cword; |
| for (const auto &cenum : tc.cenums) |
| out << cenum; |
| for (const auto &cunk : tc.cunknowns) |
| out << cunk; |
| return out; |
| } |
| |
| istream &operator>>(istream &in, TileConfig &tc) { |
| tc.carcs.clear(); |
| tc.cwords.clear(); |
| tc.cenums.clear(); |
| while (!skip_check_eor(in)) { |
| string type; |
| in >> type; |
| if (type == "arc:") { |
| ConfigArc a; |
| in >> a; |
| tc.carcs.push_back(a); |
| } else if (type == "word:") { |
| ConfigWord w; |
| in >> w; |
| tc.cwords.push_back(w); |
| } else if (type == "enum:") { |
| ConfigEnum e; |
| in >> e; |
| tc.cenums.push_back(e); |
| } else if (type == "unknown:") { |
| ConfigUnknown u; |
| in >> u; |
| tc.cunknowns.push_back(u); |
| } else { |
| throw runtime_error("unexpected token " + type + " while reading config text"); |
| } |
| } |
| return in; |
| } |
| |
| void TileConfig::add_arc(const string &sink, const string &source) { |
| carcs.push_back({sink, source}); |
| } |
| |
| void TileConfig::add_word(const string &name, const vector<bool> &value) { |
| cwords.push_back({name, value}); |
| } |
| |
| void TileConfig::add_enum(const string &name, const string &value) { |
| cenums.push_back({name, value}); |
| } |
| |
| void TileConfig::add_unknown(int frame, int bit) { |
| cunknowns.push_back({frame, bit}); |
| } |
| |
| |
| string TileConfig::to_string() const { |
| stringstream ss; |
| ss << *this; |
| return ss.str(); |
| } |
| |
| TileConfig TileConfig::from_string(const string &str) { |
| stringstream ss(str); |
| TileConfig tc; |
| ss >> tc; |
| return tc; |
| } |
| |
| bool TileConfig::empty() const { |
| return carcs.empty() && cwords.empty() && cenums.empty() && cunknowns.empty(); |
| } |
| |
| } |