#include #include "Circuit.h" #include "Exception.h" #include "NodeFactory.h" #include "NodeOutputVisitor.h" using std::format; void Circuit::create(string label, vector nodes) { if (nodes.size() == 1 && NodeFactory::has_type(nodes[0])) return new_node(label, nodes[0]); new_net(label, nodes); loops.add_connection(label, nodes); } void Circuit::new_node(string label, string type) { if (nodes.find(label) != nodes.end()) throw CircuitException("node with label \"%s\" already exists!", label.c_str()); Node * node = NodeFactory::create(type); if (node == nullptr) throw CircuitException("unknown type \"%s\"", type.c_str()); nodes[label] = node; } void Circuit::new_net(string src, vector dests) { Net * net = new Net(); nets.push_back(net); Node * node = find_node(src); if (node == nullptr) throw CircuitException("unknown source node \"%s\"", src.c_str()); node->setOutput(net); for (auto dest : dests) { Node * node = find_node(dest); if (node == nullptr) throw CircuitException("unknown destination node \"%s\"", dest.c_str()); node->addInput(net); } } void Circuit::sim() { for (auto & pair : nodes) { try { Node * node = pair.second; node->sim(); } catch (CircuitException & e) { const char * label = "???"; Node * node = e.node; if (node != nullptr) { auto it = std::find_if(nodes.begin(), nodes.end(), [node](auto && n) { return n.second == node; }); if (it != nodes.end()) label = it->first.c_str(); } throw CircuitException("node %s: %s", label, e.what()); } } } Node * Circuit::find_node(string label) { auto map_index = this->nodes.find(label); if (map_index == nodes.end()) return nullptr; return map_index->second; } Circuit::~Circuit() { for (auto & n : nodes) delete n.second; for (auto & n : nets) delete n; } string Circuit::result() { string output; for (auto & n : nodes) { NodeOutputVisitor visitor; n.second->accept(visitor); if (!visitor.output_node) continue; output += format("{}: {}\n", n.first, std::to_string(visitor.level)); } return output; }